IOS菜鸟初学第九篇:实现远程推送通知(证书创建,证书使用,ios代码,php后台发送推送)

首先说一点,我这里只是简单实现整个推送过程,还暂未对推送后的通知做处理,比如3Dtouch触发的快捷操作,如果你需要看这方面的资料,这里推荐几个参考

1.https://www.jianshu.com/p/81c6bd16c7ac

2.http://www.cocoachina.com/ios/20180719/24235.html

 

好了,整个实现流程就不多说了,简单总结一下

1.苹果开发者后台创建推送证书(建议开发环境和正式环境的证书都创建好)

2.创建好证书后,到xcode中配置,并在AppDelegate中注册设备token,发送给后台,以及处理通知

3.php使用证书,跟Apns建立连接,发送推送消息

 

就上面的3步操作,但是有繁琐的步骤,还有一些细节要注意。

由于步骤过于繁琐,某些步骤就不一一贴上来了,这里安利一下我参考的这几位大佬的教程,亲测是能成功的,只是可能会遇到些坑,我会总结一下,供大家参考。

1.证书创建和xcode配置:https://www.jianshu.com/p/adfce0921c09

2..p12证书合成.pem证书,以及php后台代码:https://www.jianshu.com/p/38d9fed94ee0

3. AppDelegate完整代码:https://www.jianshu.com/p/c58f8322a278

 

总结:

1.证书必须创建正确。自己写后台的发送程序,需要用到.pem文件。而第三方的推送服务器需要的是p12文件

2.xcode要在打开相应的开关

IOS菜鸟初学第九篇:实现远程推送通知(证书创建,证书使用,ios代码,php后台发送推送)_第1张图片

3.你测试获取的deviceToken是需要你自己写代码发给你后台的。当然自己测试的话,只需要直接复制就好了。

4.当你原生app已经能够获取deviceToken,你已经成功一半了,只需要在后端测试能否收到推送通知就好了。我用的是PHP,网上大部分是16年的教程,但是还是管用,下面附上我的PHP后段代码,亲测能成功,注意要在命令终端运行php并不可以直接运行,也可以写一个方法另一php调用这个方法,此时能够在浏览器中成功运行。

"劲爆活动来袭" , "body" =>'邀请好友,即可获得邀请大奖。累计奖金第一名还可获得额外实物奖励,速来吧');
            //app右上角显示的数字
		$badge = 1;
		//推送消息到手机时的提示音
		$sound = 'default';
		//建设的通知有效载荷(即通知包含的一些信息)
		$body = array();
		$body['aps'] = array('alert' => $message,'badge'=>$badge,'sound'=>$sound);
        //自定义参数
		$body['userInfo'] = array('type' => '2');
		//把数组数据转换为json数据
		$payload = json_encode($notification);
		echo strlen($payload);
		//这里可批量发送deviceToken,将多个deviceToken放在数组中循环即可
		$devicetoken =['8e2ac24b85b32f14bd5af82ebb80edebd0671195abb876b00044ad08ad3391c4'];
		$i = 1;
		
		//推送开始
		foreach ($devicetoken as $v){
			print_r('开始推送' .'
'); $msg = chr(0) . pack("n",32) . pack('H*', str_replace(' ', '', $v)) . pack("n",strlen($payload)) . $payload; if( !fwrite($fp, $msg) || checkAppleErrorResponse($fp) ){ //如果失败,则进行重发,连续3次还是失败,则重新建立连接,并对下一个devicetoken进行推送 $times = 1; while($times <= 3){ if(!fwrite($fp, $msg) || checkAppleErrorResponse($fp)){ $times ++ ; }else{ $fp = create_apns_link(); break; } } } print_r('已推送' . $v .'的通知
'); //每隔100次重新和APNS服务器建立连接. if( $i%100 == 0 ){ $fp = create_apns_link(); } $i++; } usleep(500000); if(checkAppleErrorResponse($fp)){ print_r('推送失败
'); }else{ print_r('推送完成
'); } fclose($fp); function create_apns_link(){ $passphrase = '123456'; //这是合成的.pem证书,跟php文件放在同一个文件夹 $filename = dirname(__FILE__) .'/'.'apns_production.pem'; //测试环境下的apns服务器,用tls连接方式 $link = 'tls://gateway.push.apple.com:2195'; //正式环境下的apns服务器 //$link = 'tls://gateway.sandbox.push.apple.com:2195'; $scc = stream_context_create(); //这里并不需要改为tls,保持ssl就好了 stream_context_set_option($scc, 'ssl', 'local_cert', $filename); stream_context_set_option($scc, 'ssl', 'passphrase', $passphrase); $fp = stream_socket_client($link, $err,$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $scc); $i = 0; while (gettype($fp) != 'resource'){ print_r('重连Apns'.'
'); if($i < 3){ usleep(500000); $fp = stream_socket_client($link, $err,$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $scc); }else{ break; } } stream_set_blocking ($fp, 0); if($fp){ echo '成功连接到Apns,等待推送' . '
'; } return $fp; } function checkAppleErrorResponse($fp) { //byte1=always 8, byte2=StatusCode, bytes3,4,5,6=identifier(rowID). // Should return nothing if OK. //NOTE: Make sure you set stream_set_blocking($fp, 0) or else fread will pause your script and wait // forever when there is no response to be sent. $apple_error_response = fread($fp, 6); if ($apple_error_response) { // unpack the error response (first byte 'command" should always be 8) $error_response = unpack('Ccommand/Cstatus_code/Nidentifier', $apple_error_response); if ($error_response['status_code'] == '0') { $error_response['status_code'] = '0-没遇到任何错误'; } else if ($error_response['status_code'] == '1') { $error_response['status_code'] = '1-处理错误'; } else if ($error_response['status_code'] == '2') { $error_response['status_code'] = '2-缺少设备token'; } else if ($error_response['status_code'] == '3') { $error_response['status_code'] = '3-缺少主题'; } else if ($error_response['status_code'] == '4') { $error_response['status_code'] = '4-缺少荷载'; } else if ($error_response['status_code'] == '5') { $error_response['status_code'] = '5-无效的设备token'; } else if ($error_response['status_code'] == '6') { $error_response['status_code'] = '6-无效的主题size'; } else if ($error_response['status_code'] == '7') { $error_response['status_code'] = '7-无效的荷载size'; } else if ($error_response['status_code'] == '8') { $error_response['status_code'] = '8-无效的token'; } else if ($error_response['status_code'] == '255') { $error_response['status_code'] = '255-未知错误'; } else { $error_response['status_code'] = $error_response['status_code'].'-错误不在错误列表内'; } echo '
+ + + + + + 错误 返回命令:' . $error_response['command'] . ' 识别码:' . $error_response['identifier'] . ' 状态码:' . $error_response['status_code'] . '
'; echo '标识符是导致问题的数据库中的rowID(索引),Apple将断开您与服务器的连接。 要继续发送推送通知,只需从此标识符后面的下一个rowID开始。
'; return true; } return false; } ?>

5.测试正式环境的推送

首先将php的测试发送通知的apns服务器和证书换成正式环境的。

然后最重要的是获取正式环境下的deviceToken。这里有两个解决方案,第一种就是代码里写好将获取到的deviceToken发送到服务器的数据库,存起来。然后在appstore上线了,在进行测试。这个时间成本太高了。第二种就是生成ipa文件,直接安装在手机上,将deviceToken存在本地文件,然后去找这个文件,读取deviceToken信息。

我这里详细说一下第二种方案:参考教程:https://www.jianshu.com/p/76e23be72b3b

1.首先修改代码,在获取deviceToken的地方把deviceToken存在本地文件。代码如下:

打个广告:我写的另一篇文章,收集了一些ios常用开发技巧:传送门

NSArray *pathArr=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *strPath=[pathArr lastObject];
NSString *strFinalPath=[NSString stringWithFormat:@"%@/myfile.txt",strPath];
[deviceToken writeToFile:strFinalPath atomically:YES encoding:NSUTF8StringEncoding error:nil];

 

2.打包生成ipa文件,首先要在apple的developer后台创建这个应用的ad hoc证书,可参考上面的教程

生成之后,打包生成ipa操作如下:

xcode->product->archive,打开窗口后distribute app,选择ad hoc

    然后next->next->

IOS菜鸟初学第九篇:实现远程推送通知(证书创建,证书使用,ios代码,php后台发送推送)_第2张图片

这里要注意hoc是我在apple的developer中创建的那个ad hoc证书。这里要用的。然后next->

IOS菜鸟初学第九篇:实现远程推送通知(证书创建,证书使用,ios代码,php后台发送推送)_第3张图片

export导出,就会在导出的地方有个文件夹,里面就有.ipa文件,如下:

IOS菜鸟初学第九篇:实现远程推送通知(证书创建,证书使用,ios代码,php后台发送推送)_第4张图片

 

3.真机安装ipa文件。xcode要链接好手机,然后打开设备窗口,操作如下:xcode->windows->devices and simulators,这样就会打开如下窗口:

IOS菜鸟初学第九篇:实现远程推送通知(证书创建,证书使用,ios代码,php后台发送推送)_第5张图片

点击+号,选择刚刚导出的ipa文件,就会自动安装好了,如下图

IOS菜鸟初学第九篇:实现远程推送通知(证书创建,证书使用,ios代码,php后台发送推送)_第6张图片

安装好之后,你就正常的使用你的app,你一打开app,他应该就会存下deviceToken了,然后你就会到上图这个窗口,选中这个app,+号旁边的设置icon就会亮起,点击选择download选项:

IOS菜鸟初学第九篇:实现远程推送通知(证书创建,证书使用,ios代码,php后台发送推送)_第7张图片

download之后就会在你download到的那个文件夹中出现一个app data文件:

IOS菜鸟初学第九篇:实现远程推送通知(证书创建,证书使用,ios代码,php后台发送推送)_第8张图片

右键->显示包内容。就能打开里面的文件目录,在document文件夹下应该有个txt文件,打开里面就是正式环境下的deviceToken,如下图:

IOS菜鸟初学第九篇:实现远程推送通知(证书创建,证书使用,ios代码,php后台发送推送)_第9张图片

5. 这时候你就可以拿着这个deviceToken去php后台发送测试了。之前我分享的那个教程中的smartpush那个测试插件挺好用的,也能用来测试,xcode打开就能跑起来,非常方便。

 

你可能感兴趣的:(IOS)