【问题标题】:Append Class array that contains other class arrays追加包含其他类数组的类数组
【发布时间】:2017-10-11 15:57:20
【问题描述】:

我有一个通知类数组,它由字符串值和 3 个其他类(用户、照片和视频类)组成。我在将通知类附加到集合视图时遇到问题。问题是如果 Photo Class 为空则失败,或者 Video Class 为空也无法追加。我已经在 Notification Class 数组中将所有类设为可选,但它似乎没有什么不同,所以我不确定下一步该做什么。帮助将不胜感激。提前致谢!

通知数组

class notification { 
    var profilePic: String?
    var fullName: String?
    var descriptionLabel: String?
    var descriptionImage: String?
    var postID: String?
    var user: userAccount?
    var post: Post?
    var videoPost: videoPost?
    var postDescription: String?
    var date: NSNumber?

init (user: userAccount, post: Post, videoPost: videoPost, dictionary: [String: Any]) 
{
            self.videoPost = videoPost
            self.post = post
            self.user = user
            self.postDescription =  dictionary["postDescription"] as? String ?? ""
            self.fullName =  dictionary["fullName"] as? String ?? ""
            self.profilePic =  dictionary["profilePic"] as? String ?? ""
            self.descriptionLabel =  dictionary["textDesciption"] as? String ?? ""
            self.descriptionImage =  dictionary["desciptionImage"] as? String ?? ""
            self.postID =  dictionary["postID"] as? String ?? ""
            self.date = dictionary["notificationDate"] as? NSNumber       
        }

CollectionViewController

func loadData(){

   let userID = Auth.auth().currentUser!.uid
    Database.database().reference().child("notification").child(userID).observe(.childAdded, with: { (snapshot) in
        guard let dictionary = snapshot.value as? [String: Any] else { return }
        let uid = dictionary["uid"] as? String
        let postId = dictionary["postID"] as? String

        Database.fetchUserWithUID(uid: uid!, completion: { (snapshot) in
            Database.fetchPostWithUID(uid: userID, postId: postId!, completion: { (postShot) in
                Database.fetchVideoPostWithUID(uid: userID, postId: postId!, completion: { (videoShot) in

                    let comment = notification(user: snapshot, post: postShot, videoPost: videoShot, dictionary: dictionary)
                    self.notifications.append(comment)
                    self.notificationTableView?.reloadData()
                })
            })
        })
    })
}

extension Database {

    static func fetchUserWithUID(uid: String, completion: @escaping (userAccount) -> ()) {
        Database.database().reference().child("user").child(uid).observeSingleEvent(of: .value, with: { (snapshot) in

        let user = userAccount(snapshot:snapshot)
         completion(user)
            })
    }

    static func fetchPostWithUID(uid: String, postId: String,  completion: @escaping (Post) -> ()) {
        Database.database().reference().child("post").child(uid).child(postId).observeSingleEvent(of: .value, with: { (snapshot) in

            if snapshot.exists() {
                let post = Post(snapshot:snapshot)
                completion(post)
            }else{
        // Not sure what to write here when snapshot is equal to nil

        })
}

  static func fetchVideoPostWithUID(uid: String, postId: String,  completion: @escaping (videoPost) -> ()) {
        Database.database().reference().child("videoPost").child(uid).child(postId).observeSingleEvent(of: .value, with: { (snapshot) in

            if snapshot.exists(){          
            let post = videoPost(snapshot:snapshot)
            completion(post)
            }else{
        // Again not sure what to write here when snapshot is equal to nil

            }            
        })
}

【问题讨论】:

  • 你可以使用static func fetchPostWithUID(uid: String, postId: String, completion: @escaping (Post?) -> ()) {,然后在其他部分你可以像completion(nil)这样调用完成处理程序,其他函数也一样
  • 感谢@3stud1ant3 的回复。我用你的建议更新了我的代码,但现在我收到了一个致命错误:在解开可选值在线时意外发现 nil let comment = notification(user: snapshot, post: postShot, videoPost: videoShot, dictionary: dictionary)
  • 我认为您需要像这样更新通知的初始化:init (user: userAccount, post: Post?, videoPost: videoPost?, dictionary: [String: Any])
  • 非常感谢它现在可以工作了! @3stud1ant3

标签: arrays swift firebase uicollectionview


【解决方案1】:

您的代码存在多个问题。我会一一采纳:

您正在级联中从Firebase 获取数据。所以首先你抓住user,然后是photo,最后是video

在您的方法fetch(Post|Video)withUUID 中,您调用完成块如果返回结果,否则您什么也不做。这意味着,永远不会调用下一个方法/块。

一种解决方法:

init (user: userAccount, post: Post?, videoPost?: videoPost, dictionary: [String: Any]) {
   // your code after
}

static func fetchPostWithUID(uid: String, postId: String,  completion: @escaping (Post?) -> ()) {
  Database.database().reference().child("post").child(uid).child(postId).observeSingleEvent(of: .value, with: { (snapshot) in

    if snapshot.exists() {
      let post = Post(snapshot:snapshot)
      completion(post)
    }else{
      completion(nil)
    })
  }

static func fetchVideoPostWithUID(uid: String, postId: String,  completion: @escaping (videoPost?) -> ()) {
    Database.database().reference().child("videoPost").child(uid).child(postId).observeSingleEvent(of: .value, with: { (snapshot) in
      if snapshot.exists(){
        let post = videoPost(snapshot:snapshot)
        completion(post)
      }else{
        completion(nil)
      }
    })
}

对您的代码进行了几处更改:

  1. postvideoPost 现在在完成块中是可选的 (?): @escaping (Post?) 代替 @escaping (Post)@escaping (videoPost?) 代替 @escaping (videoPost)

  2. 如果你没有结果,它仍然会调用带有nil值的完成块:completion(nil)

【讨论】:

  • 感谢您的回复。刚刚用你的建议更新了我的代码,但现在我收到了一个致命错误:unwrapping an Optional value on line let comment = notification(user: snapshot, post: postShot, videoPost: videoShot, dictionary: dictionary) 时意外发现 nil
  • 将您的方法也更改为可选init (user: userAccount, post: Post?, videoPost: videoPost?, dictionary: [String: Any])
  • 感谢您的回复。有了这个改变,它现在可以工作了,但是之前另一个用户建议过它,所以我已经批准了答案
【解决方案2】:

你可以使用

static  func fetchPostWithUID(uid: String, postId: String, completion: @escaping (Post?) -> ()) {

然后在其他部分你可以像这样调用完成处理程序

completion(nil)

其他功能也一样

然后

您需要像这样更新通知的初始化:

 init (user: userAccount, post: Post?, videoPost: videoPost?, dictionary: [String: Any])

【讨论】:

    猜你喜欢
    • 2018-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多