2017-10-11 1 views
0

J'ai un tableau de classe de notification composé de valeurs String et de 3 autres classes (classe utilisateur, photo et vidéo). J'ai des problèmes en ajoutant la classe de notification à une vue de collection. Le problème est que si Photo Class est vide, il échoue ou si Video Class est vide, il ne parvient pas à ajouter. J'ai rendu toutes les classes facultatives dans le tableau de classe de notification, mais cela ne semble pas faire de différence, donc je ne sais pas quoi faire ensuite. L'aide serait très appréciée s'il vous plaît. Merci d'avance!Ajouter un tableau de classes qui contient d'autres tableaux de classes

notification Tableau

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 

      }    
     }) 
} 
+1

Vous pouvez utiliser 'statique func fetchPostWithUID (uid: String, postId: String, achèvement: @escaping (Post) ->()) {'puis dans autre partie vous pouvez appeler le gestionnaire de complétion comme ceci' achèvement (nul) 'et même pour les autres fonctions – 3stud1ant3

+0

Merci @ 3stud1ant3 pour la réponse.J'ai mis à jour mon code avec votre suggestion mais maintenant je reçois une erreur fatale: trouvé de manière inattendue nil lors du déballage d'une valeur optionnelle en ligne let comment = notification (utilisateur: instantané, post: postShot, videoPost: videoShot, dictionnaire: dictionnaire) –

+0

aurait besoin de mettre à jour l'init de la notification comme ceci: 'init (utilisateur: userAccount, post: Post?, videoPost: videoPost?, dictionnaire: [String: Any])' – 3stud1ant3

Répondre

0

Vous pouvez utiliser

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

puis en partie ce que vous pouvez appeler le gestionnaire de l'achèvement de ce type

completion(nil) 

et même pour d'autres fonctions

puis

vous devez mettre à jour l'initialisation de la notification comme ceci:

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

Il y a plusieurs problèmes avec votre code. Je vais le prendre un par un:

Vous récupérez les données de Firebase en cascade. Donc d'abord vous prenez le user, que le photo et à la fin le video.

Dans vos méthodes fetch(Post|Video)withUUID vous appelez le bloc d'achèvement si un résultat a été renvoyé sinon vous ne faites rien. Ce qui signifie que la prochaine méthode/bloc ne sera jamais appelée.

Une façon de le fixer:

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) 
     } 
    }) 
} 

donc plusieurs modifications à votre code:

  1. Le post et videoPost sont maintenant en option (?) dans le bloc d'achèvement: @escaping (Post?) au lieu de @escaping (Post), @escaping (videoPost?) au lieu de @escaping (videoPost)

  2. Si vous ne disposez pas d'un résultat, il faudra encore appeler le bloc d'achèvement avec une valeur nil: completion(nil)

+0

Merci pour la réponse. Juste mis à jour mon code avec votre suggestion, mais maintenant je reçois une erreur fatale: inattendu trouvé tout en déballant une valeur facultative en ligne 'let comment = notification (utilisateur: instantané, post: postShot, videoPost: videoShot, dictionnaire: dictionnaire)' –

+0

Modifier votre méthode optionnelle aussi 'init (utilisateur: userAccount, post: Post?, videoPost: videoPost?, dictionnaire: [String: Any])' –

+0

Merci pour votre réponse. Avec ce changement, il fonctionne maintenant, mais il a été suggéré plus tôt par un autre utilisateur, j'ai donc approuvé la réponse –