python3 三行代码基于HTTP2完美实现APNS推送【详解】
以诗为茗 人气:1第一次做苹果APNS(Apple Push Notification service)推送,关于APNS推送原理以及证书的获取方式网上已经有许多资料,在此不做过多赘述,需要注意的是证书分为测试证书和正式证书两种,建议直接用通用版的正式证书
大家可以参考网上的这篇博客:点击这里查看
从苹果下载到的证书是.cer格式的,若要完成推送,需要转换为.pem格式,python已自带openssl,此步骤需要输入之前设置的密码:
openssl pkcs12 -in Development.p12 -out developent.pem
要进行python推送,自然少不了安装相应的python包:
pip install applepush
至此便可尝试推送:
from applepush import ApplePush apns =ApplePush('证书文件名称','bundle ID') resp =apns.single_push('苹果设备token',"推送内容")
如果成功实现推送,那恭喜你没有踩到坑,如果推送失败,请参考以下解决方案:
1.如果是测试环境,请确认是否是 测试环境下的DeviceToken+测试证书/通用的正式证书+测试服务器
如果是从App Store下载的正式环境,请确认是否是 正式环境下的DeviceToken+通用的正式证书+正式服务器
关于正式服务器与测试服务器地址,可参照官网进行对比:点此查看
2.如果是正式环境,会回复BadDeviceTocken,需要在下载的python包中做修改:
打开安装目录下Anacoda3\Lib\site-packages\applepush\core.py文件,将url地址改为以下,正式的服务器地址:
def __init__(self, cert, apns_topic): self.cert = cert self.headers = {"apns-topic": apns_topic} self.api_url = 'api.push.apple.com:443' self.api_path = '/3https://img.qb5200.com/download-x/device/%s'
-
Development server:
api.development.push.apple.com:443
-
Production server:
api.push.apple.com:443
也可自行添加推送参数或修改代码使其兼容正式服务器与测试服务器:
def single_push(self, token,alert,content,badge=1): """ 发送单个设备 :param token:设备 :param alert:弹出的消息 :param badge:红点数字 :return: """ token = self.handle_token(token) payload = { "aps":{ "alert":{ "title":alert, # iOS7、8设置无效,iOS9一般设置为appName #"subtitle":EXCEPTIONTYPES, # 一般使用title就能满足需求 "body":content }, "badge":1, #角标数 "sound":"default", #声音 "userinfo":{ #通知内容信息 "playid":"123", "username":"tom", "sex":1 } } } self.api_url1 = 'api.development.push.apple.com:443' conn = HTTPConnection(self.api_url, ssl_context=tls.init_context(cert=self.cert)) conn.request('POST', self.get_api_path(token), body=json.dumps(payload), headers=self.headers) resp = conn.get_response() if resp.status==200: return self.make_response(resp) else: conn = HTTPConnection(self.api_url1, ssl_context=tls.init_context(cert=self.cert)) conn.request('POST', self.get_api_path(token), body=json.dumps(payload), headers=self.headers) resp = conn.get_response() return self.make_response(resp)
加载全部内容