iOS,先强制退出应用,点击接收通知banner后,应用启动失败

Posted

技术标签:

【中文标题】iOS,先强制退出应用,点击接收通知banner后,应用启动失败【英文标题】:iOS, force quit app first, after tapping the receiving notification banner, app launch failed 【发布时间】:2015-12-04 13:21:20 【问题描述】:

我使用 APN 将通知发送到我的应用。但是当我执行以下步骤时,我的应用程序无法正常运行:

步骤

    滑动应用强制退出(应用未运行,未处于后台模式..) 从 APN 发送通知 在我的 iPhone 上收到通知,然后我点击了通知横幅 应用似乎尝试启动(显示启动图像),但启动失败(崩溃?)

我的应用可以在前台和后台接收通知。 在后台点击通知横幅,然后它可以将应用程序带到前台,然后转到我写的视图,一切正常。

强制退出APP除外

这是我在 AppDelegate.m 中的代码

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
MFSideMenuContainerViewController *container = [MFSideMenuContainerViewController
                                                    containerWithCenterViewController:[self navigationController]
                                                    leftMenuViewController:leftMenuViewController
                                                    rightMenuViewController:rightMenuViewController];

    self.window.rootViewController = container;
    [self.window makeKeyAndVisible];

    UIMutableUserNotificationAction *acceptAction =
    [[UIMutableUserNotificationAction alloc] init];

    // Define an ID string to be passed back to your app when you handle the action
    acceptAction.identifier = @"MARK_AS_READ_IDENTIFIER";

    // Localized string displayed in the action button
    acceptAction.title = NSLocalizedString(@"Mark as Read", nil);

    // If you need to show UI, choose foreground
    acceptAction.activationMode = UIUserNotificationActivationModeBackground;

    // Destructive actions display in red
    acceptAction.destructive = NO;

    // Set whether the action requires the user to authenticate
    acceptAction.authenticationRequired = NO;

    // First create the category
    UIMutableUserNotificationCategory *inviteCategory =
    [[UIMutableUserNotificationCategory alloc] init];

    // Identifier to include in your push payload and local notification
    inviteCategory.identifier = @"actionCategory";

    // Add the actions to the category and set the action context
    [inviteCategory setActions:@[acceptAction]
                    forContext:UIUserNotificationActionContextDefault];

    // Set the actions to present in a minimal context
    [inviteCategory setActions:@[acceptAction]
                    forContext:UIUserNotificationActionContextMinimal];
    NSSet *categories = [NSSet setWithObject:inviteCategory];
    [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeBadge | UIUserNotificationTypeAlert) categories:categories]];

    // for calling didReceiveRemoteNotification when app first launch
    if (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]) 
        [self application:application didReceiveRemoteNotification:launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]];
    
    return YES;

- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings 
    //register to receive notifications
    [application registerForRemoteNotifications];


- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken 
        NSLog(@"Device token: %@",deviceToken);


- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error 
    NSLog(@"Fail to get device token: %@", error);


// tap the backgraund banner button
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)newUserInfo completionHandler:(void (^)())completionHandler 
    if ([identifier isEqualToString:@"MARK_AS_READ_IDENTIFIER"]) 
        // when tapping the background banner's button will mark the notification status to read
        [Functions updateComingNotificationToRead];
    

    if (completionHandler) 
        completionHandler();
    


- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)newUserInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))handler 
   //NSLog(@"Notification received: %@ %@", newUserInfo,[newUserInfo objectForKey:@"aps"] );
    userInfo = newUserInfo;

    NSString *alertMessage = [[newUserInfo objectForKey:@"aps"]  objectForKey:@"alert"];
    UIApplicationState state = [application applicationState];
    UIAlertView *alertView = nil;

    // for background banner use
    switch (state) 
        case UIApplicationStateActive: // when app is alive, show alert to notify user
            alertView =  [[UIAlertView alloc]initWithTitle:NSLocalizedString(@"SmartHome",nil) message:NSLocalizedString(alertMessage,nil) delegate:self cancelButtonTitle:NSLocalizedString(@"Close",nil) otherButtonTitles:NSLocalizedString(@"Open",nil),NSLocalizedString(@"Mark as Read",nil), nil];
            [alertView show];
            break;
        case UIApplicationStateBackground: // app is in background mode
            // user tap the banner or tap the mark as read button, code will go here
            [Functions addNotificationDataInDatabase:[newUserInfo objectForKey:@"uniqueID"] type:[newUserInfo objectForKey:@"deviceType"] event:[newUserInfo objectForKey:@"event"] time:[newUserInfo objectForKey:@"time"] read:@"0" description:alertMessage];
            break;
        case UIApplicationStateInactive: // tapping the banner
            //NSLog(@"UIApplicationStateInactive");
            // go to notification view
        // because will go to the notification view detail, set status to read
            [self gotoNotificationView:userInfo]; //uniqueID
            break;
        default:
            break;
    

    // Set icon badge number to zero
    application.applicationIconBadgeNumber = 0;

    // Handle the received message
    // Invoke the completion handler passing the appropriate UIBackgroundFetchResult value
    handler(UIBackgroundFetchResultNoData);

    // send post notification for updating the badge, will get the notification in foreground
    [[NSNotificationCenter defaultCenter] postNotificationName:@"APNsNotification" object:self userInfo:nil];


以前有人遇到过这个问题吗?我错过了什么吗?

请帮帮我!!

【问题讨论】:

从 XCode 调试应用程序时是否发生了这种情况?通过强制关闭应用程序取消调试后的第一次启动经常崩溃... 我通过从主视图而不是 Xcode 滑动应用程序来强制退出我的应用程序 是的,但是当您这样做时,您是否从 XCOde 启动了应用程序? 不,我没有从 Xcode 启动应用程序 【参考方案1】:

你可以发出警报并检查启动选项

if (launchOptions) 
    if ([launchOptions objectForKey:@"UIApplicationLaunchOptionsRemoteNotificationKey"]) 
        [self application:self didReceiveRemoteNotification:[launchOptions objectForKey:@"UIApplicationLaunchOptionsRemoteNotificationKey"] fetchCompletionHandler:^(UIBackgroundFetchResult result) 

        ];
    

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)newUserInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))handler 

if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive) 
NSString *str = [[userInfo objectForKey:@"aps"] objectForKey:@"alert"];


【讨论】:

感谢您的回答,但我已经在我的代码中添加了这个,它根本不起作用 请阅读我的代码,我已经添加了你写的内容。这并没有解决问题。 只需将 didReceiveRemoteNotification 改为 didReceiveRemoteNotification:[launchOptions objectForKey:@"UIApplicationLaunchOptionsRemoteNotificationKey"] fetchCompletionHandler:^(UIBackgroundFetchResult result) ]; 嗨,有解决方案吗? 你可以在我的答案上打勾

以上是关于iOS,先强制退出应用,点击接收通知banner后,应用启动失败的主要内容,如果未能解决你的问题,请参考以下文章

APNS:如果应用程序被强制退出,则接收静默远程通知

iOS的通知:如何WhatsApp的接收通知,并强制关闭,即使他们以后的过程?

iOS - 当应用程序被用户强制退出时处理静默推送通知

静默推送通知。 iOS

如果应用程序被强制退出,则处理 IOS 远程通知

当应用程序被用户强制退出时处理推送通知iOS(替代方案?)