iOS_APNS(苹果远程推送)

感谢Hello杰少的文章,我在此基础上进行丰富

1/11. 获取CSR文件
为了便于文件管理,所有文件都放在AppPush文件夹中。命令行中的命令也在改文件夹下。
本次操作基于开发模式下,生产模式下类同,相关文件改为在Distribution下创建即可。

2/11. 进入MemberCenter,选择创建 AppID。填写App ID Description,然后选择Explicit App ID(推送不能使用模糊匹配的id)填写你所要开发的app的准确Bundle ID。 同时要在App Services中勾选Push Notifications,然后continue,然后register。

应用描述与Bundle ID
勾选Push

3/11. 接下来配置推送证书。可以在appID中配置,也可以在Certificates配置,但在appID中更便捷。 选择刚刚创建的appID,然后可以看到Push Notifications处于可设置状态,选择Edit。


Push Notifications处于可设置状态

4/11. 接下来在push notifications下选择创建证书,此时其实也就是跳转到了Certificates中来配置。


crecer.png

5/11. 接下来continue,然后在提示要csr文件时提交刚开始创建的csr文件,然后生成证书,下载下来后保存文件名为aps_push.cer,然后双击证书自动安装到钥匙串中。

6/11 接着还需要mobileprovision文件。选择创建profile,然后选择iOS App Development,点击continue。选择上面创建的AppID,选择开发者账号,选择测试设备,然后一路continue,最后输入profile文件名,这里设为pushTest。然后Generate,再下载下来双击即可自动安装到xcode中。

7/11. 在钥匙串中找到刚刚安装的aps_push.cer证书,右键选择导出,然后这里最好把存储文件名修改为英文,然后选择存储。接着要求设置证书密码,这里设置为abc123,然后还要输入管理员密码。搞定这些,所需要的p12文件就OK了。


exportCer.png
savep12.png

8/11. 在接下来还要对证书进行整合处理,在终端中进入AppPush文件夹,
然后执行命令openssl x509 -in aps_push.cer -inform der -out PushCert.pem 获得一个PushCert.pem文件
接着再执行命令openssl pkcs12 -nocerts -in pushTest.p12 -out PushKey.pem,这时需要输入p12文件的密码,就是上边设置的abc123,然后还要设置PushKey.pem文件的密码,依然设为abc123. 最后获的一个PushKey.pem文件
然后还有最后一击,执行命令cat PushCert.pem PushKey.pem > ck.pem 获取最终服务器要用的ck.pem文件

9/11. 经过以上的步骤,所需要的文件都准备好了,但是为了确保完事具备,还要进行简单的测试。
执行命令telnet gateway.sandbox.push.apple.com 2195,检测是否可以访问apple的推送服务器.显示如下则表明是OK的。(中间需要使用control+c来中断连接)

测试网络

执行命令openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert PushCert.pem -key PushKey.pem 测试上面生成的证书是否OK。内容很多,但只用关心最后是否如图所示,是则表示证书是OK的。这里也要输入密码及用control+c中断连接

测试证书是否OK

10/11. 经过上面的繁琐步骤终于准备好素材了。。。。。。开始实际代码开发吧。 新建工程,保证工程的Bundle ID和上边请求证书时使用的Bundle ID一致即可。然后代码的战场在AppDelegate.m中,不涉及其他地方。运行一次程序,从log信息中获取到deviceToken值(注意:如果上面没有安装profile文件,那么也会获取到一个deviceToken值,但是这个值是没卵用的)。

//
//  AppDelegate.m
//  apnsTest
//
//  Created by yuweiMac on 16/4/28.
//  Copyright © 2016年 yuweiMac. All rights reserved.
//

#import "AppDelegate.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    
    //    调用该方法有3种路径:点击appIcon或者点击通知进入或者第三方应用跳转。
    //    如果点击appIcon进入时launchOptions为nil。其他则 !nil,但两者的key同
    if (launchOptions == nil) {
        [self showAlertWithTitle:@"由AppIcon启动" msg:[launchOptions description]];
    }else{
        if ([[launchOptions allKeys] containsObject:@"UIApplicationLaunchOptionsURLKey"]) {
            [self showAlertWithTitle:@"由第三方应用启动" msg:[launchOptions description]];
            
        } else {
            
            [self showAlertWithTitle:@"点击通知启动" msg:[launchOptions description]];
        }
    }
    
    //    注册推送权限.iOS8之前的注册方式不一样,但现在最低兼容ios8,忘了7吧
    //    if ([application respondsToSelector:@selector(isRegisteredForRemoteNotifications)])
    //    {
    //IOS8
    //创建UIUserNotificationSettings,并设置消息的显示类类型
    //    可以通过判断是否已经注册远程通知来决定是否要进行注册操作,这里不这么做。
    //    if (![application isRegisteredForRemoteNotifications]) {
    
    //        注册通知权限
    UIUserNotificationSettings *notiSettings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert) categories:nil];
    
    [application registerUserNotificationSettings:notiSettings];
    //        注册远程通知
    [application registerForRemoteNotifications];
    //    }
    
    //    } else{ // ios7
    //        [application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge                                       |UIRemoteNotificationTypeSound                                      |UIRemoteNotificationTypeAlert)];
    //    }
    
    return YES;
}


-(void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings{
    //    成功注册消息通知权限
    NSLog(@"成功注册消息通知");
}



-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
    //    成功注册远程推送并获得deviceToken信息
    NSLog(@"didRegisterForRemote---deviceToken-->%@", deviceToken);
}

-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
    //    注册远程推送失败
    NSLog(@"FailToRegisterForRemoteN---fail-->%@",error);
}

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
    
    //    当应用在前台时接收到远程推送消息
    [self showAlertWithTitle:@"收到远程推送消息" msg:[userInfo description]];
}

//当从第三方应用跳转到本应用时会调用该方法
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
    
    NSLog(@"-->%@   -->%@",url,sourceApplication);
    
    return YES;
}

//弹出信息警告框
-(void)showAlertWithTitle:(NSString*)title msg:(NSString*)msg{
    
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:msg  delegate:nil cancelButtonTitle:nil otherButtonTitles:@"确定",nil];
    [alert show];
}

@end

11//11.接下来要写一个AppPush.php文件,来向apns服务器发送内容。
需要注意的几个地方:deviceToken填写你接收到的token;passPhrase则填写你的ck.pem设置的密码。当然如果你在上边保存文件时命名不是ck,那还需要替换程序内的文件名称$pemFile。 最后再在终端中执行命令php AppPush.php,然后一切都应该很美好的OK了。


<?php

// ??????????deviceToken???????????????
$deviceToken = '493c0d7eaa19a529a4422cd9ee779fc474f95b9915051118887fed7e1b0af85f';

// Put your private key's passphrase here:
$passphrase = 'abc123';

$pemFile = 'ck.pem';

// Put your alert message here:
$message = 'My first push test!';

////////////////////////////////////////////////////////////////////////////////

$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', $pemFile);
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);

// Open a connection to the APNS server
$fp = stream_socket_client(
'ssl://gateway.sandbox.push.apple.com:2195', $err,
$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);

if (!$fp)
exit("Failed to connect: $err $errstr" . PHP_EOL);

echo 'Connected to APNS' . PHP_EOL;

// Create the payload body
$body['aps'] = array(
'alert' => $message,
'sound' => 'default'
);

// Encode the payload as JSON
$payload = json_encode($body);

// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;

// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));

if (!$result)
echo 'Message not delivered' . PHP_EOL;
else
echo 'Message successfully delivered' . PHP_EOL;

// Close the connection to the server
fclose($fp);
?>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容