2017-05-17 22 views
1

ユーザー間でメッセージチャットログをコーディングしようとしています。私はメッセージ配列から特定のデータだけを取り出したいと思っています。たとえば、ある人がテキストメッセージを送信したときに、私は自分のメッセージ配列からId、toId、およびtextを取り出したいだけです。人が画像を送るとき、私は、Id、toIdおよびimageUrlからのみ取り出したいと思う。現時点では、人がテキストを送るときにアプリケーションがクラッシュするので、 "imageUrl"はnilであり、その逆は "text"がnilでないイメージを送信します。これを回避する方法はありますか?または、2つの別々の配列を作成する必要がありますか?事前のおかげでオブジェクト配列からデータを取得中にエラーが発生しました

メッセージ配列

class Message { 

    var fromId: String 
    var text: String 
    var toId: String 
    var timeStamp: NSNumber? 
    var imageUrl: String 



    init(fromId: String, text: String, toId: String, timeStamp: NSNumber, imageUrl: String){ 


     self.fromId = fromId 
     self.text = text 
     self.toId = toId 
     self.imageUrl = imageUrl 

    } 

    init(snapshot:FIRDataSnapshot) { 

     self.fromId = (snapshot.value! as! NSDictionary)["fromId"] as! String! 

     self.toId = (snapshot.value! as! NSDictionary)["toId"] as! String! 

     self.text = (snapshot.value! as! NSDictionary)["text"] as! String! 

     self.imageUrl = (snapshot.value! as! NSDictionary)["imageUrl"] as! String! 


    } 

firebase構造

{ "messages": { 

"KkGAWnQhqnOx525vv2W": { 

"fromId": tvyT6UF6mWZeewAJXt076qqt7ek2, 
"toId": USk3w8ZPYlRhfDmEwWwtkMhzUNX2, 
"text": "Hello" 
}, 
"hujU6UF6mWZeewAJXt0": { 

"fromId": tvyT6UF6mWZeewAJXt076qqt7ek2, 
"toId": USk3w8ZPYlRhfDmEwWwtkMhzUNX2, 
"imageUrl": "https://firebasestorage.googleapis.com/v0/b.." 
} 

あなたが強制とき値をラップしているので、それがクラッシュした理由は、データ

var message = [Message]() 

func observeMessages(){ 

    let ref = FIRDatabase.database().reference().child("user-messages").child(uid) 

    ref.observe(.childAdded, with: { (snapshot) in 


     let messageId = snapshot.key 

     let messageReference = FIRDatabase.database().reference().child("messages").child(messageId) 
     messageReference.observe(.value, with: { (snapshot) in 


      for posts in snapshot.children{ 

       let message = Message(snapshot: posts as! FIRDataSnapshot) 

       let chatPartnerId = message.chatPartnerId() 

       self.messagesDictionary[chatPartnerId!] = message 


        self.messageTableView.reloadData() 
       }) 
      } 

    }, withCancel: nil) 
} 
+0

データを強制的にアンラップする代わりにオプションを使用します。 –

+0

あなたの返信のためにこんにちは@JohnMontgomeryありがとう。あなたはあなたの答えにもっと詳しく説明できますか? –

+0

あなたはテキストとURLが時々ゼロであると言います。つまり、 '! 'を使用してラップを解除するとクラッシュすることになります。あなたはそれをしないで、代わりにプロパティ 'String?'を作る必要があります。 –

答えて

1

を取得するために使用される方法あなたは辞書を添えています。任意の値をラップするには、if letまたはguard letを使用するか、デフォルト値が空のNil-Coalescing Operatorを使用し、後でどちらが空でないかを確認する必要がありますtextまたはimage

init(snapshot:FIRDataSnapshot) { 
    let dictionary = snapshot.value as! [String:Any] 
    self.fromId = dictionary["fromId"] as! String 
    self.toId = dictionary["toId"] as! String 
    self.text = dictionary["text"] as? String ?? "" 
    self.imageUrl = dictionary["imageUrl"] as? String ?? "" 
} 

またバッターオプションはtypeとしてあなたのメッセージオブジェクトを持つと値textまたはimageのいずれかとの1つの以上のキーを追加することです。このような構造を作りましょう。その後

{ 
    "messages": { 

     "KkGAWnQhqnOx525vv2W": { 
      "fromId": tvyT6UF6mWZeewAJXt076qqt7ek2, 
      "toId": USk3w8ZPYlRhfDmEwWwtkMhzUNX2, 
      "type" "text" 
      "text": "Hello" 
     }, 
     "hujU6UF6mWZeewAJXt0": { 

      "fromId": tvyT6UF6mWZeewAJXt076qqt7ek2, 
      "toId": USk3w8ZPYlRhfDmEwWwtkMhzUNX2, 
      "type" "image" 
      "imageUrl": "https://firebasestorage.googleapis.com/v0/b.." 
     } 
    } 
} 

型の値を取得し、比較するあなたは、このオブジェクトは、その型をチェックアクセスし、それに応じてそのプロパティテキストとIMAGEURLにアクセスすると、それは今textまたはimage

init(snapshot:FIRDataSnapshot) { 
    let dictionary = snapshot.value as! [String:Any] 
    self.fromId = dictionary["fromId"] as! String 
    self.toId = dictionary["toId"] as! String 
    //Make one more property with name type of String 
    self.type = dictionary["type"] as! String 
    self.text = dictionary["text"] as? String ?? "" 
    self.imageUrl = dictionary["imageUrl"] as? String ?? "" 
} 

です。

+0

okありがとうございました。配列に型を追加すると、その型をチェックしてプロパティにアクセスする方法を教えてください。 –

+0

@ j.ieseようこそ:)単にif(object.type == "text"){//アクセスするテキストプロパティ} else {//アクセスimageUrlプロパティ} ' –

+1

完璧!もう一度ありがとう! :) –

関連する問題