一、推送通知

推送通知就是向用户推送一条信息来通知用户某件事件,可以在应用退到后台后,或者关闭后,能够通过推送一条消息通知用户某件事情,比如版本更新等等。

推送通知的常用应用场景:
  • 一些任务管理APP,会到任务时间即将到达时,通知你该做任务了。
  • 健身APP定时提醒你应该健身了。
  • 买过电影票,提前半个小时通知你,电影即将开场。
  • 当你QQ或微信收到信息时,即使退到后台,也可以收到信息通知你。
  • 电商APP,推送一条消息通知我们有新品上架等等。
推送通知的常用展示样式:
  1. 屏幕顶部显示一块横幅
  2. 在锁屏界面显示一块横幅
  3. 更新APP图标数字
  4. 播放音效
  5. 屏幕中间弹出一个UIAlertView
推送通知分为:
  1. 本地推送通知:
    不需要联网,在APP代码中推送的通知,确定知道未来某个时间点应该提醒用户什么
    【开发人员在APP内部通过代码发生 = 本地推送通知】
  2. 远程推送通知:
    需要联网,是由服务器推送的通知,不确定未来某个时间点应该提醒用户什么
    【服务器可以确定通知时间和内容 = 远程推送通知】

使用原则:谁确定通知时间和内容,谁就可以发生

二、本地推送通知

本地推送通知步骤:
  1. 在iOS8以后使用本地推送通知,需要得到用户的许可
  2. 创建UILocalNotification本地通知对象,并设置必要属性
  3. 开始本地推送通知:
    第一种方法,延时推送,根据本地通知对象的fireDate设置进行本地推送通知

    1. [[UIApplication shareApplication] scheduleLocalNotification:notification];

    第二种方法,立刻推送,忽略本地通知对象的fireDate设置进行本地推送通知

    1. [[UIApplication shareApplication] presentLocalNotificationNow:notification];
  4. 监听用户点击通知:

    • APP处于前台,此时不会弹框通知用户,但会调用对应的代理方法 :
    1. -(void)application:(UIApplication *)application didReceiveLocalNotification;
    • APP处于后台,屏幕上方会弹出横幅,用户点击横幅后,会进入前台,调用上面的代理方法。
    • APP已关闭,屏幕上方会弹出横幅,用户点击横幅后,会启动APP,调用以下方法:
    1. -(BOOL)application:(UIApplication *)application
    2. didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
    3. /* 通过参数launchOptions获取本地推送通知内容 */
    4. UILocalNotification *local = launchOptions[UIApplicationLaunchOptionsLocalNotificationKey];
  5. 调用UIApplication的对象方法,取消本地推送通知:

    1. /* 取消指定的本地推送通知 */
    2. -(void)cancelLocalNotification:(UILocalNotification *)notification;
    3. /* 取消全部本地推送通知 */
    4. -(void)cancelAllLocalNotification;
以下是实例代码:
1. 注册通知代码以及UIAlertView显示通知方法代码
  1. - (BOOL)application:(UIApplication *)application
  2. didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  3. {
  4. //因为是storyboard启动,这里就没有其他启动代码了
  5. //iOS8.0以后,如果需要使用推送通知,需要得到用户许可
  6. if (application.currentUserNotificationSettings.types == UIUserNotificationTypeNone) {
  7. //注册通知,有横幅通知、应用数字通知、应用声音通知
  8. UIUserNotificationSettings * setting =
  9. [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert |
  10. UIUserNotificationTypeBadge |
  11. UIUserNotificationTypeSound
  12. categories:nil];
  13. [application registerUserNotificationSettings:setting];
  14. } else {
  15. //当APP关闭后接收到通知,在启动中获取本地推送通知对象
  16. UILocalNotification *notification = launchOptions[UIApplicationLaunchOptionsLocalNotificationKey];
  17. [self showLocalNotification:notification];
  18. }
  19. return YES;
  20. }
  21. /* 弹框UIAlertView显示本地通知的信息 */
  22. - (void)showLocalNotification:(UILocalNotification *)notification
  23. {
  24. /* 显示本地通知 */
  25. NSDictionary *userInfo = notification.userInfo;
  26. NSString *title = @"本地通知";
  27. NSString *msg = userInfo[@"msg"];
  28. UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
  29. message:msg
  30. delegate:nil
  31. cancelButtonTitle:@"取消"
  32. otherButtonTitles:@"确定", nil];
  33. [alert show];
  34. //移除本地通知
  35. [[UIApplication sharedApplication] cancelLocalNotification:notification];
  36. }
2. 创建本地通知代码
  1. /* 创建一个本地通知 */
  2. - (UILocalNotification *)makeLocalNotification{
  3. //创建本地推送通知对象
  4. UILocalNotification *notification = [[UILocalNotification alloc] init];
  5. //设置调用时间
  6. notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:10.0];//通知触发的时间,10s以后
  7. notification.repeatInterval = NSCalendarUnitMinute;//每隔多久重复发一次本地通知
  8. //设置通知属性
  9. notification.alertBody = @"最近添加了诸多有趣的特性,是否立即体验?";//通知主体
  10. notification.applicationIconBadgeNumber = 1;//应用程序图标右上角显示的消息数
  11. notification.alertAction = @"打开应用"; //待机界面的滑动动作提示
  12. notification.alertLaunchImage = @"Default";//通过点击通知打开应用时的启动图片,这里使用程序启动图片
  13. notification.soundName = UILocalNotificationDefaultSoundName;//收到通知时播放的声音,默认消息声音
  14. //设置用户信息
  15. notification.userInfo = @{ @"id":@1,
  16. @"user":@"Kenshin Cui",
  17. @"msg":@"我来了一发本地通知"};//绑定到通知上的其他附加信息
  18. return notification;
  19. }

如果需要每天的中午12点准时本地推送怎么办呢?
就像这么办,修改fireDaterepeatInterval属性

  1. NSDateFormatter *formatter1 = [[NSDateFormatter alloc]init];
  2. [formatter setDateFormat:@"yyyy-MM-dd HH-mm-sss"];
  3. NSDate *resDate = [formatter dateFromString:@"2016-04-09 12-00-00"];
  4. notification.fireDate = resDate;//设定为明天中午12点触发通知
  5. //记得设置当前时区,没有设置的话,fireDate将不考虑时区,这样的通知会不准确
  6. notification.timeZone = [NSTimeZone defaultTimeZone];
  7. notification.repeatInterval = NSCalendarUnitDay;//每隔一天触发一次
3. 监听用户点击
  1. /* 注册本地通知完成会调用,即用户点击确定授权后调用 */
  2. - (void)application:(UIApplication *)application
  3. didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
  4. {
  5. //在这里我们尝试发送本地推送通知
  6. if (notificationSettings.types != UIUserNotificationTypeNone) {
  7. UILocalNotification *notification = [self makeLocalNotification];
  8. //延迟调用通知
  9. [application scheduleLocalNotification:notification];
  10. //立刻发送通知
  11. //[application presentLocalNotificationNow:notification];
  12. }
  13. }
  14. /* 应用还在运行,无论前台还是后台,都会调用该方法处理通知 */
  15. - (void)application:(UIApplication *)application
  16. didReceiveLocalNotification:(UILocalNotification *)notification
  17. {
  18. if( notification ) {
  19. [self showLocalNotification:notification];
  20. }
  21. }
  22. /* 应用进入前台,去除应用边角数字显示 */
  23. - (void)applicationWillEnterForeground:(UIApplication *)application {
  24. //去除应用边角数字
  25. [application setApplicationIconBadgeNumber:0];
  26. }

三、远程推送通知

iOS远程消息推送步骤:
  1. 应用服务提供商从服务器端把要发送的消息设备令牌(device token)发送给苹果的消息推送服务器APNs
  2. APNs根据设备令牌在已注册的设备(iPhone、iPad、iTouch、Mac等)查找对应的设备,将消息发送给相应的设备。
  3. 客户端设备接将接收到的消息传递给相应的应用程序,应用程序根据用户设置弹出通知消息。
下面是更详细的流程:

所有的苹果设备,在联网状态下,都会和苹果服务器APNs建立一个长连接

  • 长连接:服务器可以向客户端发送消息,保证数据的即时性,但比较占用资源
  • 短连接:服务器无法主动向客户端发消息,会话结束后,就立即释放资源,节省资源

远程推送通知就是借助苹果设备与APNs服务器之间的长连接,借助APNs服务器讲消息发送给客户端。

远程推送通知实现的条件:
  1. 必须有真机,只有真机具备UDID,才能生成deviceToken设备令牌
  2. 需要开发推送Cer证书

证书的申请请参考:iOS学习笔记21-推送证书与秘钥申请

deviceToken的生成算法只有Apple掌握,为了确保算法发生变化后仍然能够正常接收服务器端发送的通知,每次应用程序启动都重新获得deviceToken

远程推送通知步骤:
  1. iOS8以后,使用远程通知,需要请求用户授权
  2. 注册远程通知成功后会调用以下方法,获取deviceToken设备令牌:

    1. -(void)application:(UIApplication *)application
    2. didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken;
  3. deviceToken设备令牌发送给服务器,时刻保持deviceToken是最新的
  4. 监听远程推送通知:

    1. -(void)application:(UIApplication *)application
    2. didReceiveRemoteNotification:(NSDictionary *)userInfo;
下面是实例代码:
1. 注册远程推送通知代码:
  1. - (BOOL)application:(UIApplication *)application
  2. didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  3. {
  4. //iOS8.0以后,如果需要使用本地推送通知,需要得到用户许可
  5. if (![application isRegisteredForRemoteNotifications]) {
  6. UIUserNotificationSettings * setting =
  7. [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert |
  8. UIUserNotificationTypeBadge |
  9. UIUserNotificationTypeSound
  10. categories:nil];
  11. [application registerUserNotificationSettings:setting];
  12. //注册远程推送通知
  13. [application registerForRemoteNotifications];
  14. }
  15. return YES;
  16. }
2. 注册成功调用代码:
  1. /* 注册远程推送通知成功会调用 ,在此接收设备令牌deviceToken */
  2. - (void)application:(UIApplication *)application
  3. didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
  4. {
  5. [self addDeviceToken:deviceToken];
  6. }
  7. /* 保存deviceToken,并同步服务器上保存的deviceToken,以便能正确推送通知 */
  8. - (void)addDeviceToken:(NSData *)deviceToken
  9. {
  10. NSString *key = @"DeviceToken";
  11. NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
  12. //取出原来的deviceToken,进行比较
  13. NSData *oldToken = [defaults objectForKey:key];
  14. if ([oldToken isEqualToData:deviceToken]) {
  15. //存入新的deviceToken
  16. [defaults setObject:deviceToken forKey:key];
  17. [defaults synchronize];
  18. //发送网络请求到服务器,说明deviceToken发生了改变
  19. [self sendDeviceTokenWithOldDeviceToken:oldToken newDeviceToken:deviceToken];
  20. }
  21. }
  22. /* 发送网络请求到服务器,说明deviceToken发生了改变,服务器那边也要同步改变 */
  23. - (void)sendDeviceTokenWithOldDeviceToken:(NSData *)oldToken newDeviceToken:(NSData *)newToken
  24. {
  25. //发送到服务器,下面是服务器的一个接口
  26. NSString *urlStr = @"http://192.168.1.101/RegisterDeviceToken.aspx";
  27. urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
  28. NSURL *url = [NSURL URLWithString:urlStr];
  29. //POST网络请求
  30. NSMutableURLRequest *requestM = [NSMutableURLRequest requestWithURL:url];
  31. requestM.HTTPMethod = @"POST";
  32. //POST请求的请求体
  33. NSString *bodyStr = [NSString stringWithFormat:@"oldToken=%@&newToken=%@",oldToken,newToken];
  34. requestM.HTTPBody = [bodyStr dataUsingEncoding:NSUTF8StringEncoding];
  35. //使用会话来发送网络请求
  36. NSURLSession *session = [NSURLSession sharedSession];
  37. NSURLSessionDataTask *dataTask =
  38. [session dataTaskWithRequest:requestM
  39. completionHandler:^(NSData *data,NSURLResponse *response,NSError *error){
  40. if(!error){
  41. NSLog(@"Send Success !");
  42. } else {
  43. NSLog(@"Send Failure, error = %@",error.localizedDescription);
  44. }
  45. }];
  46. //网络请求任务启动
  47. [dataTask resume];
  48. }
3. 监听远程推送通知:
  1. /* 收到远程推送通知时会调用 */
  2. - (void)application:(UIApplication *)application
  3. didReceiveRemoteNotification:(NSDictionary *)userInfo
  4. {
  5. NSString *title = @"远程推送通知";
  6. NSString *msg = userInfo[@"msg"];
  7. UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
  8. message:msg
  9. delegate:nil
  10. cancelButtonTitle:@"取消"
  11. otherButtonTitles:@"确定", nil];
  12. [alert show];
  13. }

四、第三方远程推送

上面的远程推送过程如果觉得实现比较麻烦,你可以使用第三方推送,例如:

  • 极光推送( JPush ),我只用过这个,界面还不错,这不是在打广告!
  • 个推
  • 腾讯信鸽

具体的集成步骤及使用方法,请查看对应的官方文档,非常详细。

iOS学习笔记22-推送通知的更多相关文章

  1. IOS学习笔记—苹果推送机制APNs

    转自:唐韧_Ryan http://blog.csdn.net/ryantang03/article/details/8482259 推送是解决轮询所造成的流量消耗和 电量消耗的一个比较好的解决方案, ...

  2. iOS开发资源:推送通知相关开源项目--PushSharp、APNS-PHP以及Pyapns等

    PushSharp  (github) PushSharp是一个实现了由服务器端向移动客户端推送消息的开源C#库,支持 iOS (iPhone/iPad APNS). Android (C2DM/GC ...

  3. 【原】iOS学习之极光推送

    一.极光推送工程端 1.下载SDK 极光推送是一个推送消息的第三方,SDK下载:https://www.jpush.cn/common/products 集成压缩包内容:包名为JPush-iOS-SD ...

  4. [html5] 学习笔记-服务器推送事件

    1.HTML5服务器推送事件介绍 服务器推送事件(Server-sent Events)是Html5规范的一个组成部分,可以用来从服务端实时推送数据到浏览器端. 传统的服务器推送技术----WebSo ...

  5. 推送通知iOS客户端编写实现及推送服务器端编写

    http://blog.csdn.net/tonny_guan/article/details/8963262 1.iOS客户端编程 推送通知技术在Mac OS X和iOS系统上都可以运行,我们本章主 ...

  6. 移动设备和SharePoint 2013 - 第3部分:推送通知

    博客地址:http://blog.csdn.net/foxdave 原文地址 在该系列文章中,作者展示了SharePoint 2013最显著的新功能概观--对移动设备的支持. 该系列文章: 移动设备和 ...

  7. iOS上简单推送通知(Push Notification)的实现

    iOS上简单推送通知(Push Notification)的实现 根据这篇很好的教程(http://www.raywenderlich.com/3443/apple-push-notification ...

  8. 转:向IOS设备发送推送通知

    背景 SMS 和 MMS 消息是由无线运营商通过设备的电话号码向特定设备提供的.实现 SMS/MMS 的服务器端应用程序的开发人员必须费大量精力才能与现有的封闭电信基础架构进行交互(其中包括获取电话号 ...

  9. iOS 远程推送通知

    1.什么是推送通知 在某些特殊情况下,应用程序被动收到的以不同种界面形式出现的提醒信息 推送通知的作用:可以让不在前台运行的app通知app发生了改变 iOS中得推送通知种类 远程推送通知(Remot ...

随机推荐

  1. tar.gz

    tar.gz,或者.tgz的文件一般是在UNIX下用tar和gunzip压缩的文件.可能的文件名还有.tar.gz等.gunzip是一种比pkzip压缩比高的压缩程序,一般 UNIX下都有.tar是一 ...

  2. 在SQL SERVER 2005中还原数据库时出现错误:system.data.sqlclient.sqlerror 媒体集有 2 个媒体簇 但只提供了 1 个。必须提供所有成员。 (microsoft.sqlserver.smo)

    问题:在SQL SERVER 2005中还原数据库时出现错误:system.data.sqlclient.sqlerror 媒体集有 2 个媒体簇 但只提供了 1 个.必须提供所有成员. (micro ...

  3. selenium--Xpath定位

    前戏 前面介绍过了七种定位方式,今天来介绍最后一种,也是最强大,本人最常用的定位方式xpath Xpath 即为 xml 路径语言,它是一种用来确定 xml 文档中某部分位置的语言.Xpath 基于 ...

  4. postman使用--构建工作流和newman

    构建工作流 在使用“Collection Runner”的时候,集合中的请求执行顺序就是请求在Collection中的显示排列顺序.但是,有的时候我们不希望请求按照这样的方式去执行,可能是执行完第一个 ...

  5. java HttpServletRequest 重复流读取

    在用reset接口的时候,常常会使用request.getInputStream()方法,但是流只能读取一次,一旦想要加上一个过滤器用来检测用户请求的数据时就会出现异常.   在过滤器中通过流读取出用 ...

  6. 分享一个Delphi跨平台Http库的封装,一个Delphi跨平台TCP库的封装

    { 单元名:跨平台的TCP客户端库封装 作者:5bug 网站:http://www.5bug.wang } unit uCPTcpClient; interface uses System.Class ...

  7. struts2的动态方法配置

    动态方法调用配置 <package name="test" extends="struts-default"> <aciton name=&q ...

  8. Python-DB接口规范

    threadsafety 线程安全级别.threadsafety 这是一个整数, 取值范围如下: 0:不支持线程安全, 多个线程不能共享此模块 1:初级线程安全支持: 线程可以共享模块, 但不能共享连 ...

  9. CSS - position属性小结

    Relative: 属于文档流,针对自身进行偏移: Absolute: 脱离文档流,针对最近的定位元素进行偏移,如果没有,则针对根元素,即body标签尽心偏移: Fixed: 和absolute基本一 ...

  10. shell脚本调试打印日志问题

    shell脚本调试打印日志问题 1. 需求 我们在编写脚本的时候,有时候需要做调试,便于我们定位问题,有时候等脚本上线之后,我们需要保留脚本执行过程中的记录.便于我们在出问题的时候,定位问题. 2. ...