JSQMessagesViewControllerは大変便利なので重宝しているわけですが、メッセージの削除に対応するとなると少々厄介なんですよね。JSQMessagesオブジェクトごとに、DBに対応するメッセージのkeyを持たせれば楽勝なんでしょうけど、ライブラリいじるの面倒なので力ずくで対応します。Firebaseを使った場合の対応方法をご紹介します。
やり方としてはシンプルで、
1.自分のメッセージをタップしたときのイベントを取得する
2.イベント内でJQSMessageオブジェクトを取得しタイムスタンプを取得(DBのタイムスタンプを登録しておく必要あり)
3.タイムスタンプと投稿者IDから対応するレコードをDBから引っ張ってきてdeleteフラグを立てる
4.deleteフラグのあるメッセージを非表示にする(もしくは削除済みというメッセージを出す)
では細かく見ていきましょう。
Contents
1.自分のメッセージをタップしたときのイベントを取得する
1 2 |
override func collectionView(_ collectionView: JSQMessagesCollectionView!, didTapMessageBubbleAt indexPath: IndexPath!) { } |
これでバルーンのタップイベントを取得できます。基本的にこの中に処理を書いていくことになります。
2.イベント内でJQSMessageオブジェクトを取得しタイムスタンプを取得(DBのタイムスタンプを登録しておく必要あり)
1 2 |
let message = self.messages[indexPath.row] let targetMessegeTimeStamp = floor(message.date.timeIntervalSince1970) |
JSQMessageから投稿日情報を取得し、それをDBで使用しているタイムスタンプフォーマットに変更します。私はunixtimestampを使用しているのでこのようにしました。
3.タイムスタンプと投稿者IDから対応するレコードをDBから引っ張ってきてdeleteフラグを立てる
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
let message = self.messages[indexPath.row] let targetMessegaTimeStamp = floor(message.date.timeIntervalSince1970) let testRef = Database.database().reference().child("DBNAME").child("CHILDNAME") let testQuery = testRef.queryOrdered(byChild: "userId").queryEqual(toValue: Auth.auth().currentUser?.uid) testQuery.observeSingleEvent(of: .value, with: { (snapshot) in for item in (snapshot.children) { let dataSnapShot = item as! DataSnapshot let tmp = dataSnapShot.value as! [String: Any] let createdAt = tmp["createdAt"] as! TimeInterval if String(floor(createdAt)).contains(String(floor(targetMessegeTimeStamp))) { var isDeleted = false if tmp["isDeleted"] != nil { isDeleted = tmp["isDeleted"] as! Bool } if isDeleted == true { let alertController = UIAlertController(title: "", message: "このメッセージは削除済みです。", preferredStyle: .alert) let defaultAction = UIAlertAction(title: "OK", style: .default) { action in } alertController.addAction(defaultAction) self.present(alertController, animated: true, completion: nil) } else { // 必要に応じて削除対象フラグを立てる Database.database().reference().child("DBNAME").child("CHILENAME").child(dataSnapShot.key).child("isDeleted").setValue(true) } } } }) 以下略 |
4.deleteフラグのあるメッセージを非表示にする(もしくは削除済みというメッセージを出す)
これはメッセージをobserveするところで判定を噛ませてあげればOK