ios APP前台时显示消息通知

       最近整理了项目使用的推送资料,包括原生APNS、亚马逊推送、谷歌FireBase推送,从申请证书到代码工具调试,基本整理的差不多。

        本篇文章主要介绍app在前台活跃时,有推送时显示系统的原始通知框。在网上查了很多资料,都说只能app在后台时才能调用系统的通知弹框,所以以前用的是自定义的弹框,最近发现在app活跃时,可以调用本地通知达到app前台活跃时显示系统的弹框。

//UIApplicationLaunchOptionsRemoteNotificationKey对应的是启动应用程序的远程通知信息userInfo(NSDictionary)
-(void) dealPushNotificacton:(NSDictionary*) launchOptions {
    NSDictionary *remoteNotificationDic = nil;
    if (launchOptions != nil)
    {
        remoteNotificationDic = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
        if (remoteNotificationDic != nil)
        {
            UPDINFO(@"Launched from push notification: %@", remoteNotificationDic);
            self.remoteNotificationUserInfo = remoteNotificationDic;
        }
    }
    [self registerRemoteNotifications];
}
- (void)registerRemoteNotifications {
    if ([UPIUtils deviceOS] < 10.0 ) {
        [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound |    UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
        dispatch_async(dispatch_get_main_queue(), ^{
            [[UIApplication sharedApplication] registerForRemoteNotifications];
        });
        
    } else { 
        UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
        center.delegate = self;
        [center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error)
         {
             if(!error )
             {
                 dispatch_async(dispatch_get_main_queue(), ^{
                     [[UIApplication sharedApplication] registerForRemoteNotifications];
                 });
             } else {
                 
             }
         }];
    }
}
ios 10之前和之后注册推送的方式不一样,要注意,下面需要注册通知成功和失败的代码。
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(nonnull NSData *)deviceToken
{ 
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
}

下面的方法,当app在后台时点击才会进,app在前台时,收到通知就会进,大家可以打断点调试一下。

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    // 收到推送通知后逻辑
    UPDINFO(@"didReceiveRemoteNotification %@",userInfo);
    self.remoteNotificationUserInfo = userInfo;
    //UIApplicationStateActive = 在app界面; UIApplicationStateInactive = 未在app界面;
    if (application.applicationState == UIApplicationStateActive)
    {
        [self showLocalNotification];
        //[self showRemoteNotification];
    } else {
        [self handlePushMessageInfo];
    }
}

        下面是不同的系统版本,调用本地通知,其中设置shouldAlwaysAlertWhileAppIsForeground参数直接决定了是否显示前台通知,大家要注意。其他的title,body,userinfo等信息看情况自己取值。

-(void)showLocalNotification
{
    if ([UPIUtils deviceOS] < 10.0 ) {
        UILocalNotification *notification = [[UILocalNotification alloc] init];
        notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:0.1];
        notification.repeatInterval = NSCalendarUnitDay;
        notification.alertBody = self.remoteNotificationUserInfo[@"data"][@"content"];
        notification.timeZone = [NSTimeZone defaultTimeZone];
        notification.soundName = UILocalNotificationDefaultSoundName;
        [[UIApplication sharedApplication] scheduleLocalNotification:notification];
    } else {
        //必须写代理,不然无法监听通知的接收与点击事件
        UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
        center.delegate = self;
        UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
        content.body = self.remoteNotificationUserInfo[@"data"][@"content"];
        content.userInfo = self.remoteNotificationUserInfo;
        content.sound = [UNNotificationSound defaultSound];
        //ios 12 后失败,会导致闪退
        //[content setValue:@(YES) forKeyPath:@"shouldAlwaysAlertWhileAppIsForeground"];
        
        UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"Notif" content:content trigger:nil];
        [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
        }];
    }
}

     下面的这两个代理其实是声明通知方法的代理,适用于10及以上,这里注释掉通知点击之前的代码,只保留点击后的代理方法,在点击后方法中传值,跳转页面等。因为使用的是 didReceiveRemoteNotification方法,好像不兼容10及以上,但是系统会自动适配,所以注释掉了这个代理,不然只走点击前的方法,不走didReceiveRemoteNotification了。

// 该两个代理回调适用于10以上,点击前:
//- (void)userNotificationCenter:(UNUserNotificationCenter *)center
//       willPresentNotification:(UNNotification *)notification
//         withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
//
//    completionHandler(UNNotificationPresentationOptionSound);
//}
//点击后:
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
         withCompletionHandler:(void (^)(void))completionHandler {
    
    [self handlePushMessageInfo];
}

  下面的方法用不上,类似于didReceiveRemoteNotification这个方法。调试的时候试了很久,完全浪费时间。

////收到本地通知进行,点击跳转
//- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
//{
//    //前台跳转
//    if (application.applicationState == UIApplicationStateActive) {
//         [self handlePushMessageInfo];
//    }
//}

 

 

 

 

 

 

 

 

你可能感兴趣的:(ios)