Это то, что я придумал, и у меня это прекрасно работает. Это не похоже на Instagram, когда заблокированный пользователь полностью исчезает из вашего канала , но это определенно удержит Apple в страхе, потому что один пользователь может заблокировать другого пользователя, и как только это произойдет , ни не сможет отправить сообщение друг другу.
Это также дает вам возможность показывать «блок» или «разблокировать», когда лист действий представлен так, чтобы текущий пользователь знал, были ли они заблокированы или заблокированы другим пользователем.
Во-первых, я предполагаю, что это внутри какого-то контроллера просмотра чата, который имеет кнопку отправки сообщения, и внутри этого чата есть идентификатор отправителя (текущий пользователь) и идентификатор получателя (другой пользователь).
Чтобы заблокировать кого-то, вы создаете ссылку blocked
в Firebase, создайте узел для пользователя, который хочет заблокировать другого пользователя, и, наконец, добавьте заблокированного пользователя в качестве пары ключ / значение под этим узлом. other user's id
- это key
, и значение может быть истинным.
Например, dog123 хочет заблокировать cat456 . Когда собака решает заблокировать кошку, ссылка для блокировки будет:
let dogId = dog123 // current user
let catId = cat456 // other user
func actionSheetBlockedAction() {
let dictValues = [String: Any]()
dictValues.updateValue(true, forKey: catId)
let ref = Database.database().reference().child("blocked").child(dogId)
ref.updateChildValues(dictValues)
}
В результате база данных будет выглядеть следующим образом:
root
|
@---blocked
|
|
@----dog123
|
|----cat456: true // cat123 is blocked from sending messages to dog123
Внутри того же чата vc вам нужно добавить некоторые свойства, а в viewDidLoad или viewWillAppear вам нужно добавить 2 отдельных наблюдателя для прослушивания заблокированных ссылок для обоих пользователей.
Вы должны выполнить проверку обоих пользователей, потому что, возможно, dog123 заблокировал cat456, но взамен cat456 также может заблокировать dog123. Позже, если собака решит разблокировать кошку, но кошка по-прежнему заблокировала собаку, сообщения от собаки все равно будут передаваться кошке.
Чтобы предотвратить добавление наблюдателей, они будут переключать некоторые свойства, которые вы проверяете при нажатии кнопки отправки. Если какое-либо из свойств имеет значение true, это означает, что кто-то заблокировал кого-то другого, и никакие сообщения не должны отправляться. Свойства сообщат, кто кого заблокировал.
Вы также можете использовать эти свойства для отображения кнопки «блокировать» или «разблокировать» при появлении листа действий.
var currentUserId = Auth.auth().currentUser?.uid
var otherUserId = "whatever" // you should already have this
var isCurrentUserBlocked = false
var isOtherUserBlocked = false
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
checkBlockedRefsForBothUsers() // this is where the isCurrentUserBlocked & isOtherUserBlocked properties get changed
}
@IBAction func sendMessageButtonTapped(sender: UIButton) {
if isOtherUserBlocked {
// alert the current user that they blocked the other user
return
}
if isCurrentUserBlocked {
// alert the current user that the other user blocked them
return
}
// if neither are true then let the current user send their message to the other user
}
func checkBlockedRefsForBothUsers() {
let currentUsersBlockedRef = Database.database().reference().child("blocked").child(currentUserId!)
currentUsersBlockedRef?.observe( .value, with: { (snapshot) in
// if the current user ISN'T under the blocked ref then the other user ISN'T blocked
if !snapshot.exists() {
self.isOtherUserBlocked = false
return
}
for child in snapshot.children {
let snap = child as! DataSnapshot
// if the other user's uid IS under the current user's blocked ref then the other user IS blocked from them
if snap.key == self.otherUsersId {
self.isOtherUserBlocked = true
break
}
// if the other user's uid ISN'T under the current user's blocked ref then the other user ISN'T blocked
self.isOtherUserBlocked = false
}
})
let otherUsersBlockedRef = Database.database().reference().child("blocked").child(otherUserId)
otherUsersBlockedRef?.observe( .value, with: { (snapshot) in
// if the other user's uid ISN'T under the blocked ref then the current user ISN'T blocked
if !snapshot.exists() {
self.isCurrentUserBlocked = false
return
}
for child in snapshot.children {
let snap = child as! DataSnapshot
// if the current user's uid IS under the other user's blocked ref then the current user IS blocked from them
if snap.key == self.currentUserId {
self.isCurrentUserBlocked = true
break
}
// if the current user's uid ISN'T under the other user's blocked ref then the current user ISN'T blocked
self.isCurrentUserBlocked = false
}
})
}
А чтобы показать кнопку «заблокировать» или «разблокировать», когда представлен лист действий, используйте те же 2 свойства:
@IBAction func presentActionSheet(sender: UIButton) {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let blockAction = UIAlertAction(title: "Block", style: .default) { (action) in
// run code to block the otherUserId
self.actionSheetBlockedAction()
}
let unblockAction = UIAlertAction(title: "Unblock", style: .default) { (action) in
// run code to unblock the otherUserId
}
if isOtherUserBlocked {
actionSheet.addAction(unblockAction) // if the current user blocked the other user then show the "unblock" action
} else {
actionSheet.addAction(blockAction) // if the current user didn't block the other user then show the "block" action
}
present(actionSheet, animated: true, completion: nil)
}
Наконец, вы можете подумать про себя, что, когда собака заблокировала кошку, имело бы смысл просто обновить ссылки для них обоих. Проблема заключается в том, что при представлении листа действий кота, используя приведенную выше логику, будет казаться, что кот заблокировал собаку, и лист действий кота покажет «разблокировать».