美文网首页
ios10前后推送基本使用

ios10前后推送基本使用

作者: 冷武橘 | 来源:发表于2021-06-09 16:33 被阅读0次

    一、推送的分类

    • 本地推送通知
      “本地”可以理解为”不联网”;即使没有网络情况下,也可以推送通知消息
      通知发送方: 开发人员负责在APP内发送
      应用场景: 确定知道未来某个时间点应该提醒用户什么

    • 远程推送通知
      与“本地”相对,表示,必须在联网情况下才会向用户推送通知消息
      远程推送服务,又称为APNs(Apple Push Notification Services)
      通知发送方: 服务器
      应用场景:

    1. 不确定未来某个时间点应该提醒用户什么,临时性的
    2. 当APP彻底退出时也想继续让用户获取一些最新消息

    二、注册推送

    使用推送前你必须注册设置推送的形式,注册后系统才会弹出使用本地通知的权限弹框。

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
       #ios8-ios10
    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
           [application registerUserNotificationSettings:settings];
    
      return YES;
    }
    

    三、ios8-ios10

    注意:如果当前程序正运行在前台,那么推送通知就不会被呈现出来

     调度本地推送通知(调度完毕后,推送通知会在特地时间fireDate发出)
    [[UIApplication sharedApplication] scheduleLocalNotification:ln];
    
    取消调度本地推送通知
    - (void)cancelLocalNotification:(UILocalNotification *)notification;
    - (void)cancelAllLocalNotifications;
    
    立即发出本地推送通知
    - (void)presentLocalNotificationNow:(UILocalNotification *)notification;
    

    3.1、本地通知

    - (IBAction)fireLocalNote:(id)sender {
        // 1.创建本地通知
        UILocalNotification *localNote = [[UILocalNotification alloc] init];
        
        // 2.设置本地通知的内容
        // 2.1.设置通知发出的时间
        localNote.fireDate = [NSDate dateWithTimeIntervalSinceNow:3.0];
        // 2.2.设置通知的内容
        localNote.alertBody = @"吃饭了吗?";
        // 2.3.设置滑块的文字
        localNote.alertAction = @"快点";
        // 2.4.决定alertAction是否生效
        localNote.hasAction = NO;
        // 2.5.设置点击通知的启动图片
        localNote.alertLaunchImage = @"3213432dasf";
        // 2.6.设置alertTitle
        localNote.alertTitle = @"3333333333";
        // 2.7.设置有通知时的音效
        localNote.soundName = @"buyao.wav";
        // 2.8.设置应用程序图标右上角的数字
        localNote.applicationIconBadgeNumber = 999;
        
        // 2.9.设置额外信息
        localNote.userInfo = @{@"type" : @1};
        
        // 3.调用通知
        [[UIApplication sharedApplication] scheduleLocalNotification:localNote];
    }
    
    #pragma mark- 接收到本地通知时调用
    - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
    {
        // 当后台收到消息时,点击消息进行界面跳转
        if (application.applicationState == UIApplicationStateInactive) {
            NSLog(@"进行界面的跳转");
            NSLog(@"%@", notification.userInfo);
        
            UIView *redView = [[UIView alloc] init];
            redView.frame = CGRectMake(0, 0, 100, 100);
            redView.backgroundColor = [UIColor yellowColor];
            [self.window.rootViewController.view addSubview:redView];
        }
    }
    
    • 1、前台接收消息时调用
    • 2、后台在接收到消息时,点击消息进入前台时调用。
    • 3、程序杀死后,接收到消息时不会调用。

    针对应用程序被杀死的情况我们可以这样处理

        if (launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]) {
            // 跳转代码
            UILabel *redView = [[UILabel alloc] init];
            redView.frame = CGRectMake(0, 0, 200, 300);
            redView.numberOfLines = 0;
            redView.font = [UIFont systemFontOfSize:12.0];
            redView.backgroundColor = [UIColor redColor];
            redView.text = [NSString stringWithFormat:@"%@", launchOptions];
            [self.window.rootViewController.view addSubview:redView];
        }
    

    3.2、远程通知

    3.2.1、获取DeviceToken

    1、当得到苹果的APNs服务器返回的DeviceToken就会被调用

    - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
        NSLog(@"deviceToken是:%@", deviceToken);
    }
    

    2、 当接收到远程通知时调用, iOS3.0之后有效

    -(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
    {
        NSLog(@"-2--%@", userInfo);
        //    [self.window.rootViewController.view addSubview:[[UISwitch alloc] init]]; // 测试app退出是否执行代码
    }
    
    • 当前在前台时; 或者app在后台状态下,点击通知打开app进入前台; 都可以执行这个方法
      3、 当接收到远程通知时调用, iOS7.0之后有效
    -(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
    {
        NSLog(@"---%@", userInfo);
        [self.window.rootViewController.view addSubview:[[UISwitch alloc] init]]; // 测试app退出是否执行代码
        completionHandler(UIBackgroundFetchResultNewData);
    }
    
    • 当前在前台时; 或者app在后台、或者甚至app被杀死,点击通知打开app进入前台; 都可以执行这个方法
    • 如果实现了这个方法那么上面(2)那个方法就不会执行

    3.2.2、普通推送和静默推送

    • 普通推送:就是常见的带有alter或者声音等的推送
    • 静默推送: 就是用户无感知的推送,完全没有声音和文字。

    普通推送和静默推送都是执行下面这个方法,区别在于:
    1、静默推送,不用点开通知,不用打开APP,就能执行下面这个方法
    2、普通推送和静默推送的内容格式不同

    -(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
    {
    
        [vc loadDataWithContentID:contentId completion:^(NSArray *dataList) {
            vc.dataList = dataList;
    
            NSLog(@"刷新数据结束");
    
            completionHandler(UIBackgroundFetchResultNewData);
        }];
    }
    
    • 1、 执行completionHandler的作用: 系统会估量App消耗的电量,并根据传递的UIBackgroundFetchResult 参数记录新数据是否可用;调用完成的处理代码时,应用的界面缩略图会自动更新
    • 2、如果想实现静默推送的效果:
      a、必须选后台模式Remote Notification;
      b、告诉系统是否有新的内容更新(执行完成代码块)
      c、设置发送通知的格式("content-available”:1)
    • 3、我们最多有30s的时间来处理数据,例如上面接收到远程通知到执行完网络请求之间的时间不能超过30秒

    四、ios10及之后的推送(UserNotification)

    4.1、新的注册方式

            UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
            // 必须写代理,不然无法监听通知的接收与点击
            center.delegate = self;
            [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound) completionHandler:^(BOOL granted, NSError * _Nullable error) {
                if (granted) {
                    // 点击允许
                    NSLog(@"注册成功");
                    [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
                        NSLog(@"%@", settings);
                    }];
                } else {
                    // 点击不允许
                    NSLog(@"注册失败");
                }
    

    4.2、UNNotificationTrigger

    苹果把本地通知跟远程通知合二为一,主要用UNNotificationTrigger这个类进行区分

    • 1、UNPushNotificationTrigger(远程通知) 远程推送的通知类型
    • 2、UNTimeIntervalNotificationTrigger (本地通知) 一定时间之后,重复或者不重复推送通知。我们可以设置timeInterval(时间间隔)和repeats(是否重复)。
    • 3、UNCalendarNotificationTrigger(本地通知) 一定日期之后,重复或者不重复推送通知 例如,你每天8点推送一个通知,只要dateComponents为8,如果你想每天8点都推送这个通知,只要repeats为YES就可以了。
    • 4、UNLocationNotificationTrigger (本地通知)地理位置的一种通知,当用户进入或离开一个地理区域来通知。

    4.3、创建一个本地通知

    
           UNTimeIntervalNotificationTrigger *timeTrigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:6.0f repeats:NO];
              
           // 创建通知内容 UNMutableNotificationContent, 注意不是 UNNotificationContent ,此对象为不可变对象。
           UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
           content.title = @"Dely 时间提醒 - title";
           content.subtitle = [NSString stringWithFormat:@"Dely 装逼大会竞选时间提醒 - subtitle"];
           content.body = @"Dely 装逼大会总决赛时间到,欢迎你参加总决赛!希望你一统X界 - body";
           content.badge = @666;
           content.sound = [UNNotificationSound defaultSound];
           content.userInfo = @{@"key1":@"value1",@"key2":@"value2"};
           
           // 创建通知标示
           NSString *requestIdentifier = @"Dely.X.time";
           
           // 创建通知请求 UNNotificationRequest 将触发条件和通知内容添加到请求中
           UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:requestIdentifier content:content trigger:timeTrigger];
           
           UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
           // 将通知请求 add 到 UNUserNotificationCenter
           [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
               if (!error) {
        
                   dispatch_async(dispatch_get_main_queue(), ^{
                   
                   });
    
               }
           }];
    

    4.4、对通知消息的接收和点击

    ios10之前对通知消息的接收和点击都是通过-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler进行处理的,ios10之后分别用了两个代理方法进行处理:
    - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler

    4.4.1、监听通知
    - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
        NSDictionary * userInfo = notification.request.content.userInfo;
        UNNotificationRequest *request = notification.request; // 收到推送的请求
        UNNotificationContent *content = request.content; // 收到推送的消息内容
        NSNumber *badge = content.badge;  // 推送消息的角标
        NSString *body = content.body;    // 推送消息体
        UNNotificationSound *sound = content.sound;  // 推送消息的声音
        NSString *subtitle = content.subtitle;  // 推送消息的副标题
        NSString *title = content.title;  // 推送消息的标题
    
        if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
            NSLog(@"远程通知");
            
        }else {
            NSLog(@"本地通知");
        }
    completionHandler(UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound|UNNotificationPresentationOptionAlert); // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以设置
    }
    
    • 1、只有当app处于前台状态时,接收到远程推送或者本地推送才会调用;当app处于后台模式时是不会调用的;
    • 2、completionHandler的回调意味着消息通知可以在前台显示(ios10之前,如果当前程序正运行在前台,那么推送通知就不会被呈现出来)
    • 3、本地通知和远程的通知的监听都是用同一个代理方法
    4.4.2、通知的点击
    - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler{
        //收到推送的请求
        UNNotificationRequest *request = response.notification.request;
        
        //收到推送的内容
        UNNotificationContent *content = request.content;
        
        //收到用户的基本信息
        NSDictionary *userInfo = content.userInfo;
        
        //收到推送消息的角标
        NSNumber *badge = content.badge;
        
        //收到推送消息body
        NSString *body = content.body;
        
        //推送消息的声音
        UNNotificationSound *sound = content.sound;
        
        // 推送消息的副标题
        NSString *subtitle = content.subtitle;
        
        // 推送消息的标题
        NSString *title = content.title;
        
        if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
            NSLog(@"远程通知");
            
        }else {
            NSLog(@"本地通知");
        }
        completionHandler();
    }
    
    • 1、app在前台、后台、杀死状态下收到消息,点击消息时都会调用
    • 2、completionHandler()必须调用,系统要求要不然控制台会报错
    • 3、本地通知和远程通知的监听都是使用这个方法

    4.4.3、静默推送

    -(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
    {
    }
    
    • 在使用了UserNotification做推送时,这个方法只有在静默推送时才会被调用。

    相关文章

      网友评论

          本文标题:ios10前后推送基本使用

          本文链接:https://www.haomeiwen.com/subject/kgfeeltx.html