你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS注冊APNs通知

iOS注冊APNs通知

編輯:IOS開發綜合

1、什麼是通知

消息通知分本地通知和遠程推送通知,是沒有運行在前台的應用程序可以讓它們的用戶獲得相關消息通知的方式。消息通知可能是一條消息,即將發生的日歷事件,或遠程服務器的新數據。當被操作系統顯示時,本地通知和推送通知看起來一樣。它們可以顯示一個警告信息或在應用程序的圖標上面顯示一個徽標。它們也可以在警告窗或徽標顯示時播放一段聲音。推送通知是在 iOS 3.0 和 Mac OS X v7.0 之後引入的。本地通知是在 iOS 4.0 之後引入的。它們都不支持 Mac OS X,當用戶被通知相應的應用程序有消息,事件,或其他數據時,他們可以啟動該應用程序並查看詳情。他們也可以選擇忽略通知,此時應用程序沒有被激活。

本地通知和推送通知為不同的需求而設計的。本地通知是本地 iPhone、iPad、或iPod touch 上面的應用發起的。相反推送通知(又稱遠程通知)是從其他設備上面到達的。它來自一個遠程設備——應用程序的提供者——並在有新的消息需要查看或新的數據需要下載的時候被推送到本地設備上面的應用,常見的本地通知像iphone的日歷,微信或者qq這些都是本地推送,比如還安裝了優酷,qq視頻這些軟件,允許推送後,每天會給你發些新的視頻消息,這些就是遠程推送。

 

2. 什麼是APNS?

 

蘋果推送通知服務(APNs)是推送通知的網關,iPhone ipad 對於應用程序在後台運行有諸多限制,考慮到手機電池電量,應用不允許在後台進行過多的操作。因此,當用戶切換到其他程序後,原先的程序無法保持運行狀態。對於那些需要保持持續連接狀態的應用程序(比如社區網絡應用),將不能收到實時的信息。推送是解決輪詢所造成的流量消耗和電量消耗的一個比較好的解決方案

為解決這一限制,蘋果推出了APNs(蘋果推送通知服務Apple Push Notification services)。APNs 允許設備與蘋果的推送通知服務器保持常連接狀態。當你想發送一個推送通知給某個用戶的iPhone上的應用程序時,你可以使用 APNs 發送一個推送消息給目標設備上已安裝的某個應用程序。

蘋果的推送服務APNs基本原理簡單來說就是蘋果利用自己專門的推送服務器(APNs)接收來自我們自己應用服務器的需要被推送的信息,然後推送到指定的iOS設備上,然後由設備通知到我們的應用程序,設備以通知或者聲音的形式通知用戶有新的消息。推送的前提是裝有我們應用的設備需要向APNs服務器注冊,注冊成功後APNs服務器會返給我們一個device_token,拿到這個token後我們將這個token發給我們自己的應用服務器,當有需要被推送的消息時,我們的應用服務器會將消息按指定的格式打包,然後結合設備的device_token一並發給APNs服務器,由於我們的應用和APNs維持一個基於TCP的長連接,APNs將新消息推送到我們設備上,然後在屏幕上顯示出新消息來。

順便說下安卓的推送,Android消息推送采用MQTT協議,服務器端采用mosquito+PhpMQTTClient,有興趣的同學可以看看

mosquito:http://mosquitto.org/

PhpMQTTClient :https://github.com/tokudu/PhpMQTTClient

 

3. 推送流程

 

3.1 獲取設備device_token階段

整個過程基本就這樣,下面我們看一下設備注冊APNs的流程圖:

\

上圖完成了如下步驟:

1.Device連接APNs服務器並攜帶設備序列號

2.連接成功,APNs經過打包和處理產生device_token並返回給注冊的Device

3.Device攜帶獲取的device_token向我們自己的應用服務器注冊

4.完成需要被推送的Device在APNs服務器和我們自己的應用服務器注冊

執行順序如下所示:

\

這裡要提到的一點是,我們的設備和APNS服務器之間的通訊是基於SSL協議的TCP流通訊,二者之間維持一個長連接,當從APNS服務器注冊成功後,一定要將device_token發送給我們的應用服務器,因為在推送過程中,首相是由我們的應用服務器(上圖中Provider)將需要推送的消息結合device_token按指定格式(後面會提到)打包然後發送給APNS服務器,然後由APNS服務器推送給我們的設備。

 

3.2 消息推送過程

好了,注冊設備的過程完成了,接下來就是如何推送了:

\

推送的過程經過如下步驟:

1.首先,安裝了具有推送功能的應用,我們的設備在有網絡的情況下會連接蘋果推送服務器,連接過程中,APNS會驗證device_token,連接成功後維持一個長連接;

2.Provider(我們自己的服務器)收到需要被推送的消息並結合被推送設備的device_token一起打包發送給APNS服務器;

3.APNS服務器將推送信息推送給指定device_token的設備;

4.設備收到推送消息後通知我們的應用程序並顯示和提示用戶(聲音、彈出框)

 

3.3 完整流程介紹

比較直觀的流程參照下圖:

\

 

\

 

  1. 應用啟用推送通知功能,需要用戶確認;
  2. 應用收到設備識別ID(device token),相當於接收推送通知的地址;
  3. 應用將設備識別ID發送到你開發的服務器;
  4. 當有推送通知的需要時,你就可以通過你開發的服務組件發送信息到蘋果的服務器上;
蘋果推送通知服務將信息推送到用戶的設備上。

上圖顯示了我們的應用服務器將消息推送到我們的App的完整路徑,其實真正完成推送的是APNS服務器,我們自己的應用服務器只是將需要推送的消息告訴蘋果服務器,至於如何維護消息隊列或如何保證消息能被推送到指定的設備上,這些都由蘋果APNS給我們做完了

 

4. Push機制類型

 

四種:徽章、提示框、聲音和橫幅,具體表現形式如下圖

\

Push機制的4個組件

Provider

APNS

iPhone設備

Client App

其中APNS(Apple Push Notification Service)是由蘋果提供的消息推送服務中心,所有的消息都經由這裡轉發給相應的設備

 

 

5. 正式開工

5.1 准備工作

你得有台ios設備,iphone,ipad

5.1.2 為推送通知獲取授權

為了給提供者這邊開發和配置推送通知,你必須從開發者中心(即蘋果官網 DevCenter)取得 SSL 授權證書。每個授權證書限制必須對應一個單獨的應用,由應用的Bundle ID 標識。而且該授權證書也被限制用於以下兩個環境之一,沙箱環境(用於開發和測試)和生產環境。這些環境都擁有它自己的 IP 地址,而且需要它們自己的授權證書。你必須同時獲得這些環境的的配置文件(即 Provisioning profiles)。

 

5.1.3 提供者和APNs之間通過二進制接口通信

二進制接口是異步的,而且它使用 TCP 方式通過 sock 連接把二進制內容的推送通知發送給 APNs。沙箱和生產環境都有自己獨立的接口,每個都有它自己的地址和端口。對於每個接口,你需要使用 TLS(或 SSL)和已經拿到的 SSL 授權證書來建立一條到 APNs 的安全通信通道。提供者把推送通知打包並通過該通道發送給 APNs。APNs 包含了一個反饋服務,它負責維護每個應用的傳遞通知失敗的設備列表(即APNs 當前無法把推送通知傳遞到這些設備上面的對應的應用)。提供者應該周期性的連接到反饋服務來查看推送失敗的設備以便它可以把之前失敗的通知重復發送過
去。

開發狀態服務器地址gateway.sandbox.push.apple.com 2195

產品狀態服務器地址gateway.push.apple.com2195

Development和Production兩個版本對應的apns device token是不同的,前者是develop的mobileprovision下獲取的。後者是production的mobileprovision獲取的。
Development和Production兩個版本可以共用一個App ID(不推薦。共用時每次調試前都要刪除設備上的app,重新打包生成。而且公用appid會經常抓狂,早上行,下午就不行了。所以不推薦),但是不能共用一個mobileprovision,所以要單獨生成Distribution的證書供production版本使用。
注:Distribution的版本是無法在設備上debug調試的!
Development和Production兩個版本的code sign是不同的,前者是iPhone Developer,後者是iPhone Distribution。注意不能搞錯。

無論是Development Push SSLCertificate還是Production Push SSL Certificate 都有過期時間的。Development Push SSL Certificate有效期大概四個月左右,而ProductionPush SSL Certificate的有效期是一年。需要注意在過期之前生成新的證書,以免影響使用。

 

5.2 證書生成

 

5.2.1 過程簡介

先概述下大致過程,然後下面會截圖給出詳細的步驟

在Mac上生成 Apple推送通知SSL許可證:
1.登錄到apple Developer Connection Portal並點擊 App IDs
2.創建一個不使用通配符的 App ID。通配符 ID 不能用於推送通知服務。例如,我們的iPhone程序ID像這樣:54im.com.PushChat
3.點擊App ID旁的“Configure”,然後按下按鈕生產推送通知許可證。根據“向導”指導的步驟生成一個簽名並上傳,最後下載生成的許可證。
4.通過雙擊.cer文件將你的 aps_developer_identity.cer 引入Keychain中。
5.在Mac上啟動 Keychain助手,然後在login keychain中選擇 Certificates分類。你將看到一個可擴展選項“Apple Development Push Servicescom.54im.PushChat”
6.擴展此選項然後右擊“Apple Development Push Services” > Export “Apple Development Push Services:com.54im.PushChat”。保存為 PushChat_cert.p12 文件。
7.擴展“Apple Development Push Services” 對“Private Key”做同樣操作,保存為 PushChat_key.p12 文件。
8.需要通過終端命令將這些文件轉換為PEM格式:
openssl pkcs12 -clcerts -nokeys -out cert.pem -in PushChat_cert.p12
9.轉換得到key的pem:
openssl pkcs12 -nocerts -out key.pem -in PushChat_key.p12
10.如果你想要移除密碼,要麼在導出/轉換時不要設定或者執行:
openssl rsa -in key.pem -out key.unencrypted.pem
11.最後,你需要將鍵和許可文件合成為apns-dev.pem文件,此文件在連接到APNS時需要使用:
cat apns-dev-cert.pem key.unencrypted.pem > ck.pem

5.2.2 配置詳解

 

1. 創建APPID

首先登陸我們的Apple Developer後台為將要使用推送服務的App新建一個App ID,如下圖,點擊新建後輸入基本信息

\

 

我把要改的地方截圖下來了,高手勿笑哦,屌絲第一次用mac,也是第一次進蘋果開發者後台。

\

APPID創建好後,我們點編輯剛剛生成好的APPID,生成下development證書,生產情況下用 Production證書

 

\

 

創建正式過程中,要求上傳一張Certificate Signing Request證書請求簽名文件

\

 

2. 生成證書請求文件

這個請求文件在自己的mac上生成

\

輸入證書信息

\

\

 

3. 生成PUSH證書

還記得剛剛蘋果開發者那裡要上傳的證書不,將生成好的這個.certSigningRequest證書上傳上去,

\

下載aps_development.cer這個證書到mac上,如果是發布版的推送證書,就為aps_production.cer。然後雙擊該證書,將推送證書安裝到我們的Mac機器上,安裝成功後會看到如下界面(如果是發布版,則證書的Development部分顯示的是Production)

\

 

需要為certificate和它之下的private key各自export出一個.p12文件。(會出現設置密碼過程)

4. 導出公鑰

\

導出私鑰

\

 

5. key轉換

需要將上面的2個.p12文件轉成.pem格式:

openssl pkcs12 -clcerts -nokeys -out cert.pem -in Push_Chat_cert.p12
openssl pkcs12 -nocerts -out key.pem -in Push_Chat_cert_key.p12

如果需要對key不進行加密
openssl rsa -in key.pem -out key.unencrypted.pem

然後就可以 合並兩個.pem文件, 這個ck.pem就是服務端需要的證書了
cat cert.pem key.unencrypted.pem> apns-dev.pem

創建 Provisioning Profile

 

5.3 創建 provisioning profile

 

接下來,需要創建 provisioning profile 以便允許應用程序安裝到真實設備上。

\

\

\

 

\

\

\

將該prifiles文件下載下來,名字是PushChat.mobileprovision,其實不用下載,xcode裡面會根據你的項目id自動去拉對於的這個文件。

在制作測試demo前我們先了解下開源的一個應用 easyapns,或者你也可以寫demo,主要就是收集DeviceToken

啥是Easy APNS

EasyAPNS 是一個用來管理蘋果推送通知的PHP腳本。如果你對蘋果推送通知後端部分比較感興趣,而恰巧你有熟悉PHP,那麼EasyAPNS是你工具箱中必須的工 具。EasyAPNS完全開源,並且設置非常簡單。通過使用免費的、開源的PHP腳本,EasyAPNS為開發者提供了一種很直觀的可以用來控制整個 推送通知後端部分的方式。

項目官網:http://www.easyapns.com/

github地址:https://github.com/manifestinteractive/easyapns

github裡面有這幾個目錄

delegate 將這裡面代碼添加到新建項目的 AppDelegate.m中

php 將文件放在一個可以訪問的web目錄下(要有php+mysql環境)

sql 將該目錄sql導入到數據庫

 

6. 客戶端制作

開始制作我們的客戶端

\

\

\

\

\

在代碼中加入以下代碼

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 #import "AppDelegate.h"@implementation AppDelegate/** * This is what you need to add to your applicationDidFinishLaunching */- (void)applicationDidFinishLaunching:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)]; // Clear application badge when app launches application.applicationIconBadgeNumber = 0;}- (void)applicationDidFinishLaunching:(UIApplication *)application{ // Add registration for remote notifications [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)]; // Clear application badge when app launches application.applicationIconBadgeNumber = 0;}/* * -------------------------------------------------------------------------------------------------------------- *BEGIN APNS CODE * -------------------------------------------------------------------------------------------------------------- *//** * Fetch and Format Device Token and Register Important Information to Remote Server */- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {#if !TARGET_IPHONE_SIMULATOR // Get Bundle Info for Remote Registration (handy if you have more than one app) NSString *appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"]; NSString *appVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]; // Check what Notifications the user has turned on.We registered for all three, but they may have manually disabled some or all of them. NSUInteger rntypes = [[UIApplication sharedApplication] enabledRemoteNotificationTypes]; // Set the defaults to disabled unless we find otherwise... NSString *pushBadge = (rntypes & UIRemoteNotificationTypeBadge) ? @"enabled" : @"disabled"; NSString *pushAlert = (rntypes & UIRemoteNotificationTypeAlert) ? @"enabled" : @"disabled"; NSString *pushSound = (rntypes & UIRemoteNotificationTypeSound) ? @"enabled" : @"disabled"; // Get the users Device Model, Display Name, Unique ID, Token & Version Number UIDevice *dev = [UIDevice currentDevice]; NSString *deviceName = dev.name; NSString *deviceModel = dev.model; NSString *deviceSystemVersion = dev.systemVersion; // Prepare the Device Token for Registration (remove spaces and < >) NSString *deviceToken = [[[[devToken description] stringByReplacingOccurrencesOfString:@"<"withString:@""]stringByReplacingOccurrencesOfString:@">" withString:@""] stringByReplacingOccurrencesOfString: @" " withString: @""]; // Build URL String for Registration // !!! CHANGE "www.mywebsite.com" TO YOUR WEBSITE. Leave out the http:// // !!! SAMPLE: "secure.awesomeapp.com" NSString *host = @"121.199.25.24/pushchat"; // !!! CHANGE "/apns.php?" TO THE PATH TO WHERE apns.php IS INSTALLED // !!! ( MUST START WITH / AND END WITH ? ). // !!! SAMPLE: "/path/to/apns.php?" NSString *urlString = [NSString stringWithFormat:@"/apns.php?task=%@&appname=%@&appversion=%@&devicetoken=%@&devicename=%@&devicemodel=%@&deviceversion=%@&pushbadge=%@&pushalert=%@&pushsound=%@", @"register", appName,appVersion, deviceToken, deviceName, deviceModel, deviceSystemVersion, pushBadge, pushAlert, pushSound]; // Register the Device Data // !!! CHANGE "http" TO "https" IF YOU ARE USING HTTPS PROTOCOL NSURL *url = [[NSURL alloc] initWithScheme:@"http" host:host path:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *urlR, NSData *returnData, NSError *e) { NSLog(@"Return Data: %@", returnData); }]; NSLog(@"Register URL: %@", url);#endif}/** * Failed to Register for Remote Notifications */- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {#if !TARGET_IPHONE_SIMULATOR NSLog(@"Error in registration. Error: %@", error);#endif}/** * Remote Notification Received while application was open. */- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {#if !TARGET_IPHONE_SIMULATOR NSLog(@"remote notification: %@",[userInfo description]); NSDictionary *apsInfo = [userInfo objectForKey:@"aps"]; NSString *alert = [apsInfo objectForKey:@"alert"]; NSLog(@"Received Push Alert: %@", alert); NSString *sound = [apsInfo objectForKey:@"sound"]; NSLog(@"Received Push Sound: %@", sound); //AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); NSString *badge = [apsInfo objectForKey:@"badge"]; NSLog(@"Received Push Badge: %@", badge); application.applicationIconBadgeNumber = [[apsInfo objectForKey:@"badge"] integerValue];#endif}/* * -------------------------------------------------------------------------------------------------------------- *END APNS CODE * -------------------------------------------------------------------------------------------------------------- */- (void)applicationWillResignActive:(UIApplication *)application{// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.}

並且修改裡面的push服務器地址

seover" id="crayon-5719d77a817dc857160450"> 1 NSString *host = @"api.54im.com/pushchat";

現在可以把項目編譯到iphone或者ipad上面了,注意項目 General中team配置。
\
\

\
然後插上自己的iphone或者ipad,就可以點build按鈕了,這時屏幕上會彈出一個警告框,是否允許消息推送,類似於

\

\

用戶同於消息推送後,也可以自行再關閉掉,也可以自行調整通知方式

\

 

7. php服務器端配置

 

數據庫導入

create database pushchat DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

mysql -h 127.0.0.1 -uroot -p –databse pushchat

修改apns.php 和samples.php配置文件

$db = new DbConnect(‘localhost’, ‘root’, ’54im.com’, ‘pushchat’);

然後單獨修改class目錄下class_APNS.php的證書和日志路徑

private $DEVELOPMENT = ‘sandbox’

private $logPath = ‘/usr/local/apns/apns.log

private $sandboxCertificate = ‘/usr/local/apns/ck.pem

當然你的證書也必須放到這個目錄下(就是之前合並的那個證書)

在手機上打開我們安裝的那個PushChat應用,然後數據庫中就有手機發送過來的

\

 

8. 測試

 

消息發送測試,在服務器上執行samples.php 就可以

php -f samples.php

\

備注:

服務器端,如果是php的,那必須使用.pem的證書,如果是java的,那必須使用.p12的證書。(很可能還需要雙擊證書進行安裝!)
服務器端發出的json包是有大小限制的,最大256字節,包括自定義字典集。
aps中的alert字符串裡是可以添加”\n”做換行的。
json包中除了alert,badge,sound之外,還是是可以自定值的。

額外的自定義值:
$payload[‘aps’] = array(‘alert’ => ‘This is the alert text’, ‘badge’ => 1, ‘sound’ => ‘default’);
$payload[‘server’] = array(‘serverId’ => $serverId, ‘name’ => $name);
$output = json_encode($payload);
當用戶按下“View”後,自定義server值將被傳遞到設備中的程序。JSON 值如下:
{
“aps” :
{ “alert” :
{
“action-loc-key” : “顯示” ,
“body” : “This is the alert text”
},
“badge” : 1,
“sound” : “default” },
“server” : { “serverId” : 1, “name” : “Server name”)
}
256字節的限制適用於整個payload,包括自定義字典集。

 

IOS7之前,蘋果對於一個設備上的多個APP,生成相同的DeviceToken。
IOS7以及之後,蘋果對於一個設備上的多個APP,生成不同的DeviceToken。
這種新改變導致APNS上創建了一張新老token的映射表,如果你一直用老的token,那沒問題,但是,一旦服務器使用新的DeviceToken,映射表中的記錄就會被刪除,這意味著,老的DeviceToken就不能用了,必然發送失敗。
待驗證:IOS5和IOS6,APP永遠可以獲取DeviceToken,除此之外的系統,如果用戶拒絕了,或者關閉了推送,那麼無法獲取DeviceToken,走失敗回調。

 

 

8. 附錄:

8.1 JSON示例

以下通知負載的示例舉例說明了表 3-1 所列舉的屬性。名為”acme”的屬性是一個
自定義負載數據的例子。該示例包含了可讀性的空白符和換行符。為了提高性能,提
供者應該忽略空白符和換行符。
示例 1:以下負載包含哦一個簡單的 aps 字典,采用默認的警告按鈕的提示信息(關
閉按鈕和查看按鈕)。它使用字符串而不是字典作為 alert 的值。該負載同樣包含了一
個自定義的屬性數組。
{
“aps” : { “alert” : “Message received from Bob” },
“acme2″ : [ “bang”, “whiz” ]
}
示例 2:該示例的負載包含了一個 aps 的字典,指定設備顯示一個警告消息並在左
邊包含一個關閉按鈕和右邊顯示一個本地化的”action”按鈕。在該例中,”PLAY”被作
為鍵使用來從Localizable.strings文件裡面當前偏好語言的字典裡面獲取對應的“Play”
的字符串。aps 字典同樣要求應用程序的圖標顯示數字 5。
{
“aps” : {
“alert” : {
“body” : “Bob wants to play poker”,
“action-loc-key” : “PLAY”
},
“badge” : 5,
},
“acme1″ : “bar”,
“acme2″ : [ “bang”, “whiz” ]
}
2012-01-28 |? 2012 YouMi Mobile Co. Ltd. All Rights Reserved.                   
Local and Push Notification Programming Guide
示例 3:該示例的負載指定設備應用顯示一個警告信息並包含關閉按鈕和查看按
鈕。同時它要求應用程序的圖標顯示數字 9,並在通知顯示的時候播放主目錄廈門的
bingbong.aiff 音頻文件。
{
“aps” : {
“alert” : “You got your emails.”,
“badge” : 9,
“sound” : “bingbong.aiff”
},
“acme1″ : “bar”,
“acme2″ : 42
}
示例 4:該示例的負載主要關注的是使用 alert 字典裡面的 loc-key 和 loc-args 子屬
性來從應用程序的主目錄下面獲取一個本地化的字符串並根據 loc-args 選擇合適的子
變量位於正確的位置。它同樣指定了一個自定義聲音文件 chime,並包含了一個自定
義屬性。
{
“aps” : {
“alert” : { “loc-key” : “GAME_PLAY_REQUEST_FORMAT”, “loc-args” : [ “Jenna”,
“Frank”] },
“sound” : “chime”,
},
“acme” : “foo”
}
示例 5:下面的示例顯示了一個空的 aps 字典,因為 badge 屬性被隱藏了,所以當
前應用程序圖標的任何數字都會被移除。而自定義屬性 acme2 是一個包含兩個整形的
數組。
{
“aps” : {
},
“acme2″ : [ 5, 8 ]
}

記住,為了更好的性能,你應該在把字符串添加到通知裡面之前盡可能的去除空
白字符和換行字符

 

8.2 檢驗證書是否正確的方法:

$ telnet gateway.sandbox.push.apple.com 2195

Trying 17.172.232.226…

Connected to gateway.sandbox.push-apple.com.akadns.net.

Escape character is ‘^]’.

它將嘗試發送一個規則的,不加密的連接到APNS服務。如果你看到上面的反饋,那說明你的MAC能夠到達APNS。按下Ctrl+C 關閉連接。如果得到一個錯誤信息,那麼你需要確保你的防火牆允許2195端口。

然後再次連接,這次用我們的SSL證書和私鑰來設置一個安全的連接:

$ openssl s_client -connect gateway.sandbox.push.apple.com:2195

-cert PushChatCert.pem -key PushChatKey.pem

Enter pass phrase for PushChatKey.pem:

你會看到一個完整的輸出,讓你明白OpenSSL在後台做什麼。如果連接是成功的,你可以鍵入一些字符。當你按下回車後,服務就會斷開連接。如果在建立連接時有問題,OpenSSL將會給你一個錯誤消息,但是你不得不向上翻輸出LOG,來找到它。

當然上面要測試prodution版本是否正確的話,把gateway.sandbox.push.apple.com換成gateway.push.apple.com就好。

 

8.3 Push故障排除

\

 

8.4 APNS信息包結構體

\

上圖顯示的這個消息體就是我們的服務器(Provider)發送給APNS服務器的消息結構,APNS驗證這個結構正確並提取其中的信息後,再將消息推送到指定的設備。這個結構體包括五個部分,第一個部分是命令標示符,第二個部分是我們的device_token的長度,第三部分是我們的device_token字符串,第四部分是推送消息體(Payload)的長度,最後一部分也就是真正的消息內容了,裡面包含了推送消息的基本信息,比如消息內容,應用Icon右上角顯示多少數字以及推送消息到達時所播放的聲音等。接下來我們拆解看一下Payload(消息體)的結構:

{
“aps” : {
“alert” : “You got your emails.”,
“badge” : 1,
“sound” : “default”
},
}

這其實就是個JSON結構體,alert標簽的內容就是會顯示在用戶手機上的推送信息,badge顯示的數量(注意是整型)是會在應用Icon右上角顯示的數量,提示有多少條未讀消息等,sound就是當推送信息送達是手機播放的聲音,傳defalut就標明使用系統默認聲音,如果傳比如“beep.wav”就會播放在我們應用工程目錄下名稱為beep.wav的音頻文件,比如當手機鎖屏時QQ在後台收到新消息時的滴滴聲。

 

有這麼一種情況,當我們將應用從設備卸載後,推送的消息改如何處理呢。我們知道,當我們將應用從設備卸載後,我們是收不到Provider給我們推送的消息的,但是,如何讓APNS和Provider都知道不去向這台卸載了應用的設備推送消息呢?針對這個問題,蘋果也已經幫我們解決了,那就是Feedback service。他是APNS的一部分,APNS會持續的更新Feedback service的列表,當我們的Provider將信息發給APNS推送到我們的設備時,如果這時設備無法將消息推送到指定的應用,就會向APNS服務器報告一個反饋信息,而這個信息就記錄在feedback service中。按照這種方式,Provider應該定時的去檢測Feedback service的列表,然後刪除在自己數據庫中記錄的存在於反饋列表中的device_token,從而不再向這些設備發送推送信息。連接Feedback service的過程同樣使用Socket的方式,連接上後,直接接收由APNS傳輸給我們的反饋列表,傳輸完成後斷開連接,然後我們根據這個最新的反饋列表在更新我們自己的數據庫,刪除那些不再需要推送信息的設備的device_token。從Feedback service讀取的數據結構如下:

\

結構中包含三個部分,第一部分是一個時間戳,記錄的是設備失效後的時間信息,第二個部分是device_token的長度,第三部分就是失效的device_token,我們所要獲取的就是第三部分,跟我們的數據庫進行對比後,刪除對應的device_token,下次不再向這些設備發送推送信息

8.5 消息大批量發送問題

a.消息大批量發送問題

目前由於APNS(Apple Push Notification Service)機制原因,目前easy apns的消息發送機制為:

對每一條發送的消息,為所有需要推送的設備都在數據庫中apns_messages創建一條消息,然後通過輪訓數據庫表來一條一條向蘋果消息推送服務器發送消息

在需要推送的設備較多的情況下,由於存在大量的網絡鏈接,導致存在較長時間的延遲。

解決方案:

1、做批量消息推送時候,保持與蘋果消息推送服務器的長鏈接

2、使用批量發送機制

You should also retain connections with APNs across multiple notifications. APNs may consider connections that are rapidly and repeatedly established and torn down as a denial-of-service attack. Upon error, APNs closes the connection on which the error occurred.

As a provider, you are responsible for the following aspects of push notifications:

You must compose the notification payload (see “The Notification Payload”).

You are responsible for supplying the badge number to be displayed on the application icon.

You should regularly connect with the feedback web server and fetch the current list of those devices that have repeatedly reported failed-delivery attempts. Then you should cease sending notifications to the devices associated with those applications. See “The Feedback Service” for more information.

b、數據庫輪詢效率問題

由於目前easy apns是采用數據庫輪詢的方式來進行消息推送,效率並不高,後期可以修改為Redis這樣的NOSQL

 

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved