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,则用于监听任何对象发出的通知。 |
|
示例说明 |
ViewController.m
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// 监听UIApplicatiob的 UIApplicationDidFinishLaunchingNotification通知
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(launch:)
name:UIApplicationDidFinishLaunchingNotification
object:[UIApplication sharedApplication]];
// 监听UIApplicatiob的 UIApplicationDidEnterBackgroundNotification通知
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(back:)
name:UIApplicationDidEnterBackgroundNotification
object:[UIApplication sharedApplication]];
// 监听UIApplicatiob的 UIApplicationWillEnterForegroundNotification通知
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(fore:)
name:UIApplicationWillEnterForegroundNotification
object:[UIApplication sharedApplication]];
}
- (void)back: (NSNotification*)Notification
{
self.showLabel.text = [NSString stringWithFormat:@”应用程序加载完成!”];
}
- (void)launch: (NSNotification*)Notification
{
self.showLabel.text = [NSString stringWithFormat:@”%@\n应用程序进入后台!”,
self.showLabel.text];
}
- (void) fore: (NSNotification*)Notification
{
self.showLabel.text = [NSString stringWithFormat:@”%@\n应用程序进入前台!”,
self.showLabel.text];
}
@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 = ;
// 使用视图控制器监听任何对象发出的 PROGRESS_CHANGED 通知
[nc addObserver:self selector:@selector(update:)
name: PROGRESS_CHANGED object:nil]; // ①
}
- (IBAction)start: (id)sender
{
__block int progStatus = ;
[sender setEnabled:NO];
// 以传入的代码块作为执行体,创建NSOperation
NSBlockOperation* operation = [NSBlockOperation
blockOperationWithBlock:^{
for(int I = ; i < ; 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( == 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应用中发送本地通知的步骤很简单,只要如下几步即可。
|
|
示例示范如何开发本地通知 |
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:@””])
{
// 取消调度该通知
[app cancelLocalNotification: noti]; // ②
}
}
}
}
}
}
|
|
上面程序中的第①段代码创建了一个UILocalNotification对象,并为该对象设置了相关属性,接下来在①号代码处调用了UIApplication的scheduleLocalNotification:方法来调度通知,这样该通知将会在指定事件触发,并按相应的周期重复执行。当用户把UISwitch控件切换到关闭状态时,②号代码将会取消调度该通知。 为了让程序处于前台运行时也能看到本地通知,还重写了应用程序委托类的application:didReceiveLocalNotification:方法。 |
AppDelegate.m @implementation AppDelegate |
|
上面程序中的第①②段代码控制当应用程序处于前台运行时,即使程序收到了本地通知,也依然会将应用程序图标上的红色徽标中数字设为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服务而言,完整的过程如下。
|
|
从上图可以看出,Push客户端应用需要3个组件。
Push服务端程序则需要如下两个组件
|
开发Push客户端应用
开发Push客户端应用需要到Apple网站注册一个App ID,而且该App ID不允许使用通配符。通过Apple网站注册App ID的步骤如下。
|
|
|
将证书签名请求文件保存到磁盘上,此处将该文件保存为“Push。cerSigningRequest”。
在上图所示页面中,可以看到在“iOS |
|
iOS-----推送机制(上)的更多相关文章
- CC03 iOS推送机制浅析
• ios推送机制 可以通俗的把APNS理解为iOS系统为每个app提供的长连接通道 苹果限制了每个app在后台存活的时间,最重要的目的是为了省电,其次优化内存这些.如果彻彻底底的将app杀死了,服务 ...
- iOS推送证书上传(转)
iOS 推送证书制作(JAVA/PHP) 在使用Java或者PHP制作iOS推送服务器的时候,需要自己从开发者网站上导出的aps_developer_identity证书和Apple Developm ...
- 一步一步教你做ios推送
最近在研究ios的推送问题,遇到了一些问题,最终整理了一下.放在这里和大家分享 APNS的推送机制 首先我们看一下苹果官方给出的对ios推送机制的解释.如下图 Provider就是我们自己程序的后台服 ...
- APNS的推送机制 3
APNS的推送机制 首先我们看一下苹果官方给出的对iOS推送机制的解释.如下图 Provider就是我们自己程序的后台服务器,APNS是Apple Push Notification Service的 ...
- iOS的推送机制APNs:本地推送&远程推送
本地推送: 本地推送主要应用在备忘录,闹钟等本地的,基于时间定时的消息提醒.本篇不做详细描述. 远程推送:APNS(苹果推送通知服务) iOS远程推送机制的原理及流程: 注册推送(橙色部分):若该Ap ...
- ios消息推送机制原理与实现
本文转载至 http://hi.baidu.com/yang_qi168/item/480304c542fd246489ad9e91 Push的原理: Push 的工作机制可以简单的概括为下图 图中, ...
- (转)iOS消息推送机制的实现
原:http://www.cnblogs.com/qq78292959/archive/2012/07/16/2593651.html iOS消息推送机制的实现 iOS消息推送的工作机制可以简单的用下 ...
- IOS 推送消息 php做推送服务端
IOS推送消息是许多IOS应用都具备的功能,最近也在研究这个功能,参考了很多资料终于搞定了,下面就把步骤拿出来分享下: iOS消息推送的工作机制可以简单的用下图来概括: Provider是指某个iPh ...
- iOS 推送全解析
本文旨在对 iOS 推送(以下简称 推送)进行一个完整的剖析,如果你之前对推送一无所知,那么在你认真地阅读了全文后必将变成一个推送老手,你将会对其中的各种细节和原理有充分的理解.以下是 pikacod ...
- IOS 推送原理
最近两天在研究ios的消息推送机制.研究这个东西,还是充满兴趣的. Push的原理: Push 的工作机制可以简单的概括为下图 图中,Provider是指某个iPhone软件的Push服务器,这篇文章 ...
随机推荐
- C++宏定义不受命名空间的约束
// xxx.h namespace A { #define xxx() xxxxx } // 在其他文件中,引入xxx.h文件,使用宏定义时,不需要加命名空间 // yyy.cpp #include ...
- JavaScript的知识基本介绍
ECMAScript js简单介绍(与java的区别) 1.语法(区分大小写,弱类型,分号可写可不写) 2.变量(只能使用var定义,要么不定义,如果在函数内部使用var定 ...
- SpringBoot开发案例之整合Kafka实现消息队列
前言 最近在做一款秒杀的案例,涉及到了同步锁.数据库锁.分布式锁.进程内队列以及分布式消息队列,这里对SpringBoot集成Kafka实现消息队列做一个简单的记录. Kafka简介 Kafka是由A ...
- Angular2,Springboot,Zuul,Shiro跨域CORS请求踩坑实录
前言:前后端分离,业务分离,网关路由等已经成为当下web application开发的流行趋势.前端以单页面路由为核心的框架为主体,可以单独部署在nodejs或nginx上.后端以springboot ...
- Linux 物理内存 buffer cache
Linux下如何查内存信息,如内存总量.已使用量.可使用量.经常使用Windows操作系统的朋友,已经习惯了如果空闲的内存较多,心里比较踏实.当使用Linux时,可能觉的Linux物理内存很快被用光( ...
- 第7章使用请求测试-测试API . Rspec: everyday-rspec实操。
测试应用与非人类用户的交互,涵盖外部 API 7.1request test vs feature test 对 RSpec 来说,这种专门针 对 API 的测试最好放在 spec/requests ...
- 『TensotFlow』RNN/LSTM古诗生成
往期RNN相关工程实践文章 『TensotFlow』基础RNN网络分类问题 『TensotFlow』RNN中文文本_上 『TensotFlow』基础RNN网络回归问题 『TensotFlow』RNN中 ...
- csp 通信网络
http://blog.csdn.net/zyy_1998/article/details/78334496 试题编号: 201709-4 试题名称: 通信网络 时间限制: 1.0s 内存限制: 25 ...
- httpclient妙用一 httpclient作为客户端调用soap webservice(转)
前面有一篇使用HttpClient调用带参数的post接口方法,这里找到一篇使用HttpClient调用Soap协议接口的方式. 原文地址:httpclient妙用一 httpclient作为客户端调 ...
- ps -ef |grep xxx 输出的具体含义
ps:将某个进程显示出来 -A 显示所有程序. -e 此参数的效果和指定"A"参数相同. -f 显示UID,PPIP,C与STIME栏位. grep命令是查找 中间的|是管道命令 ...





