iOS-----推送机制

推 送 机 制

使用NSNotificationCenter通信

NSNotificationCenter实现了观察者模式,允许应用的不同对象之间以松耦合的方式进行通信。

NSNotification代表Poster与Observer之间的信息载体,该对象包含如下只读属性。


name:该属性代表该通知的名字,程序将Poster注册到指定通知中心时,就是根据该名称进行注册的


object:该属性代表该通知的Poster。


userInfo:该属性是一个NSDictionary对象,用于携带通知的附加信息。

NSNotificationCenter是整个通知系统的中心,Observer向NSNotificationCenter注册自己感兴趣的通知,Poster向NSNotificationCenter发送通知。


- addObserverForName:object:queue:usingBlock:该方法将指定代码块注册为监听者,监听object:参数代表的对象(Poster)发出的通知(由第1个参数指定通知名称)。该方法直接使用指定代码块作为监听者,当Poster向NSNotificationCenter发送通知时,将会触发、执行该代码块。如果object:参数为nil,则用于监听任何对象发出的通知。


示例说明

 1 ViewController.m
 2
 3 @implementation ViewController
 4
 5 - (void)viewDidLoad
 6
 7 {
 8
 9             [super  viewDidLoad];
10
11             // 监听UIApplicatiob的                  UIApplicationDidFinishLaunchingNotification通知
12
13             [[NSNotificationCenter  defaultCenter]  addObserver:self
14
15          selector:@selector(launch:)
16
17          name:UIApplicationDidFinishLaunchingNotification
18
19          object:[UIApplication sharedApplication]];
20
21          // 监听UIApplicatiob的         UIApplicationDidEnterBackgroundNotification通知
22
23           [[NSNotificationCenter  defaultCenter]  addObserver:self
24
25          selector:@selector(back:)
26
27          name:UIApplicationDidEnterBackgroundNotification
28
29          object:[UIApplication sharedApplication]];
30
31          // 监听UIApplicatiob的         UIApplicationWillEnterForegroundNotification通知
32
33             [[NSNotificationCenter  defaultCenter]  addObserver:self
34
35          selector:@selector(fore:)
36
37          name:UIApplicationWillEnterForegroundNotification
38
39          object:[UIApplication  sharedApplication]];
40
41 }
42
43 - (void)back: (NSNotification*)Notification
44
45 {
46
47             self.showLabel.text = [NSString stringWithFormat:@”应用程序加载完成!”];
48
49 }
50
51 - (void)launch: (NSNotification*)Notification
52
53 {
54
55             self.showLabel.text = [NSString  stringWithFormat:@”%@\n应用程序进入后台!”,
56
57          self.showLabel.text];
58
59 }
60
61 - (void) fore: (NSNotification*)Notification
62
63 {
64
65          self.showLabel.text = [NSString  stringWithFormat:@”%@\n应用程序进入前台!”,
66
67          self.showLabel.text];
68
69 }
70
71 @end

使用NSNotificationCenter监听自定义通知

使用NSNotificationCenter除了可以监听系统组件发出的通知之外,也可以监听程序自己发出的通知.下面示例将使用异步操作来模拟执行一个耗时任务,并在界面上使用UIProgressView显示耗时任务的执行进度.


示例代码

ViewController.m

@import “ViewController.h”

#define  PROGRESS_CHANGED   @”down_progress_changed”

@interface ViewController()

{

       NSNotificationCenter*  nc;

       NSOperationQueue* queue;

}

@end

@implementation ViewController

- (void)viewDidLoad

{

          [super  viewDidLoad];

          nc = [NSNotificationCenter  defaultCenter];

          queue = [[NSOperationQueue  alloc]  init];

          // 设置该队列最多支持10个并发线程

          queue.maxConcurrentOperationCount = 10;

          // 使用视图控制器监听任何对象发出的 PROGRESS_CHANGED 通知

          [nc  addObserver:self  selector:@selector(update:)

       name: PROGRESS_CHANGED  object:nil]; // ①

}

- (IBAction)start: (id)sender

{

       __block int progStatus = 0;

       [sender  setEnabled:NO];

       // 以传入的代码块作为执行体,创建NSOperation

       NSBlockOperation* operation = [NSBlockOperation 

       blockOperationWithBlock:^{

                for(int I = 0; i < 100;  i++)

               {

                  // 暂停0.5秒模拟耗时任务

                 [NSThread  sleepForTimeInterval: 0.5] ;

               // 创建NSNotification,并指定userInfo信息

                       NSNotification*  noti = [NSNotification                notificationWithName: PROGRESS_CHANGED  object:nil  userInfo: [NSDictionary  dictionaryWithObjectsAndKeys: [NSNumber numberWithInt: ++ progStatus]

,@”prog” ,  nil]];

              // 发送通知

               [nc  postNotification : noti]; // ②

                }

       }];

       // 将NSOperation添加给NSOperationQueue

       [queue  addOperation:  operation];

}

- (void)update: (NSNotification*) noti

{

       // 通过userInfo属性获取耗时任务的进度信息

       NSNumber* progStatus = noti.userInfo[@”prog”];

       NSLog(@”%d”, progStatus.intValue);

       dispatch_async(dispatch_get_main_queue(), ^{

          self.prog.progress = progStatus.intValue  /  100.0;

          // 当任务执行进度执行到100时,启用按钮

          if(100 == progStatus.intValue)

         {

             [self.bn  setEnabled: YES];

          }

      });

}

@end


上面程序中的第1行代码将视图控制器注册为通知监听者,用于监听任何对象的PROGRESS_CHANGED通知;接下来的第②行代码先创建了一个NSNotification,并使用NSNotificationCenter发送该通知。当该异步代码块向NSNotificationCenter发送通知之后,通知监听者的方法(update:)将会被触发执行,这个update:方法将会更新界面上UIProgressView的进度.

iOS本地通知

本地通知属于应用界面编程的内容,本地通知和远程推送通知都可以向不在前台运行的应用发送消息,这种消息既可能是即将发生的事件,也可以是服务器的新数据,都可能显示为一段警告信息信息或应用程序图标上的徽标。

本地通知和远程推送通知的基本目的都死让应用程序能够通知用户某些事情,而且不需要应用程序在前台运行。二者的区别在于:本地通知由本应用负责调用,只能从当前设备上的 iOS 发出;而远程推送通知由远程服务器上的程序(可由任意语言编写)发送至 Apple Push Notification service(APNs), 再由 APNs 把消息推送至设备上对应的程序.[BL1]


本地通知是一个 UILocalNotification对象,它有如下常用属性.


fireData: 指定通知将在什么时间触发.


repeatInterval:设置本地通知重复发送的时间间隔.


alertBody: 设备本地通知的消息体.


alertAction:  设置当设备处于锁屏状态时,显示通知的警告框下方的 title.


has Action: 设置是否显示 Action.


alertLaunchImage: 当用户通过该通知启动对应的应用时, 该属性设置为加载图片.


applicatonIconBadgeNumber: 设置显示在应用程序上红色徽标中的数字.


soundName: 设置通知的声音.


userInfo: 设置该通知携带的附加信息.


创建了 UILocalNotification对象之后,接下来就可以通过 UIApplication 的如下两个方法发送通知了


l  - scheduleLocalNotification: 该方法指定调度通知。通知将会于 fireDate 指定的时间触发,而且会按 repeatInterval 指定的时间间隔重复触发。

l  - presentLocalNotificationNow: 该方法指定立即发送通知。该方法会忽略UILocalNotification的fireDate属性。


如果系统发出通知时,应用程序处于前台运行,系统将会触发应用程序委托类的application:didReceiveLocalNotification:方法。


在iOS应用中发送本地通知的步骤很简单,只要如下几步即可。

  1. 创建UILocalNotification对象
  2. 设置UILocalNotification的属性
  3. 调用UIApplication的方法发送或调用通知
  4. 如果希望应用程序在前台运行时可以对通知进行相应的处理,则需要重写应用程序委托类的application:didReceiveLocalNotification:方法。
  5. 当应用需要取消本地通知时,可调用UIApplication的cancelLocalNotification:方法取消指定通知,或调用cancelLocalNotifications方法取消所有通知。

示例示范如何开发本地通知

ViewController.m

@interface  ViewController()

{

    UIApplication* app;

}

@end

@implementation  ViewController

- (void)viewDidLoad

{

     [super  viewDidLoad];

    app = [UIApplication  sharedApplication];

}

- (IBAction)changed: (id)sender

{

     UISwitch*  sw  = (UISwitch*)sender;

     if(sw.on)

     {

         //  创建一个本地通知

         UILocalNotification*  notification  = [[UILocalNotification  alloc] init]; // ①

         //  设置通知的触发时间

          notification.fireDate  = [NSDate  dateWithTimeIntervalSinceNow:10];

        //  设置通知的时区

       notification.timeZone = [NSTimeZone  defaultTimeZone];

       // 设置通知重复发送的时间间隔

       notification.repeatInterval = kCFCalendarUnitMinute;

          //  设置通知的声音

          notification.soundName  = @”gu.mp3”;

           //  设置当设备处于锁屏状态时, 显示通知的警告框下方的 title

           notification.alertAction =  @”打开”;

           //  设置通知是否显示 Action

           notification.hasAction = YES;

            //  设置通过通知加载应用时显示的图片

           notification.alertLaunchingImage  = @”logo.png”;

              //  设置通知内容

              notification.alertBody = @”轮到你下棋了,  赶快走棋!”;

              // 设置显示在应用程序上红色徽标中的数字

              notification.applicationIconBadgeNumber  =  1;

              //  设置 userInfo, 用于携带额外的附加信息

              NSDictionary*  info = @{@”123456”: @”key”};

              notification.userInfo = info;

              //  调度通知

              [app scheduleLocalNotification:Notification]; // ①

             }

       else

              {

                  // 获取所有处于调度中的本地通知数组

                 NSArray*  localArray = [app  scheduledLocalNotifications];

                 if(localArray)

                 {

                      for(UILocalNotification * noti  in  localArray)

                       {

                         NSDictionary*  dict  = noti.userInfo;

                            if(dict)

                       {

                       //  如果找到要取消的通知

                       NSString*  inKey = [dict  objectForKey:@”key”];

                       if([inKey  isEqualToString:@”123456”])

                       {

                          // 取消调度该通知

                          [app  cancelLocalNotification: noti]; // ②

                         }

                       }

                     }

                   }

             }

}
@end


上面程序中的第①段代码创建了一个UILocalNotification对象,并为该对象设置了相关属性,接下来在①号代码处调用了UIApplication的scheduleLocalNotification:方法来调度通知,这样该通知将会在指定事件触发,并按相应的周期重复执行。当用户把UISwitch控件切换到关闭状态时,②号代码将会取消调度该通知。

为了让程序处于前台运行时也能看到本地通知,还重写了应用程序委托类的application:didReceiveLocalNotification:方法。

 AppDelegate.m

@implementation  AppDelegate
//  只有当应用程序在前台运行时,该方法才会被调用

- (void)application: (UIApplication*)application

  didReceiveLocalNotification: (UILocalNotification*) notification

{

       // 如果应用程序在前台运行,则将应用程序图标上的红色徽标中的数字设为0

       application.applicationIconBadgeNumber = 0; // ①

       // 使用UIAlertView显示本地通知的信息

       [[[UIAlertView  alloc]  initWithTitle:@” 收到通知  ”

       message:notification.alertBody

       delegate:nil  cancelButtonTitle:@”确定”

       otherButtonTitles: nil]  show];  // ②

}

- (void)applicationWillEnterForeground: (UIApplication*) application

{

               // 当应用程序再次进入前台运行时,将应用程序徽标中数字设为0

              application.applicationIconBadgeNumber = 0;

}
…
@end


上面程序中的第①②段代码控制当应用程序处于前台运行时,即使程序收到了本地通知,也依然会将应用程序图标上的红色徽标中数字设为0。

iOS远程推送通知

iOS远程推送通知由远程服务器上的程序(可由任意语言编写)发送至APNs,再由APNs把消息推送至设备上对应的程序。

iOS远程推送通知的过程可用下图进行描述

在上面中,Provider指远程服务器上的Push服务端应用,这种Push服务端应用可以使用任意语言编写,如Java、PHP等。

APNs由Apple公司提供,APNs负责把通知发送到对应的iOS设备,该设备再把通知转发给ClientApp-----即我们的iOS应用。


上面所示的过程分为3个阶段


第一个阶段:Provider程序把要发送的通知、目标iPhone的device token (相当于该设备的唯一标识)打包,发给APNs.


第二阶段:APNs通过已注册Push服务的iPhone列表查找具有对应device token的iPhone,并把Push通知发送给对应的iPhone。


第三阶段:iPhone将收到的Push通知传递给相应的应用程序,并且按照设定弹出Push通知。


实际上,Push服务端程序可以通过APNs将一条通知发送给多个iPhone 上的客户端应用;与此同时,iPhone上的客户端应用也可接收多个Push服务端程序发送过来的推送通知。下图显示了这种示意图


对于开发iOSPush服务而言,完整的过程如下。

  1. 应用程序注册远程推送通知。
  2. 当应用程序注册推送通知成功或注册失败时,系统都会触发应用程序委托类的对应方法。可以通过重写应用程序委托类的这些方法来获取该设备注册成功后得到的device token。
  3. 应用程序将device token发送给Push服务端程序
  4. 服务端程序向APNs发送通知。
  5. APNs将通知发送给iOS应用------实际的过程是先发送给指定的iOS设备,再由该设备弹出Push通知。[BL2]


从上图可以看出,Push客户端应用需要3个组件。

  • App
    ID(应用程序唯一标识,这个必须到Apple网站注册来获得)
  • Provisioning
    Profile(这个也必须到Apple网站下载)
  • device
    token(当Push客户端应用注册Push推送通知成功时,APNs将会返回该设备的device  token)。[BL3]

Push服务端程序则需要如下两个组件

  • SSL
    Certificate(SSL连接证书,这个必须从Apple网站下载)。
  • Private
    Key(私钥,这个可用过开发者电脑导出)。

开发Push客户端应用

开发Push客户端应用需要到Apple网站注册一个App ID,而且该App ID不允许使用通配符。通过Apple网站注册App ID的步骤如下。

  1. 打开OS
    X系统上的”钥匙串访问”应用,单击该应用的主菜单”钥匙串访问” →”证书助理”→”从证书颁发机构请求证书”,如下图所示.

  1. 单击”从证书颁发机构请求证书”后,将会显示下图所示的对话框
  2. 输入电子邮件地址和常用名称,并选中“存储到磁盘”单选钮,然后单击“继续”按钮,该程序将会创建一个“Certificate
    Signing Request”(证书签名请求)文件,系统弹出下图所示的保存文件对话框

将证书签名请求文件保存到磁盘上,此处将该文件保存为“Push。cerSigningRequest”。

  1. 使用浏览器打开 https://developer.apple.com/ios/manage/overview/index.action站点, 页面上将会提示用户输入开发者账号\密码. 登录成功后会看到如下说是的页面

在上图所示页面中,可以看到在“iOS
Apps”栏目下包含了Certificates、Identifiers、Device、ProvisioningProfiles-----这些只有登录账号已经加入iOS Developer Program(iDP)的原因。

  1. 单击“iOS
    Apps”
    →“Identifiers”→栏目下的”App
    IDS” 链接,系统将会显示如下图

  


[BL1]本地通知与远程推送的区别

[BL2]开发iOSPush服务的完整的过程

[BL3]Push客户端应用需要3个组件

时间: 2024-10-08 10:29:00

iOS-----推送机制的相关文章

教你做IOS推送 包会!

最近在研究iOS的推送问题,遇到了一些问题,最终整理了一下,放在这里和大家分享. APNS的推送机制 首先我们看一下苹果官方给出的对iOS推送机制的解释.如下图 Provider就是我们自己程序的后台服务器,APNS是Apple Push Notification Service的缩写,也就是苹果的推送服务器. 上图可以分为三个阶段: 第一阶段:应用程序的服务器端把要发送的消息.目的iPhone的标识打包,发给APNS. 第二阶段:APNS在自身的已注册Push服务的iPhone列表中,查找有相

手把手教你做iOS推送

最近在研究iOS的推送问题,遇到了一些问题,最终整理了一下,放在这里和大家分享. APNS的推送机制 首先我们看一下苹果官方给出的对iOS推送机制的解释.如下图 Provider就是我们自己程序的后台服务器,APNS是Apple Push Notification Service的缩写,也就是苹果的推送服务器. 上图可以分为三个阶段: 第一阶段:应用程序的服务器端把要发送的消息.目的iPhone的标识打包,发给APNS. 第二阶段:APNS在自身的已注册Push服务的iPhone列表中,查找有相

iOS推送小结--swift语言

APNS的推送机制 首先我们看一下苹果官方给出的对ios推送机制的解释.如下图 Provider就是我们自己程序的后台服务器,APNS是Apple Push Notification Service的缩写,也就是苹果的推送服务器. iPhone当然就是我们的iOS设备了,CllentApp就是我们的客户端程序 第一阶段:应用程序的服务器端把要发送的消息.目的iPhone的标识打包,发给APNS. 第二阶段:APNS在自身的已注册Push服务的iPhone列表中,查找有相应标识的iPhone,并把

一步一步教你做ios推送

最近在研究ios的推送问题,遇到了一些问题,最终整理了一下.放在这里和大家分享 APNS的推送机制 首先我们看一下苹果官方给出的对ios推送机制的解释.如下图 Provider就是我们自己程序的后台服务器,APNS是Apple Push Notification Service的缩写,也就是苹果的推送服务器. 上图可以分为三个阶段: 第一阶段:应用程序的服务器端把要发送的消息.目的iPhone的标识打包,发给APNS. 第二阶段:APNS在自身的已注册Push服务的iPhone列表中,查找有相应

[转]手把手教你做iOS推送

最近在研究iOS的推送问题,遇到了一些问题,最终整理了一下,放在这里和大家分享. APNS的推送机制 首先我们看一下苹果官方给出的对iOS推送机制的解释.如下图 Provider就是我们自己程序的后台服务器,APNS是Apple Push Notification Service的缩写,也就是苹果的推送服务器. 上图可以分为三个阶段: 第一阶段:应用程序的服务器端把要发送的消息.目的iPhone的标识打包,发给APNS. 第二阶段:APNS在自身的已注册Push服务的iPhone列表中,查找有相

Android与iOS系统的消息推送机制

相信大家在使用iPhone版微信的时候都会有这样的经历,微信已经处于关闭状态了(后台进程运行一段时间就被系统杀掉),这时候我们收到了一个消息提醒,打开微信应用,微信显示“连接中…”和“收取中…”,然后再次显示一次刚才系统推送给我的消息通知.对这个现象比较好奇,于是去知乎上查一下资料,发现知乎上的热心人还真多,看了大家的回答之后,总结如下: [之所以去知乎查看技术问题,因为我并非技术人员,而知乎上很多开发人员是会用通俗易懂的方式解释好技术问题的,因为里面有不少大牛.] 先介绍一下两个重要的消息推送

iOS的推送机制APNs:本地推送&amp;远程推送

本地推送: 本地推送主要应用在备忘录,闹钟等本地的,基于时间定时的消息提醒.本篇不做详细描述. 远程推送:APNS(苹果推送通知服务) iOS远程推送机制的原理及流程: 注册推送(橙色部分):若该App允许接收推送消息,则先要在代码中注册远程推送.注册推送后,iOS带着设备序列号去请求ANPS而获得deviceToken.然后App把deviceToken发送给我们App的服务器.因为若服务器有消息给我们推送时,它会把要发送的消息和deviceToken按照一定的格式一并打包发送给ANPS服务器

iOS推送&amp;PHP后台

iOS远程推送,PHP最后台服务器进行推送. 推送机制: 1,PHP后台把要发送的消息.目的iPhone的标识打包,发给APNS(apple 推送服务器). 2,APNS在自身的已注册Push服务的iPhone列表中,查找有相应标识的iPhone,并把消息发到iPhone. 3,iPhone把发来的消息传递给相应的应用程序, 程序收到通知. 流程: 1,首先创建一个对应的APPID (Registering an App ID),这个和自己项目的Bundle Identifier要相符,不然推送

IOS推送功能push

笔记:ios推送功能 推送可实时提醒用户你想要让客户端用户知道的信息,那怕用户并没有开启这个应用.应用场景很广泛,如淘宝应用:在你使用淘宝客户端的时候,假如你拍的东西发货了,如果没有推送功能,你不会及时知道你拍下的东西已经发货.但使用了推送后,淘宝就会发送一条推送通知,告知使用客户端App的你,你拍下的东西已经发货.使用推送的场景很多,在用户的体验度上更人性. 苹果的推送机制(APNS)咯(ps:其实每一篇教程都有),先来看一张苹果官方对其推送做出解释的概要图. Provider是给你手机应用发

ios推送消息的基本原理

Push的原理: Push 的工作机制可以简单的概括为下图 图中,Provider是指某个iPhone软件的Push服务器,这篇文章我将使用.net作为Provider. APNS 是Apple Push Notification Service(Apple Push服务器)的缩写,是苹果的服务器. 上图可以分为三个阶段. 第一阶段:.net应用程序把要发送的消息.目的iPhone的标识打包,发给APNS. 第二阶段:APNS在自身的已注册Push服务的iPhone列表中,查找有相应标识的iPh