Я сейчас пытаюсь настроить уведомления для моего приложения. Это был полезный опыт, и теперь я могу отправлять push-уведомления на нужное устройство для ассоциированного пользователя. То, что я сейчас делаю, это информирование пользователя, если другой пользователь следует за ним. Я нашел это руководство от PushWoosh , с которого я начинал, но я не пользуюсь их услугами, я использую свой собственный серверный узел node.js.
Когда нажата следующая кнопка, мой сервер node.js отправляет уведомление, используя следующий код:
let apnProvider = new apn.Provider(options)
let deviceToken = device["deviceToken"]
let notification = new apn.Notification()
notification.expiry = Math.floor(Date.now() / 1000) + 24 * 3600
notification.badge = selectCountRows[0]["badgeNumber"]
notification.sound = "default"
notification.contentAvailable = 1
notification.alert = pushText
let notificationID = `${ notificationType }${ fromUserID }`
notification.payload = {'crt': notificationID, 'fromUserID': fromUserID, 'notificationType': notificationType} notification.topic = "com.myapp"
apnProvider.send(notification, deviceToken).then( result => {
console.log(result);
})
apnProvider.shutdown();
Все переменные установлены правильно (они извлекаются из моей базы данных, например, deviceToken и pushText). В этом примере я создаю уведомление с предупреждением (переменная pushText) «PennyWise начал следовать за вами». - в этом случае для ID-уведомления следует follow1 (для переменной visibleType следует follow, а fromUserID равно 1) . Чтобы удалить уведомление, я использую аналогичное «тихое» уведомление, которое просто не имеет тела / текста для отображения, например:
let apnProvider = new apn.Provider(options)
let deviceToken = device["deviceToken"]
let notification = new apn.Notification()
notification.expiry = Math.floor(Date.now() / 1000) + 24 * 3600
notification.badge = selectCountRows[0]["badgeNumber"]
notification.contentAvailable = 1
let notificationID = `${ notificationType }${ fromUserID }`
notification.payload = {'dlt': notificationID, 'fromUserID': fromUserID, 'notificationType': "delete"}
notification.topic = "com.myapp"
apnProvider.send(notification, deviceToken).then( result => {
console.log(result);
})
apnProvider.shutdown();
В моем приложении для iOS я использую этот метод приложения для обработки полученных уведомлений:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
let dltPushId = userInfo["dlt"]
if let pushIdString = dltPushId as? String {
let pushNotificationId = "com.myapp." + pushIdString
UserDefaults.standard.removeObject(forKey: pushNotificationId)
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [pushNotificationId])
UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: [pushNotificationId])
print("deleted push notification with id ", pushNotificationId)
completionHandler(UIBackgroundFetchResult.newData)
return
}
let createPushId = userInfo["crt"]
if let pushIdString = createPushId as? String {
let content = UNMutableNotificationContent()
content.userInfo = userInfo
let pushNotificationId = "com.myapp." + pushIdString
let request = UNNotificationRequest(identifier: pushNotificationId, content: content, trigger: nil)
UNUserNotificationCenter.current().add(request, withCompletionHandler: { (error) in
if error == nil {
UserDefaults.standard.set(pushNotificationId, forKey: pushNotificationId)
print("created push notification with id ", request.identifier)
}
})
}
completionHandler(UIBackgroundFetchResult.noData)
}
Сначала казалось, что все работает. Я смог подписаться на другого пользователя (поэтому я вошел на два устройства) и получил уведомление. Затем, когда я откажусь от этого пользователя, уведомление исчезнет.
Однако проблема возникает, когда я использую три устройства для тестирования: я начинаю, следуя за пользователем 1 от пользователя 2, затем я также следую за пользователем 1 от пользователя 3. На этом этапе у меня есть два уведомления на устройстве для пользователя 1 : user 2 started following you.
и user 3 started following you.
Но затем, когда я отписываюсь от пользователя 3, уведомление не исчезает. Когда я откажусь от пользователя 2, оба уведомления исчезнут! Другими словами: все уведомления исчезают, когда идентификатор соответствует тому, который отправил первое уведомление, видимое в Центре уведомлений.
Это, конечно, не то поведение, которое я хочу, и мне интересно, в чем может быть проблема. Мои журналы из Xcode показывают правильный идентификатор уведомления, когда я отписываюсь от пользователя 1 (например, follow2 и follow3).
Мои наблюдения пока:
- В руководстве PushWoosh используется
let userData = PushNotificationManager.push().getCustomPushData(asNSDict: userInfo)
, к которому у меня нет доступа (это из их собственной структуры / API), поэтому я просто использую userInfo
вместо userData
- Похоже, что идентификатор уведомления в моем приложении iOS установлен неправильно и не обновляется при получении нового уведомления. Я чувствую, что проблема должна быть где-то в
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [pushNotificationId])
, где pushNotificationId ссылается на идентификаторы обоих уведомлений.
Любая помощь, чтобы выяснить, как я могу идти отсюда, будет искренне признательна. Я долго искал в интернете, но не могу понять, почему это происходит.
РЕДАКТИРОВАТЬ: Копать немного глубже, я думаю, проблема в том, что я установил идентификатор, например, "follow2", но Apple отправляет мое уведомление с другим идентификатором (apns-id? "), Который В данный момент я не могу получить. Я сейчас пытаюсь получить этот apns-id.
РЕДАКТИРОВАТЬ 2: Установка моего собственного идентификатора в node.js через notification.id
(для UUIDString) также не решила эту проблему. Я считаю, что уведомление обрабатывается где-то еще, за пределами моей функции, где я создаю локальное уведомление, поэтому я использую «неправильный» идентификатор. На самом деле, я ищу идентификатор, который генерируется Apple при получении нового удаленного уведомления. Я полагаю, что если я получу это, я смогу удалить правильное уведомление.