LINEのようなメッセージアプリを開発しています。どうかお力添えを願います。
Firebaseからメッセージを取得し、Custom Classに代入し、Table Viewに表示させています。既存メッセージの取得および新着メッセージの取得は問題なくできますが、既存メッセージに紐づく情報(既読の有無)に変更があった際に、それをリアルタイムで反映できず困っています。
まず以下コードを記載していました。
Swift
1Database.database().reference().child("user-messages").child(uid!).observe(.childAdded, with: { (snapshot) in 2 let messageId = snapshot.key 3 DBProvider.Instance.mediaMessagesRef.child(messageId).observe(.value, with: {[weak self] (snapshot) in 4 //中略 5self?.messages.append(newContact);
Swift
1class Message { 2 //read以外の変数は省略 3 private var _read = false 4 init(read: Bool) { 5 _read = read 6 } 7 var read: Bool? { 8 return _read; 9 } 10} 11
この場合、ステータスが変更されたメッセージだけダブりが生じてしまいます。既存メッセージを読み込む際に一度messagesクラスがappendされ、そのあと既読ステータスが変わると、同じメッセージが重複表示されてしまいます。重複のうち、新たに重複表示された方のメッセージには既読表示がされ、最初から読み込めていたメッセージには既読表示がされていません。これはobserve(.value, を使っているため、変更された箇所だけを再度読み込んで新たにappendしてしまっているのが原因のように思います。
試したこと
.valueをやめて、singleEvent方式に変更しました。
Swift
1Database.database().reference().child("user-messages").child(uid!).observe(.childAdded, with: { (snapshot) in 2 let messageId = snapshot.key 3 DBProvider.Instance.mediaMessagesRef.child(messageId).observeSingleEvent(of: .value, with: { [weak self] (snapshot) in
これにより既存+新着メッセージは今までどおり読み込めて、既存メッセージの既読ステータスに変更があったとしても重複表示は解消されました。ただ既読メッセージのステータスに変更があった際に、messages配列にその変更を反映できていないため、table view上で既読を表示ができず困りました。
そこで、childChangeの追記も試みました。変更があったnodeの情報だけを取得し、messages配列の特定メッセージをピンポイントで探し出し上書きするという方法です。ただ、childChangeの場合は変更した箇所の「read 1」というデータしか取得できかったため意味がなかったです。
Swift
1 DBProvider.Instance.mediaMessagesRef.child(messageId).observe(.childChanged) { [weak self](snapshot) in 2 print("itemchanged") 3 print(snapshot) // Snap (read) 1 4 if let d2 = snapshot.value as? [String:AnyObject]{ 5print("成功") //出力されず 6 let timeStamp = d2["timeStamp"] as? NSNumber 7 self?.messages.filter{$0.timeStamp == timeStamp}.first?._read = true 8
何か良い方法をご存知でしたら、アドバイス頂けますと幸いです。
あなたの回答
tips
プレビュー