本文旨在對 IOS 推送進行一個完整的剖析,如果你之前對推送一無所知,那麼在你認真地閱讀了全文後必將變成一個推送老手,你將會對其中的各種細節和原理有充分的理解。以下是pikacode使用 IOS 推送的一些經驗,歡迎互相交流,指出錯漏之處。
推送服務可以說是所有 App 的標配,不論是哪種類型的 App,推送都從很大程度上決定了 App 的 打開率、使用率、存活率 。因此,熟知並掌握推送原理及方法,對每一個開發者來說都是必備技能,對每一個依賴 App 的公司來說都至關重要。
從 IOS 10 新增的UserNotifications Framework
可以發現,Apple
整合了原有散亂的 API,並且增加了許多強大的功能。以 Apple 官方的角度來看,也必然是相當重視推送服務對 App 的影響、以及對 Apple iOS 生態圈長遠發展的影響。
badge
[以下簡稱角標]
等都會由系統來控制和展示)。收到推送時,是無法在 App 的代碼中獲取到通知內容的。因為沙盒機制,此時 App 的任何代碼都不可能被執行。
Tip 3:手機向 APNs 注冊推送服務
在代碼中注冊推送服務:
#ifdef __IPHONE_8_0
if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)]) {
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge| UIUserNotificationTypeSound|UIUserNotificationTypeAlert categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
} else {
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:myTypes];
}
#else
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:myTypes];
#endif
在第一次觸發這段代碼的時候,會有一個系統彈窗,詢問你是否允許該 App 要給你推送信息。當你選擇允許時,系統會打包 App+手機唯一標識+證書 信息發送至 APNs 服務器注冊推送服務,APNs 系統會對該手機安裝的該 App 是否有推送權限進行驗證,所以必須要加入了 Apple Deveice 的手機,使用對應 App 的推送證書才能夠成功的注冊。
如果注冊成功,則可以在AppDelegate.m
的如下方法中獲取到deviceToken
,它是對
該手機+該App 組合的一個唯一標識,當使用遠程推送時,只需將推送消息發給指定的deviceToken
即可使推送信息傳達給指定手機的指定
App 上。因此如果你使用第三方,就需要在這個方法裡將deviceToken
傳給第三方。(在
iOS 9 為了更好的保護用戶隱私,會出現多次重復刪除/安裝 App 導致deviceToken
不斷變化的情況。有時會出現一條推送手機會收到
2 次的問題,屬於 iOS 9 系統問題)。
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
[JPUSHService registerDeviceToken:deviceToken];//將 deviceToken 傳給極光推送
}
如果以上步驟均成功,此時你能夠取到第三方提供的設備注冊 id。能否取到該 id 值,可以作為判斷設備是否能夠成功推送的標准(見 Tip 6 - Registration ID)。因為當你取到該值時必然:
推送證書配置正確(你擁有了推送權限)。設備成功在 APNs 注冊並返回了deviceToken
(APNs
能識別你的設備了)。返回 的deviceToken
傳給第三方,成功在第三方生成了唯一標識注冊
id(第三方能將你的設備信息傳給 APNs 了)。
綜上,注冊及接收推送必須使用真機,必須連網。
Tip 4:推送通知從 服務端 --> App 代碼 的過程
使用你們公司或第三方的服務端向 APNs 發送推送請求(請參考蘋果 APNs 相關資料,或者第三方推送提供了更簡單的 REST API)。APNs 接收並驗證推送請求。APNs 找到設備下發推送。手機收到推送通知,系統根據 App 狀態進行處理:
前台收到:
系統會將通知內容傳到didReceiveRemoteNotification
後台收到:
如果開啟了Remote
Notification
,系統將推送傳到didReceiveRemoteNotification:fetchCompletionHandler:
(見
Tip 5 - 後台推送),否則此時代碼中收不到推送。展示橫幅、通知中心、聲音、角標。
退出收到:
如果點擊推送橫幅/通知中心而啟動 App,系統將通知傳到didFinishLaunchingWithOptions
。展示橫幅、通知中心、聲音、角標。
推送通知內容篇
Tip 5:推送通知分為 本地/遠程 2 種類型:
本地通知,可指定推送時間,在該時間准時彈出推送通知。
遠程推送通知,分為 普通推送/後台推送/靜默推送 3 種類型。存在延遲問題(由於 Tip 1 第 2 點,APNs 的不穩定及高峰時段的巨量請求所致)。
普通推送
就是我們在手機上平時見到的推送通知。包含聲音、橫幅、角標、自定義字段。App : 處於前台,不會展示橫幅,可通過didReceiveRemoteNotification
(iOS
7 before)didReceiveRemoteNotification:fetchCompletionHandler:
(iOS
7 after)獲取通知內容(前台展示橫幅的方法看這裡)。處於後台,會展示橫幅,無法獲取通知內容。處於退出,會展示橫幅,無法獲取通知內容。點擊圖標啟動,無法獲取通知內容。點擊通知橫幅啟動,在didFinishLaunchingWithOptions
獲取通知內容。
通知內容類似如下:
{
"_j_msgid" = 200806057; // 第三方附帶的 id,用於統計點擊
aps = {
alert = "顯示內容";
badge = 1; // App 角標,可推送 n、+n、-n 來實現角標的固定、增加、減少
sound = default; // 推送聲音,默認系統三全音,如需使用自己的聲音,需要將聲音文件拖拽&拷貝至 Xcode 工程目錄任意位置,並在推送時指定其文件名
};
key1 = value1; // 自定義字段,可設置多組,用於處理內部邏輯
key2 = value2;
}
後台推送
各種顯示效果跟普通推送完全一樣。必須攜帶"content-available"
= 1;
必須攜帶alert
、badge
、sound
中至少
1 個字段
。僅 iOS 7 以後支持。必須在 Xcode 工程中 TARGETS - Capabilities - Background Modes - Remote notifications 開啟該功能,具體可參照iOS
7 Background Remote Notification。App:
處於前台,可通過didReceiveRemoteNotification
(iOS
7 before)didReceiveRemoteNotification:fetchCompletionHandler:
(iOS
7 after) 獲取通知內容。處於後台,可通過didReceiveRemoteNotification:fetchCompletion
Handler:
獲取通知內容 // 獲取情況中與普通推送的唯一不同點,此時 iOS 系統允許開發者在 App 處於後台的情況下,執行一些代碼,大概提供幾分鐘的時間,可以用來偷偷的刷新 UI、切換頁面、下載更新包等等操作。處於退出,無法獲取通知內容。點擊圖標啟動,無法獲取通知內容。點擊推送橫幅啟動,在didFinishLaunchingWithOptions
獲取通知內容。
通知內容類似如下:
{
"_j_msgid" = 2090737306;
aps = {
alert = "顯示內容";
badge = 1;
"content-available" = 1; // 必帶字段
sound = default;
};
key1 = value1;
}
靜默推送
沒有任何展示效果。必須攜帶"content-available"
= 1;
,因此靜默必然是後台的。必須不攜帶alert
、badge
、sound
。可攜帶自定義字段。App :
處於前台,可通過didReceiveRemoteNotification
(iOS
7 before)didReceiveRemoteNotification:fetchCompletionHandler:
(iOS
7 after) 獲取通知內容。處於後台,可通過didReceiveRemoteNotification:fetchCompletion
Handler:
獲取通知內容 //獲取情況中與普通推送的唯一不同點,此時 iOS 系統允許開發者在 App 處於後台的情況下,執行一些代碼,大概提供幾分鐘的時間,可以用來偷偷的刷新 UI、切換頁面、下載更新包等等操作。處於退出,無法獲取通知內容。
通知內容類似如下:
{
"_j_msgid" = 3938587719;
aps = {
alert = "";
"content-available" = 1; // 必帶字段
};
key1 = value1;
}
推送目標篇
別名、標簽、Registration ID 均是第三方提供的用於更方便地指定推送目標的功能。
Tip 6:推送根據目標的不同可分為: 廣播 無差別發送給所有用戶。 別名 alias 推送 第三方提供的功能一個手機的一款 App 只能設置一個 alias(可修改)。建議對每一個用戶都取不同的別名,以此來確定唯一的用戶(也可多個用戶取 1 個別名)。推送時可指定多個 alias 來下發同一內容。僅指定 alias 的用戶能夠收到推送。 標簽 tag 推送 第三方提供的功能。可設置多個、可增加、清空。用於指定多樣的屬性,如 『1000』+『daily』+『discount』 可用於表示月消費超過 1k、喜歡購買日用品、偏好折扣商品的用戶。如果要刪除,需要在上次設置時,將設置的 tags 保存至NSUserDefaults
,本次剔除不需要的
tag 後,再重新設置。推送時可指定多個 tag 來下發同一內容。手機如果設置了推送指定的多個 tag 中任一個tag,都能夠收到推送消息。如指定 『1000』+『globe』+『original』 (千元級消費者、全球購、原價),那麼設置了 『100』+『globe』+『discount』(百元級消費者、全球購、折扣價)的用戶可以收到該推送消息。
Registration ID 推送
第三方提供的功能。在 Tip 3 的第 3 步時將deviceToken
提供給第三方之後,其服務器會自動生成的指向該手機的唯一
id。可在推送時指定多個 id 來下發消息。可用於對核心用戶、旗艦用戶的精准推送。
應用內消息篇
Tip 7:應用內消息(以下簡稱消息 )和推送通知的區別,消息:
不需要 Apple 推送證書。由第三方的服務器下發,而不是 APNs。相比通知,更快速,幾乎沒有延遲,可用於 IM 消息的即時送達。能夠長時間保留離線消息,可獲取所有歷史消息內容。通過長連接技術下發消息,因此:
手機必須啟動並與第三方服務器建立連接。如果手機啟動立刻切至後台,很可能連接沒有建立。手機必須處於前台才能收到消息。手機從後台切回前台,會自動重新建立連接,並收到離線消息。
沒有任何展示(橫幅、通知中心、角標、聲音),因此可以:
自定義字段實現 UI 效果。完全在靜默情況下處理 App 內部邏輯。使用一些 App Store 審核不會通過的功能,在審核時關閉功能,上架後通過接收消息,開啟相關功能。
組合大招篇
Tip 8:tags 的組合技巧
見 Tip 5 - 標簽 tag 推送。可以在服務端來統計分析用戶行為,然後將指定的 tags 發送至手機,手機接收後再為用戶打上對應的 tags。
Tip 9:通知+消息的組合技巧
首先來看通知和消息特性的對比:
由於各自的特性都存在差異,因此二者結合使用是使得 App 推送性能最大化的必然選擇:
情景一:
作者:pikacode - 極光
原文:iOS 推送全解析,你不可不知的所有 Tips!
知乎專欄:極光日報
以上就是iOS 推送全解析,你不可不知的所有 Tips!的全文介紹,希望對您學習和使用ios應用開發有所幫助.【iOS 推送全解析,你不可不知的所有 Tips!】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!