1. 程式人生 > >python3 三行程式碼基於HTTP2完美實現APNS推送【詳解】

python3 三行程式碼基於HTTP2完美實現APNS推送【詳解】

    第一次做蘋果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 = '/3/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)