投稿内容に「位置情報(ユーザーがマップ上で選択する)」をつけて投稿することで、ホーム画面(GoogleMap)上に「マーカー」として表示され、マーカーをタップすることで該当の投稿内容を閲覧できるというアプリを作成しました。投稿内容などの保管場所はFirebaseを利用しております。
そこに「ブロック機能」をつけたいです。
現状は
①UserDefaultsを利用してブロックボタンをタップしたときに、ブロックする投稿内容(postData.id)にキー値を持たせて投稿画面を閉じてホーム画面に戻る。
②そしてホーム画面に戻ったとき、viewWillAppearメソッド内で、Firebaseより最新の状態に更新(投稿内容の数だけマップ上にマーカーを表示する処理)した後に、キー値と同じ値を持つマーカー(投稿内容:postData.id)をmarker.map = nilでマップ上から非表示にする処理をしました。
本題はここからになります。
ブロックしたマーカーを非表示にすることはできたのですが、ブロックしたユーザーだけでなく、他のユーザーからもマーカーが非表示になり投稿内容を閲覧できない状態になりました。(AユーザーがBユーザーの投稿内容ブロックしたら、CユーザーもDユーザーも見ることができなくなってしまった状態です。)
ブロック処理をする時とマーカーを非表示にする時に、ブロックする投稿内容の指定だけでなく、ブロックする側のユーザーも指定したいのですが、現状調べてわからず苦慮しております。ブロックした本人(そのアカウントから)のみがブロックした投稿を見ないようにする処理方法を教えていただきたいです。
以下は該当の記述箇所・クラスになります。
ご確認・ご教示よろしくお願いいたします。
①ブロックボタンタップ時の処理が書かれたクラス(ShowViewController.swift)
@IBAction func blockButton(_ sender: Any) { //ログイン中のアカウント名と投稿者名が同じ場合は機能しないようにする let user = Auth.auth().currentUser if postData.name == user?.displayName { SVProgressHUD.showError(withStatus: "自身の投稿をブロックすることはできません。") SVProgressHUD.dismiss(withDelay: 1) }else { //他者の投稿の場合に機能する。 //ブロックする投稿データのidに名称をつけキーとしてUserDefaultsに一旦格納*ホーム画面でマーカー削除処理として使うため UserDefaults.standard.setValue(postData.id, forKey: "blockMarker") //画面をとじて一つ前のホーム画面に戻る self.dismiss(animated: true, completion: nil) } } コード
②ホーム画面(マップ上)にてFirebaseのデータより最新状態に更新(投稿内容の数だけマップ上にマーカーを表示する処理)した後に、キー値と同じ値を持つマーカー(投稿内容:postData.id)をmarker.map = nilでマップ上から非表示にする処理が書かれたクラス(HomeViewController.swift)
override
1 super.viewWillAppear(animated) 2 print("DEBUG_PRINT: viewWillAppear") 3 4 //ShowViewControllerで投稿削除時に格納したキー(id)と一致するidを削除する 5 if let delMarker: String = UserDefaults.standard.value(forKey: "delMarker") as? String { 6 //for文でmarkers配列から一つずつ一致するもの探していく 7 for marker in markers { 8 let data = marker.userData as! PostData 9 if (data.id == delMarker) { 10 print("hit: delete marker") 11 marker.map = nil 12 } 13 } 14 15 } 16 17 //投稿データの更新をもとにマップに最新の状態でマーカー表示 18 //ログイン済みかどうかを確認 19 if Auth.auth().currentUser != nil { 20 21 //listenerを登録して投稿データの更新を監視する 22 let postRef = Firestore.firestore().collection(Const.PostPath).order(by: "date", descending: true) 23 //addSnapshotListenerメソッドがpostrefで取得する投稿データを監視し、投稿データが追加される・更新される度にクロージャ内の処理が呼び出される 24 listener = postRef.addSnapshotListener() {(querySnapshot,error) in //querySnapshotに最新の投稿データが入っている。 25 if let error = error { 26 print("DEBUG_PRINT: snapshotの取得に失敗しました。 (error)") 27 return 28 } 29 //取得したdocumentをもとにPostDataを作成し、更新された(新しいデータを含んだ)postDataをpostArrayの配列にする 30 //*mapメソッドは新しい投稿データを新しい配列に変換して作成してくれる 31 self.postArray = querySnapshot!.documents.map { document in 32 let postData = PostData(document: document) 33 return postData 34 } 35 36 //makeMarkerメソッドを使用して複数ある投稿データを一つずつマップ上にマーカーを表示させる 37 for element in self.postArray { 38 self.makeMarker(postData: element) 39 40 //上記でマーカーを全て表示した上でブロックしたマーカーを非表示にする 41 if let blockMarker: String = UserDefaults.standard.value(forKey: "blockMarker") as? String { 42 //for文でmarkers配列から一つずつ一致するもの探していく 43 for marker in self.markers { 44 let data = marker.userData as! PostData 45 if (data.id == blockMarker) { 46 print("hit: block marker") 47 marker.map = nil 48 } 49 } 50 51 } 52 53 } 54 55 } 56 } 57 58 } 59コード
こちらはPostDataクラスになります。
import
1import Firebase 2 3class PostData: NSObject { 4var id: String //投稿者ID、保存のために作成 *String?にならない理由としては、下記イニシャライザにて id != nil(nilは絶対に入らない)の初期化宣言をしているため。 5 var name: String? //投稿者名 *nilが入る可能性も考えて?をつけている 6 var caption: String? //キャプション:投稿者名と投稿者からのコメント *nilが入る可能性も考えて?をつけている 7 var latitude: Double? 8 var longitude: Double? 9 var date: Date? //日時 *nilが入る可能性も考えて?をつけている 10 var likes: [String] = [] //複数のいいねした人のID(文字列)を扱うため、配列型にする 11 var isLiked: Bool = false //自分がいいねしたかどうかのフラグ 12 13 14 //イニシャライザ *上記プロパティのままだとデフォルト(初期)値がなく、変数の使い方がわからないため 15 init(document: DocumentSnapshot) { //ShowViewControllerにてデータ更新する際に扱うquerySnapshot(最新データが含まれている)がDocumentSnapshot型のため、QueryDocumentSnapshot→DocumentSnapshotに変更 16 self.id = document.documentID 17 let postDic = document.data()! //DocumentSnapshotへの変更に伴い、「!」を追記 18 self.name = postDic["name"] as? String 19 self.caption = postDic["caption"] as? String 20 self.latitude = postDic["latitude"] as? Double 21 self.longitude = postDic["longitude"] as? Double 22 let timestamp = postDic["date"] as? Timestamp 23 self.date = timestamp?.dateValue() 24 25 //nilがくる可能性もあるので、そのうちString型の場合に限って、下記デフォルト値に代入して扱うという意味 26 if let likes = postDic["likes"] as? [String] { 27 self.likes = likes 28 } 29 if let myid = Auth.auth().currentUser?.uid { 30 //likesの配列の中にmyidが含まれているかチェックすることで、自分が「いいね」を押しているかを判断 31 if self.likes.firstIndex(of: myid) != nil { 32 //myidがあれば、「いいね」を押していると認識する 33 self.isLiked = true 34 } 35 } 36 } 37} 38 39 40コード
回答1件
あなたの回答
tips
プレビュー