web-dev-qa-db-fra.com

Les notifications push ne sont pas reçues sur iOS 10, mais fonctionnent sur iOS 9 et avant

J'ai plusieurs applications qui ont été écrites en Swift 2.2, compilé avec Xcode 7.3 et en direct sur l'App Store. Les applications utilisent les notifications push et fonctionnent correctement sous iOS 9.3 et les versions antérieures.

Sur les appareils mis à niveau vers iOS 10, toutefois, mes applications ne reçoivent aucune notification push. Les appareils qui exécutent encore iOS 9 reçoivent toujours des notifications.

Pensant qu'il pourrait s'agir d'un problème de certificat ou de droit, j'ai essayé les solutions suivantes: Mise à niveau de l'une de mes applications vers Swift 2.3, ajout du droit d'accès à l'environnement APS et compilation dans Xcode 8, mais cela ne faisait aucune différence. .

Dans mon AppDelegate, je dispose toujours des méthodes existantes pour enregistrer les notifications Push, à savoir:

let notificationSettings = UIUserNotificationSettings(forTypes: [.Badge, .Sound, .Alert], categories:nil)
application.registerUserNotificationSettings(notificationSettings)

Cet enregistrement semble avoir réussi même sur iOS 10, car L'application didRegisterForRemoteNotificationsWithDeviceToken est alors appelée. Je reçois donc un jeton d'APNS.

Le problème est que, lorsque j'envoie une notification Push à ce périphérique, l'application didReceiveRemoteNotification n'est jamais appelée.

Maintenant, ici il est dit que les méthodes sur UIApplicationDelegate sont obsolètes sur iOS 10 et que je devrais implémenter userNotificationCenter (: didReceive: withCompletionHandler :) et userNotificationCenter (: willPresent: withCompletionHandler :)

Le problème est que je ne cible pas SEULEMENT iOS 10. J'ai encore besoin de l'application pour fonctionner sur iOS 8 et 9, donc je doute que ce soit la bonne approche pour implémenter ces méthodes.

Comment obtenir des notifications Push pour une application existante afin de continuer à travailler sur des appareils mis à niveau vers iOS 10? Dois-je réécrire le code? Dois-je simplement mettre à jour des certificats ou des droits et recompiler Xcode 8 avec certains "nouveaux" paramètres?

30
Stanley

Ok je l'ai compris. J'ai maintenant mes notifications push d'origine qui fonctionnaient sur iOS 9 et iOS 10 avec Xcode 8 et Swift 2.3.

J'ai implémenté cela en apportant les modifications suivantes à mon AppDelegate:

1) Sur les paramètres de mon projet, sous l'onglet Capacités, je fais défiler jusqu'à "Notifications" et le met sur "ON". Cela génère automatiquement un fichier de droits contenant la clé "Environnement APS" et la valeur "Développement".

2) Dans AppDelegate.Swift, j'apporte plusieurs modifications de code. Je commence par importer le cadre UserNotifications:

import UserNotifications

Ensuite, j'ai AppDelegate implémenter le protocole UNUserNotificationCenterDelegate:

class AppDelegate: /*Some other protocols I am extending...*/, UNUserNotificationCenterDelegate {

Puis j'ajoute la méthode suivante:

func registerForPushNotifications(application: UIApplication) {

    if #available(iOS 10.0, *){
        UNUserNotificationCenter.currentNotificationCenter().delegate = self
        UNUserNotificationCenter.currentNotificationCenter().requestAuthorizationWithOptions([.Badge, .Sound, .Alert], completionHandler: {(granted, error) in
            if (granted)
            {
                UIApplication.sharedApplication().registerForRemoteNotifications()
            }
            else{
                //Do stuff if unsuccessful...
            }
        })
    }

    else{ //If user is not on iOS 10 use the old methods we've been using
        let notificationSettings = UIUserNotificationSettings(
            forTypes: [.Badge, .Sound, .Alert], categories: nil)
        application.registerUserNotificationSettings(notificationSettings)

    }

}

J'appelle ensuite cette fonction nouvellement créée dans didFinishLaunchingWithOptions:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
...
    registerForPushNotifications(application)
...
}

Je ne modifie pas ma méthode didRegisterForRemoteNotificationsWithDeviceToken:

func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
    //Implement this. Do something with the token I receive. Send it to my Push notification server to register the device or something else I'd like to do with the token.
 }

Maintenant, j'implémente deux nouvelles méthodes pour iOS 10 afin de gérer la réception des notifications push:

@available(iOS 10.0, *)
func userNotificationCenter(center: UNUserNotificationCenter, willPresentNotification notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {
    //Handle the notification
}

@available(iOS 10.0, *)
func userNotificationCenter(center: UNUserNotificationCenter, didReceiveNotificationResponse response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {
    //Handle the notification
}

Je n'ai supprimé aucune des méthodes que j'ai précédemment implémentées pour les notifications push dans iOS 9.

52
Stanley

IOS 10 a un kit de notification différent.

import UserNotifications

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {



    if #available(iOS 10.0, *) {
        let center = UNUserNotificationCenter.current()
        center.requestAuthorization(options: [.badge, .alert , .sound]) { (granted, error) in
            if granted {
                UIApplication.shared.registerForRemoteNotifications()
            }
        }
    } else {
        let type: UIUserNotificationType = [UIUserNotificationType.badge, UIUserNotificationType.alert, UIUserNotificationType.sound]
        let setting = UIUserNotificationSettings(types: type, categories: nil)
        UIApplication.shared.registerUserNotificationSettings(setting)
        UIApplication.shared.registerForRemoteNotifications()
    }
}



func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data){
    let token = String(format: "%@", deviceToken as CVarArg)
}
9
ilan

J'ai résolu ce problème en utilisant l'étape ci-dessous:

Étape 1: Allez dans Projet -> Cible -> Capacités -> Notifications Push -> Allumez-le

enter image description here Étape 2: résolution du problème lié au certificat approprié, au profil d'approvisionnement

Étape 3: Quittez Xcode, nettoyez et exécutez

8
Dheeraj D

Dans diverses SO réponses à des questions sur les notifications push iOS 9 vs iOS 10, j'ai testé les tests suivants:

1) mettre à jour les appels de notification pour utiliser spécifiquement le périphérique UNUserNotificationCenter pour iOS 10

2) mettre à jour la fonctionnalité Push afin que le fichier de droits soit mis à jour

Je peux confirmer que le fait de conserver la même chose que le n ° 2 et de conserver le même code Push pour iOS 9 existant permettra aux notifications Push de base d'apparaître sur les appareils iOS 10.

2
kevinl

Lorsque mon application a été déplacée de IOS 9 à IOS 10), les notifications Push silencieuses envoyées par mon serveur Parse hébergé sur Heroku ont cessé d'être reçues par l'application.

La seule modification que j'ai apportée pour que les notifications fonctionnent à nouveau était de modifier le code Javascript sur mon serveur afin que l'argument de content-available soit un entier 1 et non une chaîne "1".

           Parse.Push.send({
                where: notifyDeletedRequestsQuery,
                data: {
                    'content-available': 1,
                    refresh: constants.requestsClassName
                    }
            }, { useMasterKey: true });

Notez également que le contenu disponible ne peut pas apparaître dans la même notification Push que badge, son ou alerte.

0
BrianM