您的位置:首页 > 移动开发 > IOS开发

ios 远程推送和本地推送

2014-04-19 13:36 471 查看

[转载]IOS开发之----远程推送通知




(2013-02-01
15:56:06)


转载▼

标签:

转载

原文地址:IOS开发之----远程推送通知作者:倒計時

玩了一年的iPhone了各种App的远程通知接收了不少,每次接收到的时候,就在反思,这丫的怎么实现的!

由于工作方面一直没有接触的机会,所以只好自己主动去做做练习试试了.

实践后发现,一系列的配置非常繁琐,当然咯,网上的教程已经一大堆了.

在这里还是写一篇文章来记录一些自己容易忘记的细节,以备日后所需时能够有用武之地.

依照自己的习惯,喜欢把参考过的教程列举出来,真的很感谢这些网上的牛人.

1: ios本地通知和远程通知

http://wangjun.easymorse.com/?p=1482

2: 苹果远程通知服务申请激活例图 (外国佬写的.)

http://mobiforge.com/developing/story/programming-apple-push-notification-services

3:书籍参考:iPhone 开发秘籍 第16章 推送通知.

好了,进入正文:

首先是申请证书的网址

https://developer.apple.com/ios/manage/overview/index.action

登录成功以后,进入iOS 配置管理的 主页面.





第一步操作是去创建一个新的AppIDs创建成功后,会需要提供安全证书来激动推送服务,如下图:













选择存储到磁盘以后,生成一个文件名称为(简称CSR): CertificateSigningRequest.certSigningRequest

回到Apple页面 将这个提交并提示激动成功.

激活成功后的App IDs 提供下载开发版或是发布版的主动推送证书(aps_development.cer),如果需要做服务器方面的主动推送的话,就必须要下载这个文件来使用推送服务了.

第二步要为App提供接受推送许可的证书,点击Provisioning进行设置,添加一个新的许可,选择刚刚新创建的AppIDs. 再选择可以调试的iPhone 设备.

最后,同样是下载下来: YsyPushMessageDemo.mobileprovision双击该证书,让其加载一次.

接下来,进入iOS工程,选择使用该证书来调试.





红圈中,全部设置刚刚加载的许可证书.

那么到这里,关于证书类的准备工作,已经全部准备就绪.

在这里再此强调一次,每个文件的具体作用

1: CertificateSigningRequest.certSigningRequest :为生成App IDs 而用

2: aps_development.cer 为开发主动推送服务而用到的证书

3: YsyPushMessageDemo.mobileprovision 为App接受推送通知的许可服务

主动推送的Push 代码及使用,请参考一开始介绍的第一篇博客

这里只附上下载地址: https://github.com/stefanhafeneger/PushMeBaby

接下来,说说收到推送通知代码方面.

1:申请本App需要接受来自服务商提供推送消息,

[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];

2:申请发出后,如果成功,委托会自动返回一个设备令牌(toKen),如果失败,将会进入另外一个失败的委托

//远程通知注册成功委托

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken

{

NSLog(@"%@",deviceToken);

self.viewController.toKenValueTextView.text = [NSString stringWithFormat:@"%@",deviceToken];

self.viewController.pushStatusLabel.text = @"已经注册.";

}

//远程通知注册失败委托

-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error

{

self.viewController.toKenValueTextView.text = [error description];

}

3:将设备令牌码提供给服务商,以供推送到具体的手机上面.如果远程推送消息来了,用户点击了推送消息,或者应用已经处于打开状态,系统都会自动调用以下委托:

//点击某条远程通知时调用的委托 如果界面处于打开状态,那么此委托会直接响应

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo

{

NSLog(@"远程通知");

[self PMD_uesPushMessage:userInfo];

}

4:第三点里面的介绍的情况是应用程序已经处于运行状态,上面的委托才会被执行,如果应用程序处于未启用状态,此时又需要响应消息,那么需要以下委托处理.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

//这里处理应用程序如果没有启动,但是是通过通知消息打开的,此时可以获取到消息.

if (launchOptions != nil) {

NSDictionary *userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];

[self PMD_uesPushMessage:userInfo];

}

return YES;

}

5:清空通知中心已有的推送消息,只需要将指定App 的 Badge 设置为 0即可

[[UIApplication sharedApplication ] setApplicationIconBadgeNumber:0];

6:主动推送的字符串必须符合如下Json数组的格式,才能正确推送到手机当中.

@"{

//自定义参数

"userinfo":

{

"name":"remotenotice"

},

//标准写法

"aps":

{

"alert":

{

"action-loc-key":"Open",//支持多语言

"body":"messgaecontent"//消息正文

},

"badge":1,//为App的icon 标记 具体数值

"sound":"default" //播放的音频文件,default表示系统默认的选择列铃声

}

}";

到这里就差不多结束了.

php服务器推送消息

<?php

$deviceToken = '38c866dd bb323b39 ffa73487 5e157ee5 a85e0b7ce90d56e9 fe145bcc 6c2c594b'; // masked for security reason

// Passphrase for the private key (ck.pem file)

// $pass = '';

// Get the parameters from http get or from command line

$message = $_GET['message'] or $message = $argv[1] or $message = 'Message received from javacom';

$badge = (int)$_GET['badge'] or $badge = (int)$argv[2];

$sound = $_GET['sound'] or $sound = $argv[3];

// Construct the notification payload

$body = array();

$body['aps'] = array('alert' => $message);

if ($badge)

$body['aps']['badge'] = $badge;

if ($sound)

$body['aps']['sound'] = $sound;

$ctx = stream_context_create();

stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');

// assume the private key passphase was removed.

// stream_context_set_option($ctx, 'ssl', 'passphrase', $pass);

$fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);

if (!$fp) {

print "Failed to connect $err $errstrn";

return;

}

else {

print "Connection OKn";

}

$payload = json_encode($body);

$msg = chr(0) . pack("n",32) . pack('H*', str_replace(' ', '', $deviceToken)) . pack("n",strlen($payload)) . $payload;

print "sending message :" . $payload . "n";

fwrite($fp, $msg);

fclose($fp);

?>

这个帖子写的也不错

http://blog.csdn.net/bl1988530/article/details/6729369

代码例子下载:

http://ishare.iask.sina.com.cn/f/33789601.html

=============================分割线==================================


第一步:创建本地推送

// 创建一个本地推送

UILocalNotification *notification = [[[UILocalNotification alloc] init] autorelease];

//设置10秒之后

NSDate *pushDate = [NSDate dateWithTimeIntervalSinceNow:10];

if (notification != nil) {

// 设置推送时间

notification.fireDate = pushDate;

// 设置时区

notification.timeZone = [NSTimeZone defaultTimeZone];

// 设置重复间隔

notification.repeatInterval = kCFCalendarUnitDay;

// 推送声音

notification.soundName = UILocalNotificationDefaultSoundName;

// 推送内容

notification.alertBody = @"推送内容";

//显示在icon上的红色圈中的数子

notification.applicationIconBadgeNumber = 1;

//设置userinfo 方便在之后需要撤销的时候使用

NSDictionary *info = [NSDictionary dictionaryWithObject:@"name"forKey:@"key"];

notification.userInfo = info;

//添加推送到UIApplication

UIApplication *app = [UIApplication sharedApplication];

[app scheduleLocalNotification:notification];

}

第二步:接收本地推送

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification*)notification{

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"iWeibo" message:notification.alertBody delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil];

[alert show];

// 图标上的数字减1

application.applicationIconBadgeNumber -= 1;

}

第三步:解除本地推送

// 获得 UIApplication

UIApplication *app = [UIApplication sharedApplication];

//获取本地推送数组

NSArray *localArray = [app scheduledLocalNotifications];

//声明本地通知对象

UILocalNotification *localNotification;

if (localArray) {

for (UILocalNotification *noti in localArray) {

NSDictionary *dict = noti.userInfo;

if (dict) {

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

if ([inKey isEqualToString:@"对应的key值"]) {

if (localNotification){

[localNotification release];

localNotification = nil;

}

localNotification = [noti retain];

break;

}

}

}

//判断是否找到已经存在的相同key的推送

if (!localNotification) {

//不存在初始化

localNotification = [[UILocalNotification alloc] init];

}

if (localNotification) {

//不推送 取消推送

[app cancelLocalNotification:localNotification];

[localNotification release];

return;

}

}

//为了保证程序每次启动不要重复的去添加本地推送 所以要遍历系统所有本地推送,如果已经注册了的推送就不要去再次添加了

UILocalNotification *localNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];

if (localNotification) {

UIAlertView *alertV = [[UIAlertView alloc] initWithTitle:@"提示" message:@"本地通知启动的程序!请做后续处理!" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:nil, nil];

[alertV show];

[alertV release];

}

//在程序入口处,用launchOptions来判断是不是本地通知来启动的程序,然后再做下一步处理。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: