LoginSignup
8
7

More than 3 years have passed since last update.

SNSの報告・ブロック機能

Last updated at Posted at 2020-02-10

完成予想図

SNSをリリースする上で必須なブロックと報告機能を、tableviewをスワイプさせて実装してみました。
コードの書き方は基本同じなので、アラートで出したい場合なども応用してみてください!

途中途中に出てくる 【やること】2つと、【完成形】2つを行ってください!

全体像を知りたい場合は、こちらのGitHubと併用して見てみてください〜!

ブロック.gif

【説明】他人に対して報告・ブロック機能

他人の投稿(自分の投稿ではないもの)をブロックします。

①まず、サーバーから投稿とユーザー情報(誰がその投稿をしたか)を取得します(ここは割愛)
取得したuserのobjectIdが自分のobjectIdと一致しない(=つまり他人)ものに関して処理を書いていきます。


if 〇〇.user.objectId != NCMBUser.current()?.objectId{
//他人の投稿に対する処理
}

処理内容は、いきなりスワイプ選択したものが実行されないように、アラートを入れとくと良いかもですね!(ここも割愛)

②報告した投稿Idをサーバーに保存しましょう!
今回はサーバーをNCMBとしてコーディングします

【やること】そのため、新たにNCMBのclassを作っておいてください。→今回はReport

保存するものは投稿IDと、現在ログインしているユーザー情報です。
以下のように、setした後は、保存しておいてください。


 let object = NCMBObject(className: "Report")
                    object?.setObject(self.〇〇[indexPath.row].objectID, forKey: "reportId")
                    object?.setObject(NCMBUser.current(), forKey: "user")

【やること】ブロック機能も同様に、アラートとサーバー上のclassを作っておいてください!→今回はBlock

【説明】自分の投稿の場合削除する

先ほど、他人のログインしている人と異なるIdの場合の非同期処理を書きましたが、それ以外(つまり、ログインしている人と同じ人が投稿している場合)はelseの方に分岐されます。
この部分で、自分の投稿を削除するアラートをかけば良さそうです!
削除したい項目をqueryでサーバーにアクセスしてください!


if 〇〇.user.objectId != NCMBUser.current()?.objectId{
//他人の投稿に対する処理
}else{
//ここに自分の投稿に対する処理
}

【完成形①】ブロックユーザーを格納する配列の読み込み

①NCMB上で保存したブロックされたユーザーIDの値を持ってきて、格納する配列を用意します。(この配列に入っているIDの表示をしないようにするためです!)→今回は blockUserIdArray
②先ほど作成した"Block"という名前のNCMBのclassNameの情報を持ってくる関数(この場合はgetBlockUser())を用意します。(いつも通りqueryで持ってくるだけ)+その関数の中でタイムラインに表示する(この場合はloadData())関数を読み込みます。
③そして、②の最後に読み込んだ関数の中で、NCMBから値を持ってきてappendする時にそのブロックIDだけを排除するようにコードを書きます。
firstIndexの説明はこちら

//①
    var blockUserIdArray = [String]()

//② この関数はviewWillAppearと、ブロックが選択される部分(※最後のtableviewのコードに記載あり)の二箇所で読み込む
func getBlockUser() {

        let query = NCMBQuery(className: "Block")

        //includeKeyでBlockの子クラスである会員情報を持ってきている
        query?.includeKey("user")
        query?.whereKey("user", equalTo: NCMBUser.current())
        query?.findObjectsInBackground({ (result, error) in
            if error != nil {
                //エラーの処理
            } else {
                //ブロックされたユーザーのIDが含まれる + removeall()は初期化していて、データの重複を防いでいる
                self.blockUserIdArray.removeAll()
                for blockObject in result as! [NCMBObject] {
                    //この部分で①の配列にブロックユーザー情報が格納
self.blockUserIdArray.append(blockObject.object(forKey: "blockUserID") as! String)

                }

            }
        })
        loadData()
    }


//③
func loadData(){
//ここにNCMBから値を持ってくるコードが書いてある前提

//appendする時に、ブロックユーザーがnilであったらappendされるようにしている。

//Movieクラスのinitalをmovieという定数で定義した場合
let movie = Movie(title: title, user: userModel, objectID: objectID!)

if self.blockUserIdArray.firstIndex(of: movie.user.objectId) == nil{
                            self.movies.append(movie)
               }
}

【完成形②】TableViewの全体コード

editActionsForRowAt関数の中に書いていきます。
アラートも付けた一例を示しておくので、自分でカスタマイズしてみてください☺️
NCMB仕様なので、サーバー違う人は気を付けてください!
ライブラリのSVProgressHUDを使用しています!


//Movieという名前のクラスの場合→クラスの名前は自分のものに変更しましょう
var movies = [Movie]()

//自分以外=>報告・ブロックする
    func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
        if movies[indexPath.row].user.objectId != NCMBUser.current()?.objectId {
            let reportButton: UITableViewRowAction = UITableViewRowAction(style: .normal, title: "報告") { (action, index) -> Void in
                let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
                let reportAction = UIAlertAction(title: "報告する", style: .destructive ){ (action) in
                    SVProgressHUD.showSuccess(withStatus: "この投稿を報告しました。ご協力ありがとうございました。")
                    let object = NCMBObject(className: "Report") //新たにクラス作る
                    object?.setObject(self.movies[indexPath.row].objectID, forKey: "reportId")
                    object?.setObject(NCMBUser.current(), forKey: "user")
                    object?.saveInBackground({ (error) in
                        if error != nil {
                            SVProgressHUD.showError(withStatus: "エラーです")
                        } else {
                            SVProgressHUD.dismiss(withDelay: 2)
                            tableView.deselectRow(at: indexPath, animated: true)
                        }
                    })
                }
                let cancelAction = UIAlertAction(title: "キャンセル", style: .cancel) { (action) in
                    alertController.dismiss(animated: true, completion: nil)
                }

                alertController.addAction(reportAction)
                alertController.addAction(cancelAction)
                self.present(alertController, animated: true, completion: nil)
                tableView.isEditing = false

            }
            reportButton.backgroundColor = UIColor.red
            let blockButton: UITableViewRowAction = UITableViewRowAction(style: .normal, title: "ブロック") { (action, index) -> Void in
                //self.comments.remove(at: indexPath.row)
                //tableView.deleteRows(at: [indexPath], with: .fade)
                let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
                let blockAction = UIAlertAction(title: "ブロックする", style: .destructive) { (action) in
                    SVProgressHUD.showSuccess(withStatus: "このユーザーをブロックしました。")

                    let object = NCMBObject(className: "Block") //新たにクラス作る
                    object?.setObject(self.movies[indexPath.row].user.objectId, forKey: "blockUserID")
                    object?.setObject(NCMBUser.current(), forKey: "user")
                    object?.saveInBackground({ (error) in
                        if error != nil {
                            SVProgressHUD.showError(withStatus: "エラーです")
                        } else {
                            SVProgressHUD.dismiss(withDelay: 2)
                            tableView.deselectRow(at: indexPath, animated: true)

                     //ここで③を読み込んでいる
                self.getBlockUser()
                        }
                    })

                }
                let cancelAction = UIAlertAction(title: "キャンセル", style: .cancel) { (action) in
                    alertController.dismiss(animated: true, completion: nil)
                }

                alertController.addAction(blockAction)
                alertController.addAction(cancelAction)
                self.present(alertController, animated: true, completion: nil)
                tableView.isEditing = false
            }
            blockButton.backgroundColor = UIColor.blue
            return[blockButton,reportButton]
        } else {
            let deleteButton: UITableViewRowAction = UITableViewRowAction(style: .normal, title: "削除") { (action, index) -> Void in
                let query = NCMBQuery(className: "取り出したいクラスの名前")
                query?.getObjectInBackground(withId: self.movies[indexPath.row].objectID, block: { (post, error) in
                    if error != nil {
                        SVProgressHUD.showError(withStatus: "エラーです")
                        SVProgressHUD.dismiss(withDelay: 2)
                    } else {
                        DispatchQueue.main.async {
                            let alertController = UIAlertController(title: "投稿を削除しますか?", message: "削除します", preferredStyle: .alert)
                            let cancelAction = UIAlertAction(title: "キャンセル", style: .cancel) { (action) in
                                alertController.dismiss(animated: true, completion: nil)
                            }
                            let deleteAction = UIAlertAction(title: "OK", style: .default) { (acrion) in
                                post?.deleteInBackground({ (error) in
                                    if error != nil {
                                        SVProgressHUD.showError(withStatus: "エラーです")
                                        SVProgressHUD.dismiss(withDelay: 2)
                                    } else {
                                        tableView.deselectRow(at: indexPath, animated: true)
                                        self.loadData()
                                        self.〇〇TableView.reloadData()
                                    }
                                })
                            }
                            alertController.addAction(cancelAction)
                            alertController.addAction(deleteAction)
                            self.present(alertController,animated: true,completion: nil)
                            tableView.isEditing = false
                        }

                    }
                })
            }
            deleteButton.backgroundColor = UIColor.red //色変更
            return [deleteButton]
        }
    }
8
7
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
7