81、iOS本地推送与远程推送详解

一、简介

  分为本地推送和远程推送2种。可以在应用没打开甚至手机锁屏情况下给用户以提示。它们都需要注册,注册后系统会弹出提示框(如下图)提示用户石否同意,如果同意则正常使用;如果用户不同意则下次打开程序也不会弹出改提示框,需要用户到设置里面设置。一共有三种提示类型:

UIUserNotificationTypeBadge:应用图标右上角的信息提示    

UIUserNotificationTypeSound:播放提示音

UIUserNotificationTypeAlert:提示框

二、本地推送

1.注册与处理

代码如下:

/// 一般在在启动时注册通知,程序被杀死,点击通知后调用此程序
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

- (void)registerAPN {

    // 注册通知

    if (@available(iOS 10.0, *)) { // iOS10 以上

        UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];

        [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert + UNAuthorizationOptionSound) completionHandler:^(BOOL granted, NSError * _Nullable error) {

            

        }];

    } else {// iOS8.0 以上

        UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil];

        [[UIApplication sharedApplication] registerUserNotificationSettings:setting];

    }

}

 return YES; } /// 程序没有被杀死(处于前台或后台),点击通知后会调用此程序 - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { // 这里添加处理代码 }

可以看到,处理代码有两个方法,一个是

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification;
另一个是
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
如果程序没有被杀死,即处于前台或者后台,那么调用前者;如果程序被杀死,则调用后者。

- (void)applicationWillResignActive:(UIApplication *)application {

    #pragma mark -->NSLog(@"\n ===> 程序挂起 !");  比如:当有电话进来或者锁屏,这时你的应用程会挂起,在这时,UIApplicationDelegate委托会收到通知,调用 applicationWillResignActive 方法,你可以重写这个方法,做挂起前的工作,比如关闭网络,保存数据。

}

- (void)applicationDidEnterBackground:(UIApplication *)application {

    #pragma mark --> NSLog(@"\n ===> 程序进入后台 !");

}

- (void)applicationWillEnterForeground:(UIApplication *)application {

    #pragma mark --> NSLog(@"\n ===> 程序进入前台 !");

    [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];

}

- (void)applicationDidBecomeActive:(UIApplication *)application {

    #pragma mark -->  NSLog(@"\n ===> 程序重新激活 !"); 应用程序在启动时,在调用了 applicationDidFinishLaunching 方法之后也会调用 applicationDidBecomeActive 方法,所以你要确保你的代码能够分清复原与启动,避免出现逻辑上的bug。(大白话就是说:只要启动app就会走此方法)。

}

- (void)applicationWillTerminate:(UIApplication *)application {

    #pragma mark --> 当用户按下按钮,或者关机,程序都会被终止。当一个程序将要正常终止时会调用 applicationWillTerminate 方法。但是如果长主按钮强制退出,则不会调用该方法。这个方法该执行剩下的清理工作,比如所有的连接都能正常关闭,并在程序退出前执行任何其他的必要的工作.

}

2.发送通知

- (void)addLocalNotice {

    if (@available(iOS 10.0, *)) {

        UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];

        UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];

        // 标题

        content.title = @"测试标题";

        content.subtitle = @"测试通知副标题";

        // 内容

        content.body = @"测试通知的具体内容";

        // 声音

//        content.sound = [UNNotificationSound defaultSound];

        content.sound = [UNNotificationSound soundNamed:@"Alert_ActivityGoalAttained_Salient_Haptic.caf"];

        // 角标 (我这里测试的角标无效,暂时没找到原因)

        content.badge = @1;

        // 多少秒后发送,可以将固定的日期转化为时间

        NSTimeInterval time = [[NSDate dateWithTimeIntervalSinceNow:2] timeIntervalSinceNow];

//        NSTimeInterval time = 10;

        // repeats,是否重复,如果重复的话时间必须大于60s,要不会报错

        UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:time repeats:NO];

        

        /*

        //如果想重复可以使用这个,按日期

        // 周一早上 8:00 上班

        NSDateComponents *components = [[NSDateComponents alloc] init];

        // 注意,weekday默认是从周日开始

        components.weekday = 2;

        components.hour = 8;

        UNCalendarNotificationTrigger *calendarTrigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:YES];

        */

        // 添加通知的标识符,可以用于移除,更新等操作

        NSString *identifier = @"noticeId";

        UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:identifier content:content trigger:trigger];

        

        [center addNotificationRequest:request withCompletionHandler:^(NSError *_Nullable error) {

            NSLog(@"成功添加推送");

        }];

    }else {

        UILocalNotification *notif = [[UILocalNotification alloc] init];

        // 发出推送的日期

        notif.fireDate = [NSDate dateWithTimeIntervalSinceNow:5];

        // 推送的内容

        notif.alertBody = @"你已经10秒没出现了";

        // 可以添加特定信息

        notif.userInfo = @{@"noticeId":@"00001"};

        // 角标

        notif.applicationIconBadgeNumber = 1;

        // 提示音

        notif.soundName = UILocalNotificationDefaultSoundName;

        // 每周循环提醒

        notif.repeatInterval = NSCalendarUnitWeekOfYear;

        

        [[UIApplication sharedApplication] scheduleLocalNotification:notif];

    }

}

3. 取消通知

// 取消所有本地通知
[application cancelAllLocalNotifications];

三、远程推送

与Android上我们自己实现的推送服务不一样,Apple对设备的控制非常严格,消息推送的流程必须要经过APNs(Apple Push Notification service).

一般情况下如果一个程序退到后台就不能运行代码(Audio、VoIP等等可以在后台运行),或者程序退出后,那么它就和对应应用的后台服务器断开了链接,就收不到服务器发送的信息了,但是每台设备只要联网就会和苹果的APNs服务器建立一个长连接(persistent IP connection),这样只要通过苹果的APNs服务器,我们自己的服务器就可以间接的和设备保持连接了,示意图如下:

使用步骤:

1 勾选Backgroud Modes -> Remote notifications,主要是iOS7之后,苹果支持后台运行,如果这里打开后,当接收到远程推送后,程序在后台也可以做一些处理,如下图所示:

 

2.远程推送机制

  

你的应用服务端将消息发送到apple的APNS服务器,APNS服务器将消息推送到指定的Iphone,最后由Iphone负责将消息推送至你的APP。在此先不说这个过程是如何实现的,仅仅看这个流程,你可能会觉得,在你们服务端和客户端之间增加了一个apple的APNS,不是增加开发者的负担么?其实结果恰恰相反,因为apple对推送的统一管理,使我们开发者的工作变得异常简单。

 3.服务端如何连接到客户端的

 如果你是做android开发的,你一定非常了解长链接与心跳包。事实上,大部分的android应用的推送也确实是通过长链接来实现的。因为android系统的开放性,APP是很容易做到自启动和后台长链接的,而心跳验证,就是始终保证长链接属于接通状态,然后由服务端直接推送消息。如果IOS开发者也采用这种思路,就十分困难了,在IOS中想要保持一个APP服务始终不被系统杀死,我只能说太难了。通过上面的流程图,对比android的推送思路,我们很容易明白,IOS中其实也始终有一个长链接,那就是系统本身,这个长链接始终与APNS服务器相连,然后统一管理所有应用程序的推送。

4.
这是IOS推送机制的优势?

1、因为推送的服务端是appleID的验证用户,推送可靠性会高。

2、所有推送消息由APNS统一管理,效率高。

3、在客户端只需系统维护一个长链接,节省了用户流量消耗和手机的性能消耗,并且提高了安全性,使得有恶意推送和流氓软件的几率降低。

准备工作:参考大神博客https://www.cnblogs.com/ludashi/p/4093454.html

猜你喜欢

转载自www.cnblogs.com/qiangzheVSruozhe/p/10577884.html