如下是一位開發者在集成個推iOS推送SDK過程當中的真實經歷。
做者:Ezreallpios
一次偶然的機會,公司的項目要用到推送,我本身原本就很懶,不肯意去弄整套APNS的流程,恰好以前跟朋友聊起過他們的產品中集成了個推的Android推送,說是體驗還能夠,那此次我就試一下他們的iOS推送。因而抱着試一試的心態,我先建個demo,試着去集成一下個推iOS推送SDK,摸索着完成了整個流程,言歸正傳,直接上硬菜!c++
看了個推的官網,發現他們集成的方式有兩種,分別是XCode集成和CocoaPods集成。本人比較懶,越簡單越好,越輕鬆越好,堅決果斷的選擇了Cocoapods集成方式,程序猿麼,就是要想盡辦法的懶,搞起!面試
1.安裝CocoaPodssql
安裝方式簡單, Mac 下都自帶 ruby,使用 ruby 的 gem 命令便可下載安裝:xcode
$ sudo gem install cocoapods $ pod setup
2.準備Podfile文件ruby
在咱們的工程目錄下,新建一個名爲Podfile的文件,以下格式,將依賴的庫名字依次列在文件中便可:服務器
做者這裏使用的是標準版本:app
target 'GeTuipush' do platform :ios, "7.0" pod 'GTSDK' end target 'NotificationService' do platform :ios, "10.0" pod 'GTExtensionSDK' end
3.完成GTSDK導入ide
在項目根目錄中執行以下命令:測試
$ pod install
執行完成後,項目目錄結構以下圖所示:
注意:在pod install以前,首先你的工程必須建立好,而且若是Podfile文件裏面若是有target:NotificationService,那在pod install以前須要建立好通知擴展的Target。
4.開啓推送功能:既然是推送,固然是要開推送功能啦!:
5.後臺運行權限設置:看個推的官網上面說是爲了更好的支持消息推送,提供更多的推送樣式,提升消息到達率,既然這麼說了,那就無論三七二十一先開了再說,以下圖所示:
6.XCode10建議開啓WiFi信息受權:在 Xcode 10.x 以上,找到應用Target設置中的Capabilities -> Access WiFi Information,確認開關已經設爲ON狀態。以下圖所示:
注意:主Target和通知擴展的Target都須要打開
7.代碼部分,下來就是咱們程序猿最喜歡的部分了,粘貼複製。因爲是第一次集成個推SDK的代碼,我仍是仔細的研究了下。
1.爲AppDelegate增長回調接口類:
#import <UIKit/UIKit.h> #import <GTSDK/GeTuiSdk.h> // iOS10 及以上需導入 UserNotifications.framework #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 #import <UserNotifications/UserNotifications.h> #endif @interface AppDelegate : UIResponder <UIApplicationDelegate, GeTuiSdkDelegate, UNUserNotificationCenterDelegate> @property (strong, nonatomic) UIWindow *window; @end
2.初始化SDK並註冊APNs:
#import "AppDelegate.h" /// 個推開發者網站中申請App時,註冊的AppId、AppKey、AppSecret #define kGtAppId @"GVZZTqh7lu6S4VLMacneZ7" #define kGtAppKey @"RRYDFjGzO17TJXZfGeTuq3" #define kGtAppSecret @"7BXDJ0IgWF6a8M0xCgo4G" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. [GeTuiSdk startSdkWithAppId:kGtAppId appKey:kGtAppKey appSecret:kGtAppSecret delegate:self]; // 註冊 APNs [self registerRemoteNotification]; return YES; }
註冊APNs獲取DeviceToken:
/** 註冊 APNs */ - (void)registerRemoteNotification { UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; center.delegate = self; [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionCarPlay) completionHandler:^(BOOL granted, NSError *_Nullable error) { if (!error) { NSLog(@"request authorization succeeded!"); } }]; [[UIApplication sharedApplication] registerForRemoteNotifications]; }
個推demo裏面給開發者提供演示代碼,根據APP支持的iOS系統不一樣,進行修改。咱們的工程最低支持iOS10。
獲取CID信息:
/** SDK啓動成功返回cid */ - (void)GeTuiSdkDidRegisterClient:(NSString *)clientId { NSLog(@"clientId:%@", clientId); }
這三個參數kGtAppId、kGtAppKey、kGtAppSecret是幹啥用的,這三個參數如何獲取?回頭又看了下個推的官網才搞明白,正好記錄下如何申請者三個參數,跟我應用的bundleID綁定。
1.建立個推開發者帳號
訪問個推開發者中心,申請個推帳號
2.登記新應用
注意:登記新應用是在應用管理頁面而不是消息推送頁面。
在登記應用界面填寫應用名和應用表示,勾選個推產品,勾選iOS,填寫包名和bundleID,以下圖所示:
這裏我有點疑惑。建立應用的時候想勾選iOS,可是看到默認選擇了Android平臺,並要填寫Android簽名,這簽名是what,這如何搞?看到跟前有個提示如何獲取,點了一下,發現裏面有SHA256的簽名,抱着試一試的態度,直接copy過來,呦呵,能用哦,內心美滋滋。
提交成功後就能夠獲取到kGtAppId、kGtAppKey、kGtAppSecret,將三個參數填入咱們的工程中,而後運行工程,在GeTuiSdkDidRegisterClient的回調方法中獲取到cid了,嗯,看來咱們已經成功了一一小部分了,距離成功還要繼續加油。
1.向個推服務器註冊DeviceToken:
/** 遠程通知註冊成功委託 */ - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { //向個推服務器註冊deviceToken 爲了方便開發者,建議使用新方法 NSLog(@"deviceToken:%@",deviceToken); [GeTuiSdk registerDeviceTokenData:deviceToken]; }
2.處理APNs通知點擊事件:
由於咱們的工程最低適配到iOS10,這裏我就只添加了iOS10及之後版本的通知點擊事件,要是想兼容iOS10如下的,能夠在個推的demo中找到。
iOS 10及之後版本,處理APNs通知點擊事件
// iOS 10: 點擊通知進入App時觸發,在該方法內統計有效用戶點擊數 - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler { NSLog(@"didReceiveNotification:%@", response.notification.request.content.userInfo); // [ GTSdk ]:將收到的APNs信息傳給個推統計 [GeTuiSdk handleRemoteNotification:response.notification.request.content.userInfo]; completionHandler(); }
3.接受個推通道下發的透傳消息:
/** SDK收到透傳消息回調 */ - (void)GeTuiSdkDidReceivePayloadData:(NSData *)payloadData andTaskId:(NSString *)taskId andMsgId:(NSString *)msgId andOffLine:(BOOL)offLine fromGtAppId:(NSString *)appId { //收到個推消息 NSString *payloadMsg = nil; if (payloadData) { payloadMsg = [[NSString alloc] initWithBytes:payloadData.bytes length:payloadData.length encoding:NSUTF8StringEncoding]; } NSString *msg = [NSString stringWithFormat:@"taskId=%@,messageId:%@,payloadMsg:%@%@",taskId,msgId, payloadMsg,offLine ? @"<離線消息>" : @""]; NSLog(@"\n>>>[GexinSdk ReceivePayload]:%@\n\n", msg); }
獲取到了透傳消息,可是當應用在後臺或者應用殺死的狀況下,咱們如何獲取到APNs消息,這裏咱們就須要在個推平臺用到推送證書,如何獲取推送證書?由於本人也是第一次搞推送這書,並且也踩了很多的坑,爲了下次再也不踩一樣的坑,因此在這裏就對如何製做推送證書進行了一次規整。
1.進入蘋果開發者中心,選擇證書選項,以下圖所示:
2.建立推送證書以前必須建立一個APPID,由於推送證書是和APPID綁定在一塊兒的,以下圖所示:
在下面的App Services中選擇容許推送(Push Notifications),以下圖所示:
3.APPID建立好了以後,這個時候須要去建立推送證書,並且還要根據須要的環境選擇對應的推送證書,包括開發環境推送證書和生產環境推送證書,而後還要跟剛纔建立好的APPID相關聯,以下圖所示:
這個時候須要上傳CSR文件,咱們回到桌面,打開鑰匙串,從頒發機構申請證書並保存到本地磁盤,以下圖所示:
這樣CSR文件就建立好了,咱們回到蘋果開發者中心,繼續建立咱們的推送證書,選擇保存到本地的CSR文件,以下圖所示:
這樣,咱們的推送證書就建立完成了,在本地下載中找到下載的推送證書並雙擊添加到鑰匙串中,而後打開鑰匙串找到建立好的推送證書,右鍵導出P12證書,並輸入證書密碼,以下圖所示:
4.打開咱們的個推開發者中心,在個推·消息推送-應用列表-應用配置」中上傳正確的APNs證書,以下圖所示:
接下來最重要的時刻來了,那就是測試了,看看咱們的推送能不能成功。
本人是在個推平臺上面進行推送測試的,在應用列表裏面點擊以前建立的應用上的建立推送按鈕,以下圖所示:
進入後,我有點懵逼,由於以前沒有了解過個推SDK的邏輯,在詢問了個推技術支持後,技術支持告訴我怎麼在個推平臺上面去推,也是本身太粗心了,人家進去第一句話就寫的很清楚,推送通知目前僅支持安卓用戶,iOS請使用透傳消息。尷尬!那就透傳消息頁面試試推。以下圖所示:
透傳消息測試:
APNs消息測試
NICE啊,這下應用在前臺、應用在後臺和應用被殺死的狀況下均可以收到推送消息了,爽歪歪啊!看來咱們已經成功看了百分之九十了!
正在沾沾自喜的時候,忽然發現個推的官網上面還有多媒體推送,我靠,還有這種操做,好奇心的趨勢下,讓我從新審視如何去作多媒體推送。由於咱們以前已經把通知擴展的target建立好了,因此,直接上代碼。
1.Notification Service Extension 添加成功後會在項目中自動生成 NotificationService.h 和 NotificationService.m 兩個類,包含如下兩個方法:
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent *_Nonnull))contentHandler { self.contentHandler = contentHandler; self.bestAttemptContent = [request.content mutableCopy]; // [ 測試代碼 ] TODO:用戶能夠在這裏處理通知樣式的修改,eg:修改標題,開發階段能夠用於判斷是否運行通知擴展 //self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [WillIn]", self.bestAttemptContent.title]; // [ GTSDK ] 統計APNs到達狀況和多媒體推送支持接口, 建議使用該接口 [GeTuiExtSdk handelNotificationServiceRequest:request withAttachmentsComplete:^(NSArray *attachments, NSArray *errors) { // self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [Success]", self.bestAttemptContent.title]; self.bestAttemptContent.attachments = attachments; // 設置通知中的多媒體附件 self.contentHandler(self.bestAttemptContent); }]; }
咱們能夠在這個方法中處理咱們的 APNs 通知,並個性化展現給用戶。APNs 推送的消息送達時會調用這個方法,此時你能夠對推送的內容進行處理,而後使用contentHandler方法結束此次處理。可是若是處理時間過長,將會進入serviceExtensionTimeWillExpire方法進行最後的緊急處理。
- (void)serviceExtensionTimeWillExpire { // [ GTSDK ] 銷燬SDK,釋放資源 [GeTuiExtSdk destory]; //self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [Timeout]", self.bestAttemptContent.title]; self.contentHandler(self.bestAttemptContent); }
若是didReceiveNotificationRequest方法在限定時間內沒有調用 contentHandler方法結束處理,則會在過時以前進行回調本方法。此時你能夠對你的 APNs 消息進行緊急處理後展現,若是沒有處理,則顯示原始 APNs 推送。
接下來就是測試咱們的多媒體推送是否成功,我在網上找了個小狗的照片,直接在個推平臺上面推。
多媒體測試
6啊,終於搞定了!棒棒噠~~~
可是,以前的一個老項目說也要集成推送,我透,老項目要用XCode集成,這對於我這種懶人來講,簡直是一種折磨啊,哎,折磨歸折磨,該搞還要搞。可是以前已經用CocoaPods搞過一遍,此次用XCode集成還不是手到擒來。可是爲了防止出錯,本人仍是先作了個demo,這樣後面在本身項目上面集成的話把握性會更大,踩的坑也就會更少。
1.導入個推SDK:
2.庫引用檢查:
3.添加系統依賴庫:
libc++.tbd libz.tbd libsqlite3.tbd libresolv.tbd Security.framework MobileCoreServices.framework SystemConfiguration.framework CoreTelephony.framework AVFoundation.framework CoreLocation.framework UserNotifications.framework (iOS 10 及以上需添加,使用 Optional 方式接入) AdSupport.framework (若是使用無IDFA版本SDK,則需刪除該 AdSupport 庫)
幸好後面的步驟基本上都是同樣的,惟一的欣慰呀!
4.開啓推送功能、後臺運行權限設置、開啓WiFi信息受權
這裏跟上面步驟同樣,就不囉嗦了。
5.copy代碼,這是咱們程序猿最喜歡的啦,哈哈哈,以前搞過,這裏就不累贅了。
6.添加Notification Service Extension
(1).打開XCode,菜單中選擇File->New->Target->Notification Service Extension。以下圖所示:
注意:1.Extension的Bundle Identifier不能和Main Target(也就是本身的App Target)的Bundle Identifier相同,不然會報BundleID重複的錯誤。2.Extension 的 Bundle Identifier 須要在 Main Target 的命名空間下,好比說 Main Target 的 BundleID 爲 ent.getui.xxx,那麼Extension的BundleID應該相似與ent.getui.xxx.yyy這樣的格式。若是不這麼作,會引發命名錯誤。
這個是在個推官網上面看到的,以前本身也踩了這個坑,這裏就記錄下來。
添加 Notification Service Extension 後會生成相應的 Target。點Finish按鈕後會彈出是否激活該 Target 對應 scheme 的選項框,選擇 Activate,若是沒有彈出該選項框,須要自行添加相應的 scheme。以下圖所示:
(2).Notification Service Extension 添加成功後會在項目中自動生成 NotificationService.h 和 NotificationService.m 兩個類
這裏跟上面同樣,就不累贅了。
(3).添加GtExtensionSdk依賴庫
選擇Notification Service Extension所對應的Target,添加以下依賴庫:
libz.tbd libsqlite3.tbd GTExtensionSDK.framework UserNotifications.framework
(4).XCode10建議開啓WiFi信息受權:在 Xcode 10.x 以上,找到應用Target設置中的Capabilities -> Access WiFi Information,確認開關已經設爲ON狀態。以下圖所示:
(5).開啓多媒體地址Http訪問支持:
最讓我印象深入的就是無效的deviceToken,在測試APNS推送的時候,詢問過個推那邊的技術支持,他們說能夠先在應用配置裏面測試一下,而後我就拿着個人deviceToken去測試一下,結果提示我是無效的deviceToken,我暈,而後繼續諮詢個推的技術支持,他們說這個緣由有多是我證書環境的問題。通過一番仔細的檢查以後,發現,我在個推平臺上面上傳的是通用證書,而後我XCode上面的受權證書是開發環境下,這樣一來,拿到的是開發環境下的deviceToken,用測試一下,固然會出錯。
解決的方案有兩種:第一,在個推開發平臺上傳開發環境下的推送證書。第二:將本身的受權證書更換爲生產環境。
self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [Success]", self.bestAttemptContent.title];
發現demo裏面有這麼一行代碼,我把這行代碼打開後,推送一條消息,發現標題沒有變化,我驚呆了!詢問個推技術支持,個推技術支持說,讓我先運行主target,而後再運行通知擴展,運行通知擴展的時候會讓咱們去找主targetAPP,選擇主target,而後再推送就會有了,嗯,想了下,這個應該是XCode的bug。
最後,我要說,消息推送功能的集成對APP而言真的真的很重要。以上是個推iOS推送SDK集成的全步驟,給你們作個參考。特別須要注意的幾點是:
1.在個推平臺上上傳的推送證書必定要正確而且要和本身的環境相對應,推薦上傳P8證書;
2.主target和通知擴展target是兩個target,命名和bundleID上要注意,本人是按照個推官網給的建議命名的。
原文連接: https://www.jianshu.com/p/cce2200c0ed7