didReceiveRemoteNotification:fetchCompletionHandler:从图标打开与推送通知

问题描述 投票:0回答:3

我正在尝试实现后台推送通知处理,但在确定用户是否从发送的推送通知打开应用程序而不是从图标打开应用程序时遇到问题。

- (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);
}

使用此代码,无论用户如何打开应用程序,应用程序都会向 MPOOpenViewController 打开。如何才能使视图控制器仅在通过滑动通知打开应用程序时才被推送?

使用相同的代码,这可以在 iOS 6 上运行,但是使用新的 iOS 7 方法,它的行为并不像我想要的那样。

编辑:我现在尝试在 iOS 7 上运行该应用程序,我们不支持 iOS 7 之前的任何版本。我在该方法的 iOS 6 版本中使用了相同的代码(没有完成处理程序)它的表现正如我所期望的那样。您只需滑动通知即可调用该通知。如果您从图标打开,则永远不会调用该方法。

ios ios7 push-notification apple-push-notifications uiapplicationdelegate
3个回答
88
投票

好吧,我明白了。该方法实际上被调用两次(一次是在收到推送时,一次是在用户与图标或通知交互时)。

- (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);

    }
}

感谢 Tim Castelijns 的以下补充:

注意:它被调用两次的原因是由于 Payload 有

content_available : 1
。如果您删除键及其值,那么它只会在点击时运行。这并不能解决每个人的问题,因为有些人需要该密钥为真


12
投票

@MikeV 在 Swift 3 中的解决方案(但带有 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)
    }

    @unknown default: 
        print("state unknown")
        completionHandler(.noData)

}

9
投票

@MikeV 在 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)
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.