J'essaie d'implémenter la gestion des notifications Push en arrière-plan, mais je rencontre des problèmes pour déterminer si l'utilisateur a ouvert l'application à partir de la notification Push envoyée par opposition à l'ouvrir à partir de l'icône.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
//************************************************************
// I only want this called if the user opened from swiping the Push notification.
// Otherwise I just want to update the local model
//************************************************************
if(applicationState != UIApplicationStateActive) {
MPOOpenViewController *openVc = [[MPOOpenViewController alloc] init];
[self.navigationController pushViewController:openVc animated:NO];
} else {
///Update local model
}
completionHandler(UIBackgroundFetchResultNewData);
}
Avec ce code, l'application s'ouvre sur MPOOpenViewController quelle que soit la façon dont l'utilisateur ouvre l'application. Comment puis-je faire en sorte que le contrôleur de vue ne soit poussé que s'il ouvre l'application en glissant la notification?
Avec le même code, cela a fonctionné sur iOS 6, mais avec la nouvelle méthode iOS 7, il ne se comporte pas comme je le souhaite.
Edit: J'essaie d'exécuter l'application sur iOS 7 maintenant, et nous ne prenons en charge aucune version antérieure à iOS 7. J'ai utilisé ce même code exact dans la version iOS 6 de la méthode (sans le gestionnaire d'achèvement) et il s'est comporté comme je m'y attendais. Vous feriez glisser la notification et cela serait appelé. Si vous ouvrez à partir de l'icône, la méthode ne sera jamais appelée.
Ok je l'ai compris. La méthode est en fait appelée deux fois (une fois lorsqu'il reçoit le Push et une fois lorsque l'utilisateur interagit avec l'icône ou la notification).
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
if(application.applicationState == UIApplicationStateInactive) {
NSLog(@"Inactive");
//Show the view with the content of the Push
completionHandler(UIBackgroundFetchResultNewData);
} else if (application.applicationState == UIApplicationStateBackground) {
NSLog(@"Background");
//Refresh the local model
completionHandler(UIBackgroundFetchResultNewData);
} else {
NSLog(@"Active");
//Show an in-app banner
completionHandler(UIBackgroundFetchResultNewData);
}
}
Merci à Tim Castelijns pour l'ajout suivant:
Remarque: la raison pour laquelle il est appelé deux fois est due au fait que la charge utile a
content_available : 1
. Si vous supprimez la clé et sa valeur, elle ne s'exécutera qu'après avoir appuyé sur. Cela ne résoudra pas le problème de tout le monde car certaines personnes ont besoin de cette clé pour être vraie
@ La solution de MikeV dans Swift 3 (mais avec l'instruction switch):
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
switch application.applicationState {
case .inactive:
print("Inactive")
//Show the view with the content of the Push
completionHandler(.newData)
case .background:
print("Background")
//Refresh the local model
completionHandler(.newData)
case .active:
print("Active")
//Show an in-app banner
completionHandler(.newData)
}
}
@ La solution de MikeV dans Swift 2:
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
if(application.applicationState == UIApplicationState.Inactive)
{
print("Inactive")
//Show the view with the content of the Push
completionHandler(.NewData)
}else if (application.applicationState == UIApplicationState.Background){
print("Background")
//Refresh the local model
completionHandler(.NewData)
}else{
print("Active")
//Show an in-app banner
completionHandler(.NewData)
}
}