#完成予想図
SNSをリリースする上で必須なブロックと報告機能を、tableviewをスワイプさせて実装してみました。
コードの書き方は基本同じなので、アラートで出したい場合なども応用してみてください!
途中途中に出てくる 【やること】2つと、【完成形】2つを行ってください!
全体像を知りたい場合は、こちらのGitHubと併用して見てみてください〜!
#【説明】他人に対して報告・ブロック機能
他人の投稿(自分の投稿ではないもの)をブロックします。
①まず、サーバーから投稿とユーザー情報(誰がその投稿をしたか)を取得します(ここは割愛)
取得した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]
}
}