Arracher mes cheveux en essayant de faire fonctionner les notifications Push dans iOS10. Configuration actuelle:
dans func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
:
if #available(iOS 10.0, *) {
let center = UNUserNotificationCenter.current()
center.delegate = self
center.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in
if error == nil {
print("DID REQUEST THE NOTIFICATION")
UIApplication.shared.registerForRemoteNotifications()
}
}
print("DID SET DELEGATE")
}
Dans func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
:
print("DID REGISTER FOR A REMOTE NOTIFICATION AND THE TOKEN IS \(deviceToken.base64EncodedString())"
let request = UpdatePushNotificationSubscription_Request(deviceToken: deviceToken)
updatePushNotificationSubscriptionWorker.updateSubscription(request)
J'ai vérifié que le jeton est chargé correctement dans le backend et qu'il correspond bien.
J'ai aussi implémenté:
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
print("GOT A NOTIFICATION")
}
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
//This is for the user tapping on the notification
print("GOT A NOTIFICATION")
}
J'ai défini les droits d'accès à toutes les cibles et activé Push:
Maintenant, lorsque j'essaie d'envoyer un message depuis le backend, l'appareil ne reçoit rien. Les délégués ne sont pas appelés. Je n'ai aucune idée de ce que je fais mal ici. Push fonctionne pour les appareils iOS9 et Android. Des indicateurs sur ce que je pourrais faire de mal?
Essayez de faire que votre classe AppDelegate implémente le protocole UNUserNotificationCenterDelegate au lieu d’une classe séparée implémentant le protocole.
J'ai eu une classe séparée pour le délégué et cela n'a pas fonctionné. Voici à quoi ressemblait mon code lorsque je le faisais fonctionner:
import UIKit
import UserNotifications
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application
UIApplication.shared.registerForRemoteNotifications()
let center = UNUserNotificationCenter.current()
center.delegate = self //DID NOT WORK WHEN self WAS MyOtherDelegateClass()
center.requestAuthorization(options: [.alert, .sound, .badge]) {
(granted, error) in
// Enable or disable features based on authorization.
if granted {
// update application settings
}
}
return true
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent: UNNotification,
withCompletionHandler: @escaping (UNNotificationPresentationOptions)->()) {
withCompletionHandler([.alert, .sound, .badge])
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive: UNNotificationResponse,
withCompletionHandler: @escaping ()->()) {
withCompletionHandler()
}
// and so forth for your other AppDelegate stuff
J'ai eu du mal avec cela pendant une journée complète. Parfois, je recevais des notifications, parfois pas, mais je ne pouvais jamais obtenir le rappel userNotificationCenter(_:willPresent:completionHandler:)
sur déclenché.
Il s'est avéré qu'il y avait deux problèmes. La première me laisse encore un peu perplexe: ma version de déploiement cible était définie à 11.0 mais mon projet à 10.0. Changer le projet en 11.0 était la première étape. Je ne comprends pas tout à fait cela, mais peut-être y at-il une différence dans le traitement des notifications entre 10.0 et 11.0?
La deuxième partie était le délégué du centre de notification. J'ai remarqué le note dans la documentation d'Apple _: -
Important
Vous devez affecter votre objet délégué à UNUserNotificationCenter objet avant que votre application ne soit lancée. Par exemple, dans une application iOS, vous devez l'assigner dans le application (: willFinishLaunchingWithOptions :) ou application (: didFinishLaunchingWithOptions :) méthode de votre application déléguer. L'affectation d'un délégué après l'appel de ces méthodes pourrait vous faire manquer les notifications entrantes.
J'étais en train de définir une classe "gestionnaire de notification" distincte, où sont également situés les rappels (en tant qu'implémentations de protocole de délégué). J'avais instancié ceci en tant qu'instance var dans mon délégué d'application, en supposant que cela serait créé tôt et ne causerait pas de problème.
Je me suis amusé avec l'instanciation, etc. pendant un certain temps, mais seulement lorsque j'ai défini le délégué dans ma méthode application(_:didFinishLaunchingWithOptions:)
et mis en œuvre les rappels de délégué dans le délégué de l'application, j'ai réussi à résoudre le problème.
Donc, mon code est devenu, essentiellement: -
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// You MUST do this HERE and nowhere else!
UNUserNotificationCenter.current().delegate = self
// other stuff
return true
}
extension AppDelegate: UNUserNotificationCenterDelegate {
// These delegate methods MUST live in App Delegate and nowhere else!
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
if let userInfo = notification.request.content.userInfo as? [String : AnyObject] {
}
completionHandler(.alert)
}
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
if let userInfo = response.notification.request.content.userInfo as? [String : AnyObject] {
}
completionHandler()
}
}
Peut-être que vous n'avez pas défini l'intentionIdentifiers de UNNotificationCategory, si le code ressemble à ceci:
UNNotificationCategory* expiredCategory = [UNNotificationCategory categoryWithIdentifier:@"TIMER_EXPIRED" actions:@[snoozeAction, stopAction] intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction];
il n'appellera pas les méthodes de délégué de UNUserNotificationCenter, vous devez donc définir les identIdentifiers comme suit:
UNNotificationCategory* expiredCategory = [UNNotificationCategory categoryWithIdentifier:@"TIMER_EXPIRED" actions:@[snoozeAction, stopAction] intentIdentifiers:@[@"a",@"b"] options:UNNotificationCategoryOptionCustomDismissAction];