Arrays Xcode说我的数组超出范围,但我可以确认我的数组没有超出范围
我有一个用于TableView单元格的数组,类似于Facebook提要。我成功地让我的应用程序版本的提要成功地显示了用户发表帖子的日期,显示了用户创建帖子的电子邮件,显示了与帖子一起上传的照片,但我似乎不知道如何为他们的用户配置文件创建数组。所有信息都来自Firebase 下面您可以看到我的数据库结构的屏幕截图 在这里你可以看到我的帖子结构,我在那里存储帖子信息Arrays Xcode说我的数组超出范围,但我可以确认我的数组没有超出范围,arrays,swift,firebase,google-cloud-firestore,Arrays,Swift,Firebase,Google Cloud Firestore,我有一个用于TableView单元格的数组,类似于Facebook提要。我成功地让我的应用程序版本的提要成功地显示了用户发表帖子的日期,显示了用户创建帖子的电子邮件,显示了与帖子一起上传的照片,但我似乎不知道如何为他们的用户配置文件创建数组。所有信息都来自Firebase 下面您可以看到我的数据库结构的屏幕截图 在这里你可以看到我的帖子结构,我在那里存储帖子信息 func tableView(_ tableView: UITableView, cellForRowAt indexPath
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let Cell = tableView.dequeueReusableCell(withIdentifier: "VidaFeed", for: indexPath) as! FeedCell
print("Posteremail count = \(PosterEmail.count)")
>> //Cell.userProfilePhotoFeedCellLabel.sd_setImage(with: URL(string: self.userProfilePhotoArray[indexPath.row]))
Cell.FeedCellUserNameLabel.text = PosterEmail[indexPath.row]
Cell.dateFeedCellLabel.text = "test"
Cell.likeCountFeedCellLabel.text = String(likeArray[indexPath.row])
Cell.postImageFeedCellLabel.sd_setImage(with: URL(string: self.userPostImageArray[indexPath.row]))
Cell.postDescriptionLabel.text = userPostDescription[indexPath.row]
if userPostImageArray[indexPath.row] == ""{
Cell.postImageFeedCellLabel.isHidden = true
}
if userPostImageArray[indexPath.row] != "" {
Cell.postImageFeedCellLabel.isHidden = false
}
return Cell
帖子>文档ID>帖子信息(日期、上传的图像url为字符串、海报电子邮件,如计数为Int)
表视图 我试图从另一个名为Public的集合中提取用户的个人资料 公共>用户电子邮件(test@gmail.com)>用户信息(姓名、日期、个人资料照片url) 我从Firestore数据库中获取帖子信息,并将所有内容都放入数组中 然后我将所有内容加载到tableview单元格中 //后置变量 var userCommentArray=String 以上是我的帖子变量 下面是我的手机和用来加载信息的阵列
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let Cell = tableView.dequeueReusableCell(withIdentifier: "VidaFeed", for: indexPath) as! FeedCell
print("Posteremail count = \(PosterEmail.count)")
>> //Cell.userProfilePhotoFeedCellLabel.sd_setImage(with: URL(string: self.userProfilePhotoArray[indexPath.row]))
Cell.FeedCellUserNameLabel.text = PosterEmail[indexPath.row]
Cell.dateFeedCellLabel.text = "test"
Cell.likeCountFeedCellLabel.text = String(likeArray[indexPath.row])
Cell.postImageFeedCellLabel.sd_setImage(with: URL(string: self.userPostImageArray[indexPath.row]))
Cell.postDescriptionLabel.text = userPostDescription[indexPath.row]
if userPostImageArray[indexPath.row] == ""{
Cell.postImageFeedCellLabel.isHidden = true
}
if userPostImageArray[indexPath.row] != "" {
Cell.postImageFeedCellLabel.isHidden = false
}
return Cell
//Cell.userProfilePhotoFeedCellLabel.sd_setImage(带:URL(字符串:self.userProfilePhotoArray[indexPath.row]))
如果我只注释掉profile单元格,那么我的应用程序会成功运行,但每当我重新添加它时,它就会崩溃
下面您可以看到,我试图确保我的var userProfilePhotoArray不会超出索引范围,因为我将它设置为一个变量,以限制超出数组范围
if self.profilecount <= self.PosterEmail.count{
func getDatFromFirestore(){
让firestoreDatabase=Firestore.Firestore()
firestoreDatabase.collection(“Posts”).order(按:“日期”,降序:true).addSnapshotListener{(快照,错误)在
如果错误!=nil{
打印(错误?.localizedDescription??“连接错误”)
}否则{
self.userPostImageArray.removeAll(保留容量:false)
self.userCommentArray.removeAll(保留容量:false)
self.userCommentArray.removeAll(保留容量:false)
self.likerray.removeAll(保留容量:false)
self.PosterEmail.removeAll(保留容量:false)
self.userProfilePhotoArray.removeAll(保留容量:false)
用于快照文档中的文档{
self.dbread=self.dbread+1
打印(self.dbread)
让documentID=document.documentID
self.documentIDArray.append(documentID)
self.getUserProfilePhoto()
如果让postedBy=document.get(“postedBy”)作为?字符串{
self.PosterEmail.append(postedBy)
设db=Firestore.Firestore()
让docRef=db.collection(“Public”).文档(postedBy)
docRef.getDocument{(文档,错误)位于
如果self.profilecountAFirebase
文档将通过网络连接或本地磁盘缓存获取,这意味着无法保证每个API调用所需的时间。因此,Firebase API
调用始终是异步的。您的第一个API调用将获取按日期排序的Posts
集合,itera检查所有文档并将数据追加到PosterEmail
数组中。它还将数据追加到userProfilePhotoArray
数组中,但请注意,这是通过不同的API调用完成的,这意味着它是异步完成的。但是,您正在调用reloadData()在第二个异步调用完成之前,VidaFeed
上的方法-填充userProfilePhotoArray
-这意味着PosterEmail
和userProfilePhotoArray
中的计数不同
解决此问题的一种方法是在{code>docRef.getDocument{(document,error)in…}
中添加self.VidaFeed.reloadData()
:
docRef.getDocument { (document, error) in
if self.profilecount <= self.PosterEmail.count{
self.profilecount = self.profilecount + 1
print("Profile count is \(self.profilecount)")
if let document = document, document.exists {
print(document)
if let userProfile = document.get("imageUrl") as? String {
self.userProfilePhotoArray.append(userProfile)
print("time = \(Date.self), \(self.userProfilePhotoArray).")
// Add this line.
self.VidaFeed.reloadData()
}
}
}
}
与
如果indexath.row
Perfect!现在用户的个人资料照片正确显示了正确的用户个人资料照片。I"I’在对Firestore进行两次不同的调用时,请务必重新加载数据,以避免再次出现此问题。非常感谢。@IrvingGonzalez这是一个很好的答案,但只有一个澄清/更正;这确保了每当向userProfilePhotoArray添加新项目时,都会通知VidaFeed。此处的PhotoArray不正确。docRef.getDocument只获取一次文档,因此vidaFeed将仅在调用该函数时更新,而不会在添加新项时更新。在父集合上使用将确保在添加新项时刷新tableView。否则,将更新。
func getDatFromFirestore() {
let firestoreDatabase = Firestore.firestore()
firestoreDatabase.collection("Posts").order(by: "Date" , descending : true).addSnapshotListener { (snapshot, error) in
if error != nil {
print(error?.localizedDescription ?? "Connection Error")
} else {
self.userPostImageArray.removeAll(keepingCapacity: false)
self.userCommentArray.removeAll(keepingCapacity: false)
self.userCommentArray.removeAll(keepingCapacity: false)
self.likeArray.removeAll(keepingCapacity: false)
self.PosterEmail.removeAll(keepingCapacity: false)
self.userProfilePhotoArray.removeAll(keepingCapacity: false)
for document in snapshot!.documents {
self.dbread = self.dbread + 1
print(self.dbread)
let documentID = document.documentID
self.documentIDArray.append(documentID)
self.getUserProfilePhoto()
if let postedBy = document.get("postedBy") as? String {
self.PosterEmail.append(postedBy)
let db = Firestore.firestore()
let docRef = db.collection("Public").document(postedBy)
docRef.getDocument { (document, error) in
if self.profilecount <= self.PosterEmail.count{
self.profilecount = self.profilecount + 1
print("Profile count is \(self.profilecount)")
if let document = document, document.exists {
print(document)
if let userProfile = document.get("imageUrl") as? String {
self.userProfilePhotoArray.append(userProfile)
print("time = \(Date.self), \(self.userProfilePhotoArray).")
}
}
}
}
if let postDescription = document.get("PostDescription") as? String {
self.userPostDescription.append(postDescription)
}
if let imageUrl = document.get("imageUrl") as? String {
self.userPostImageArray.append(imageUrl)
}
if let PostLikes = document.get("Likes") as? Int {
self.likeArray.append(PostLikes)
}
if let timeStamp = document.get("Date") as? Date {
let formatter = DateFormatter()
formatter.dateFormat = "MM/dd/yyyy"
let dateString = formatter.string(from: timeStamp)
let timeStampAsString = dateString
self.postDate.append(timeStampAsString)
}
}
self.VidaFeed.reloadData()
}
}
}
Posteremail count = 1
Profile count is 1
<FIRDocumentSnapshot: 0x6000001a2850>
time = 2020-06-01 03:00:28 +0000, "https://firebasestorage.googleapis.com/v0/b/vida-clock-11690.appspot.com/o/UserProfilePhotos%2F8C2ADEC6-C108-4C70-8CDA-ADBFCC56B4E2?alt=media&token=1c2178b8-b35b-4e2a-bbc0-c7747843b673"].
docRef.getDocument { (document, error) in
if self.profilecount <= self.PosterEmail.count{
self.profilecount = self.profilecount + 1
print("Profile count is \(self.profilecount)")
if let document = document, document.exists {
print(document)
if let userProfile = document.get("imageUrl") as? String {
self.userProfilePhotoArray.append(userProfile)
print("time = \(Date.self), \(self.userProfilePhotoArray).")
// Add this line.
self.VidaFeed.reloadData()
}
}
}
}
Cell.userProfilePhotoFeedCellLabel.sd_setImage(with: URL(string: self.userProfilePhotoArray[indexPath.row]))
if indexPath.row < self.userProfilePhotoArray.count {
Cell.userProfilePhotoFeedCellLabel.sd_setImage(with: URL(string: self.userProfilePhotoArray[indexPath.row]))
}