如何在IOS中处理多个远程通知点击

moD*_*Dev 5 notifications objective-c viewcontroller ios notificationcenter

我试图打开基于notification点击的不同视图控制器,但是当push notification它被接收时它会自动在后台运行控制器代码,所以当我通过应用程序图标/通知打开应用程序时notification centre,view controller立即加载,但是当收到多个通知时,它会加载第一个通知控制器无论采用哪种通知.

假设我已收到标题为"晚上","早晨"和"夜晚"的通知,当点击"晚上"通知时它应打开"晚间视图控制器",但当我回去加载时它会加载"夜视控制器" "早晨视图控制器",最后加载"晚视图控制器".在通知发出之前,我在主控制器上,然后我将应用程序移至后台.

当我点击"早晨"时,notification它现在什么都不做.

之前我尝试过使用addObserver,但结果是一样的,所以我转到app delegate.

这是app委托代码

@interface AppDelegate ()

@end


@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    [[UIApplication sharedApplication]setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];

    // Override point for customization after application launch.
    // Register for Push Notitications, if running iOS 8 or More

    if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {

        UIUserNotificationType userNotificationTypes = (UIUserNotificationTypeAlert |
                                                        UIUserNotificationTypeBadge |
                                                        UIUserNotificationTypeSound);
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:userNotificationTypes categories:nil];
        [application registerUserNotificationSettings:settings];
        [application registerForRemoteNotifications];

    } else {
        // Register for Push Notifications before iOS 8

        [application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert |  UIRemoteNotificationTypeSound)];
    }

    [application setStatusBarHidden:YES];

    return YES;
}

// Handle remote notification registration.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {

    NSLog(@"Device Token %@",[self stringWithDeviceToken:deviceToken]);

    [[NSUserDefaults standardUserDefaults]setObject:[self stringWithDeviceToken:deviceToken] forKey:@"registration_id"];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {

    NSLog(@"Error in registration. Error: %@", err);
}


- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {

    NSDictionary *alertInfo = (NSDictionary *) userInfo[@"aps"][@"alert"];
    NSLog(@"%@",alertInfo);

    NSString *alertID = [userInfo valueForKey:@"alertid"];


    if (application.applicationState == UIApplicationStateBackground) {

        [UIApplication sharedApplication].applicationIconBadgeNumber = [UIApplication sharedApplication].applicationIconBadgeNumber + 1;

        NSLog(@"Background Mode");
        NSString *title = alertInfo[@"title"];

        [self openViewController:title];
    }

    if(application.applicationState == UIApplicationStateActive){

        NSLog(@"Active Mode");
           }

    completionHandler(UIBackgroundFetchResultNewData);
    [self performSelector:@selector(sendAckRequest:) withObject:alertID];
}


- (void)openViewController:(NSString *)notificationTitle{

    NSDictionary * userDict = [[NSUserDefaults standardUserDefaults] objectForKey:@"loginUser"];

    if([notificationTitle isEqualToString:@"Exercise"]){

    UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;

    UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];

    Excercise *excerciseController = (Excercise*)[mainStoryboard instantiateViewControllerWithIdentifier: @"Excercise"];       
    [navigationController pushViewController:excerciseController animated:YES];
    //[navigationController presentViewController:excerciseController animated:YES completion:nil];

    }else if([notificationTitle isEqualToString:@"Weight"]){

        UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;

        UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];

        Weight *weightController = (Weight*)[mainStoryboard instantiateViewControllerWithIdentifier: @"Weight"];           
       [navigationController pushViewController:weightController animated:YES];

        //[navigationController presentViewController:weightController animated:YES completion:nil];

    }else if([notificationTitle isEqualToString:@"MCQ"]){

        UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;

        UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];

        QuestionOfTheDay *questionController = (QuestionOfTheDay*)[mainStoryboard instantiateViewControllerWithIdentifier: @"QuestionOfTheDay"];
        questionController.self.dictUser = userDict;
        [navigationController pushViewController:questionController animated:YES]
    }
}

-(void)sendAckRequest:(NSString *)alertID {

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    manager.requestSerializer = [AFHTTPRequestSerializer serializer];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    NSString *userID =[[defaults objectForKey:@"loginUser"]objectForKey:@"UserId"];
    NSString *serverRegistrationID = [defaults objectForKey:@"server_registration_id"];

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];

    [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss"];
    NSString *currentDateString = [dateFormatter stringFromDate:[NSDate date]];

    //NSDate *currentDate = [dateFormatter dateFromString:currentDateString];

    //NSDictionary *parameter = @{@"ReminderDateTime":currentDateString};

    NSString *url = [NSString stringWithFormat:@"%@%@/%@/%@/?ReminderDateTime=%@",sendNotificationAck,userID,serverRegistrationID,alertID,currentDateString];


    NSLog(@"url: %@",url);

    [manager GET:url parameters:nil success:^(AFHTTPRequestOperation * _Nonnull operation, id  _Nonnull responseObject) {

        if(operation.response.statusCode == 200)
            NSLog(@"Notification Acknowledged");
        else
            NSLog(@"Notification failed to acknowledge");

    } failure:^(AFHTTPRequestOperation * _Nullable operation, NSError * _Nonnull error) {

        NSLog(@"error: %@",[error localizedDescription]);
    }];
}

- (NSString *)stringWithDeviceToken:(NSData *)deviceToken {

    const char *data = [deviceToken bytes];

    NSMutableString *token = [NSMutableString string];

    for (int i = 0; i < [deviceToken length]; i++) {

        [token appendFormat:@"%02.2hhX", data[i]];
    }

    return token;
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.

    if([UIApplication sharedApplication].applicationIconBadgeNumber!=0)
    [UIApplication sharedApplication].applicationIconBadgeNumber = [UIApplication sharedApplication].applicationIconBadgeNumber - 1;
}

@end
Run Code Online (Sandbox Code Playgroud)

dic*_*hen 4

首先,您的Remote Notification后台模式已启用,因此通知将在后台处理。现在的错误是,每当通知到来时,您都会将一个 viewController 推送到 viewController 堆栈,这就是为什么您会看到三个 viewController 堆叠在一起。

其次,didReceiveRemoteNotification可以在不同的状态下调用/处理。StateBackground如果应用程序在后台,StateInactive如果用户点击通知中心的通知,StateForeground如果应用程序在前台。您添加一个检查仅将 viewController 推送到 中StateBackground,这就是为什么点击通知时您看不到任何更改。