iOS 細說訊息推送

來源:互聯網
上載者:User

標籤:應用   控制   ios   裝置   訊息   

轉自豐俊文的部落格

Apple對裝置的控制非常嚴格,訊息推送的流程必須要經過APNs

APNS的推送機制

與Android上我們自己實現的推送服務不一樣,Apple對裝置的控制非常嚴格,訊息推送的流程必須要經過APNs:

這裡 Provider 是指某個應用的Developer,當然如果開發人員使用AVOS Cloud的服務,把發送訊息的請求委託給我們,那麼這裡的Provider就是AVOS Cloud的推送服務程式了。可以分為三步:
第一步:AVOS Cloud推送服務程式把要發送的訊息、目的裝置的唯一標識打包,發給APNs。
第二步:APNs在自身的登入Push服務的應用列表中,尋找有相應標識的裝置,並把訊息發送到裝置。
第三步:iOS系統把發來的訊息傳遞給相應的應用程式,並且按照設定彈出Push通知

為了實現訊息推送,有兩點非常重要:
1,App的推送認證
要能夠完整實現一條訊息推送,需要我們在App ID中開啟Push Notifications,需要我們準備好Provisioning Profile和SSL認證,並且一定要注意Development和Distribution環境是需要分開的。最後,把SSL認證匯入到AVOS Cloud平台,就可以嘗試遠程訊息推送了。具體的操作流程可以參考我們的使用指南:iOS推送認證設定指南。

2,裝置標識DeviceToken
知道了誰要推送,或者說要推送給哪個App之後,APNs還需要知道推到哪台裝置上,這就是裝置標識的作用。擷取裝置標識的流程如下:

第一步:App開啟推送開關,使用者要確認TA希望獲得該App的推送訊息
第二步:App獲得一個DeviceToken
第三步:App將DeviceToken儲存起來,這裡就是通過[AVInstallation saveInBackground]將DeviceToken儲存到AVOS Cloud
第四步:當某些特定事件發生,開發人員委託AVOS Cloud來發送推送訊息,這時候AVOS Cloud的推送伺服器就會給APNs發送一則推送訊息,APNs最後訊息送到使用者裝置

推送相關的幾個概念

訊息類型
一條訊息推送過來,可以有如下幾種表現形式:
1. 顯示一個alert或者banner,展現具體內容
2. 在應用icon上提示一個新到訊息數
3. 播放一段聲音

開發人員可以在每次推送的時候設定,在推送達到使用者裝置時開發人員也可以選擇不同的提示方式。

本地訊息通知
iOS上有兩種訊息通知,一種是本地訊息(Local Notification),一種是遠程訊息(Push Notification,也叫Remote Notification),設計這兩種通知的目的都是為了提醒使用者,現在有些什麼新鮮的事情發生了,吸引使用者重新開啟應用。

本地訊息什麼時候有用呢?譬如你正在做一個To-do的工具類應用,對於使用者加入的每一個事項,都會有一個完成的時間點,使用者可以要求這個To-do應用在事項到期之前的某一個時間點提醒一下TA。為了達到這一目的,App就可以調度一個本地通知,在時間點到了之後發出一個Alert訊息或者其他提示。
我們在處理推送訊息的時候,也可以綜合運用這兩種方式。

代碼裡面如何?推送

首先,我們要擷取DeviceToken。
App需要每次啟動的時候都去註冊遠程通知——通過調用UIApplication的registerForRemoteNotificationTypes:方法,傳遞給它你希望支援的訊息類型參數即可,例如:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {     // do some initiale working     ...     [application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];     return YES; } 

如果註冊成功,APNs會返回給你裝置的token,iOS系統會把它傳遞給app delegate代理
application:didRegisterForRemoteNotificationsWithDeviceToken:
方法,你應該在這個方法裡面把token儲存到AVOS Cloud後台,例如:

- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {     NSLog(@"Receive DeviceToken: %@", deviceToken);     AVInstallation *currentInstallation = [AVInstallation currentInstallation];     [currentInstallation setDeviceTokenFromData:deviceToken];     [currentInstallation saveInBackground]; } 

如果註冊失敗
application:didFailToRegisterForRemoteNotificationsWithError:方法會被調用,通過NSError參數你可以看到具體的出錯資訊,例如:

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {     NSLog(@"註冊失敗,無法擷取裝置ID, 具體錯誤: %@", error); } 

請注意:註冊流程需要在app每次啟動時調用,這並不不會帶來額外的負擔,因為iOS作業系統在第一次獲得了有效device token之後,會本機快取起來,以後app再調用registerForRemoteNotificationTypes:的時候會立刻返回,並不會再進行網路請求。另外,app層面不應該對device token進行緩衝,因為device token也有可能變化——如果使用者重裝了作業系統,那麼APNs再次給出的device token就會和之前的不一樣,又或者是,使用者restore了原來的backup到新的裝置上,那麼原來的device token也會失效。
其次,我們要處理收到訊息之後的回調
我們可以設想一下訊息通知的幾種使用情境:
1,在app沒有被啟動的時候,接收到了訊息通知。這時候作業系統會按照預設的方式來展現一個alert訊息,在app icon上標記一個數字,甚至播放一段聲音。

2,使用者看到訊息之後,點擊了一下action按鈕或者點擊了應用表徵圖。如果action按鈕被點擊了,系統會通過調用
application:didFinishLaunchingWithOptions:這個代理方法來啟動應用,並且會把notification的payload資料傳遞進去。如果應用表徵圖被點擊了,系統也一樣會調用application:didFinishLaunchingWithOptions:這個代理方法來啟動應用,唯一不同的是這時候啟動參數裡面不會有任何notification的資訊。
範例程式碼如下:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {     // do initializing works     ...     if (launchOptions) {         // do something else         ...         [AVAnalytics trackAppOpenedWithLaunchOptions:launchOptions];     }     [application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];     return YES; } 

3,如果遠程訊息發送過來的時候,app正在運行,這時候會發生什麼呢?

app代理的application:didReceiveRemoteNotification:方法會被調用,同時遠程訊息中的payload資料會作為參數傳遞進去。

範例程式碼如下:

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {     if (application.applicationState == UIApplicationStateActive) {         // 轉換成一個本地通知,顯示到通知欄,你也可以直接顯示出一個alertView,只是那樣稍顯aggressive:)         UILocalNotification *localNotification = [[UILocalNotification alloc] init];         localNotification.userInfo = userInfo;         localNotification.soundName = UILocalNotificationDefaultSoundName;         localNotification.alertBody = [[userInfo objectForKey:@"aps"] objectForKey:@"alert"];         localNotification.fireDate = [NSDate date];         [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];     } else {         [AVAnalytics trackAppOpenedWithRemoteNotificationPayload:userInfo];     } } 

常見問題FAQ

1.我能推送長訊息嗎?
不能,APNs限制了每個notification的payload最大長度是256位元組,超長的訊息是不能發送的。

2.推送怎麼加聲音提醒?
訊息推送是可以指定聲音的。譬如你可以對正面的反饋使用歡快的聲音,對負面的反饋使用低沉一點的聲音,都可以達到別出心裁讓人眼前一亮的目的。

你需要先放一些aiff、wav或者caf音頻檔案到app的資源檔中,然後在推送的時候指定不同的音頻檔案名稱就可以了。

3.推送的Badge是怎麼回事?
推送並不一定會導致應用表徵圖上紅色數字增加,是否顯示這一數字,顯示成多少,都取決於開發人員自己。

在發送推送訊息的時候,我們可以選擇是否遞增這一數字;如果不選擇這一項,那麼訊息推送並不會導致應用表徵圖上紅色數位出現。

好,現在問題來了,這個數字如果搞出來了,怎麼讓它消失掉呢?

其實我們只需要在任何時候設定
UIApplication.applicationIconBadgeNumber屬性為0,就可以讓這個數字消失掉。

一般我們會選擇在應用啟動的時候
application:didFinishLaunchingWithOptions:方法中),或者乾脆一點,在應用每次被切換到前台的時候(applicationWillEnterForeground:方法中),調用這一行代碼,即可立刻清除掉Badge數字了。

  1. AVOS Cloud平台發出去的通知格式究竟是什麼樣子的
    對於每一條推送訊息,都包含一個payload,通常是組成了一個JSON的Dictionary,這其中必不可少的是aps屬性,它對應的value也是一個Dictionary,包含下面一些內容:
    1)alert訊息(文本或Dictionary)
    2)應用表徵圖上的紅色數字
    3)播放的音效檔名

在由推送啟用的app開啟事件中,
application:didFinishLaunchingWithOptions:的options參數就是這個大的Dictionary對象。

{     aps =     {         alert = "hello, everyone";         badge = 2;         sound = default;     }; } 

這裡要注意的時alert部分,它的值可以是一個String(簡訊),也可以是一個JSON的Dictionary。當它是簡訊的時候,系統就會把這些文字顯示到一個alertview中;如果它也是由一個JSON Dictionary組成的話,其格式如下:
* body
* action-loc-key
* loc-key
* loc-args
* launch-image

body部分就是alertView中將要展現出來的簡訊,loc-屬性主要是用來實現本地化訊息,launch-image只是app主bundle裡的一個圖片檔案的名稱,一般來說我們不指定這一屬性。

  1. 如何顯示本地化的訊息
    有兩種辦法可以實現推送訊息的本地化:
    1)在推送的payload中使用loc-key和loc-args來指定進行本地化,這樣Provider方只需要按照統一的格式來發送即可,訊息的解析和組裝則由用戶端來完成。
    2)如果推送的payload裡面不包含loc-key/loc-args資訊,那麼Provider方就需要自己做本地化處理,然後給不同的device發送不同的訊息,為了做到這一點,還需要app在上傳device token的時候也把使用者的語言設定資訊傳回來。
    目前,因為AVOS Cloud主要就是瞄準中國大陸市場和海外中文使用者,所以我們在推送上還不提供多語言支援。

  2. 應用該怎麼響應推送訊息
    上面說的處理流程,只能簡單展示一下遠程訊息,啟用使用者讓他們重新回到app中來。但是有時候,我們希望帶給使用者更好的使用體驗,譬如如果我們告訴使用者:張三剛剛評論了你的照片。這時候使用者如果點擊action按鈕進入app,我們是展示具體的評論頁面為好,還是展示通常的啟動頁面然後讓使用者自己去找張三的評論好?我想負責任的開發人員都會選擇前者。

要做到靈活響應不同類型的通知訊息,我們需要在通知的payload中增加更多資訊,而不能僅僅只有alert出來的文字資訊。對於AVOS Cloud訊息推送平台來講,就需要開發人員使用更進階功能的JSON格式。譬如我們發送這樣的json字串{"action":{"type":4},"alert":"hello, everyone”}最終在app內會收到這樣的UserInfo Dictionary:

{     action =     {         type = 4;     };     aps =     {         alert = "hello, everyone";         badge = 4;     }; } 

“hello, everyone”會顯示到alertView中,但是整個Dictionary會通過launchOptions傳遞給application: didFinishLaunchingWithOptions:方法,這樣我們在程式裡面就可以對不同的訊息實現不同的跳轉了。

iOS 細說訊息推送

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.