個推第三方平臺官網地址:http://www.getui.com/cn/index.htmlhtml
首先去官網註冊帳號,建立應用,應用的配置信息,建立APNs推送證書上傳 P12證書(開發對應開發證書,上線對應生產證書)包括導入 SDK 添加依賴庫...這些繁瑣的事請移步個推官網查看 xcode 集成教程.前端
個推 iOS 推送服務框架以下圖所示:ios
1.app 在前臺接收到通知web
APP接收到推送後推送後首先彈出一個Alert提示是否跳轉頁面json
2.app 在後臺接收到通知xcode
點擊通知欄使APP進入前臺後,直接跳轉頁面服務器
點擊icon圖標使APP進入前臺後,不做操做app
3.app 處於關閉狀態接收到通知框架
點擊通知欄啓動APP,直接跳轉頁面性能
點擊icon圖標啓動APP,不做操做
二.iOS 集成個推只支持透傳消息(透傳消息而且支持安卓)
首先爲AppDelegate添加一個屬性 分辨通知的三種狀況
// 用來判斷是不是經過點擊通知欄開啓(喚醒)APP @property (nonatomic) BOOL isLaunchedByNotification;
[1]:使用APPID/APPKEY/APPSECRENT建立個推實例
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self startSdkWith:kGtAppId appKey:kGtAppKey appSecret:kGtAppSecret];
}
- (void)startSdkWith:(NSString *)appID appKey:(NSString *)appKey appSecret:(NSString *)appSecret { //[1-1]:經過 AppId、 appKey 、appSecret 啓動SDK //該方法須要在主線程中調用 [GeTuiSdk startSdkWithAppId:appID appKey:appKey appSecret:appSecret delegate:self]; //[1-2]:設置是否後臺運行開關 [GeTuiSdk runBackgroundEnable:YES]; //[1-3]:設置電子圍欄功能,開啓LBS定位服務 和 是否容許SDK 彈出用戶定位請求 [GeTuiSdk lbsLocationEnable:YES andUserVerify:YES]; }
[2]:註冊APNS
#pragma mark - 用戶通知(推送) _自定義方法 /** 註冊遠程通知 */ - (void)registerRemoteNotification { if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) { #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 // Xcode 8編譯會調用 UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionCarPlay) completionHandler:^(BOOL granted, NSError *_Nullable error) { if (!error) { NSLog(@"request authorization succeeded!"); } }]; [[UIApplication sharedApplication] registerForRemoteNotifications]; #else // Xcode 7編譯會調用 UIUserNotificationType types = (UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge); UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil]; [[UIApplication sharedApplication] registerUserNotificationSettings:settings]; [[UIApplication sharedApplication] registerForRemoteNotifications]; #endif } else if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) { UIUserNotificationType types = (UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge); UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil]; [[UIApplication sharedApplication] registerUserNotificationSettings:settings]; [[UIApplication sharedApplication] registerForRemoteNotifications]; } else { UIRemoteNotificationType apn_type = (UIRemoteNotificationType)(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge); [[UIApplication sharedApplication] registerForRemoteNotificationTypes:apn_type]; } }
[3]遠程通知註冊成功委託
/** 遠程通知註冊成功委託 */ - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]]; token = [token stringByReplacingOccurrencesOfString:@" " withString:@""]; NSLog(@"\n>>>[DeviceToken Success]:%@\n\n", token); NSLog(@"--個推註冊成功_-"); // [ GTSdk ]:向個推服務器註冊deviceToken [GeTuiSdk registerDeviceToken:token]; }
/** 遠程通知註冊失敗委託 */
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { NSLog(@"---個推註冊失敗---");
//註冊失敗通知個推服務器 [GeTuiSdk registerDeviceToken:@""];
}
[4]APP已經接收到「遠程」通知(推送) - (App運行在後臺/App運行在前臺)
/** APP已經接收到「遠程」通知(推送) - (App運行在後臺/App運行在前臺) */ - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler { //此時 App 在後臺點擊通知欄進去前臺 這裏可作進入前臺操做 //app 進去前臺 icon角標顯示數爲0 而且發送個推服務器 [[UIApplication sharedApplication] cancelAllLocalNotifications]; [UIApplication sharedApplication].applicationIconBadgeNumber = 0; [GeTuiSdk setBadge:0]; // [ GTSdk ]:將收到的APNs信息傳給個推統計 [GeTuiSdk handleRemoteNotification:userInfo]; // [4-EXT]:處理APN NSString *record = [NSString stringWithFormat:@"App運行在後臺/App運行在前臺[APN]%@, %@", [NSDate date], userInfo]; NSLog(@"%@", record); completionHandler(UIBackgroundFetchResultNewData); self.isLaunchedByNotification = YES;
//iOS 10中收到推送消息
#pragma mark - iOS 10中收到推送消息 #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 // iOS 10: App在前臺獲取到通知 - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler { NSLog(@"willPresentNotification:%@", notification.request.content.userInfo); // 根據APP須要,判斷是否要提示用戶Badge、Sound、Alert completionHandler(UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert); } // iOS 10: 點擊通知進入App時觸發 - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler { //角標復位 [GeTuiSdk resetBadge]; [[UIApplication sharedApplication]setApplicationIconBadgeNumber:0]; [[UIApplication sharedApplication] cancelAllLocalNotifications]; NSLog(@"didReceiveNotification:%@", response.notification.request.content.userInfo); // [ GTSdk ]:將收到的APNs信息傳給個推統計 [GeTuiSdk handleRemoteNotification:response.notification.request.content.userInfo]; completionHandler(); } #endif
//設置GeTuiSdkDelegate
注意 APP 啓動成功會返回 clientId ,咱們項目中使用clientId進行消息透傳,在登陸的時候將clientId傳給咱們本身的服務器,咱們服務器根據clientId給用戶進行推送
/** SDK啓動成功返回cid */ - (void)GeTuiSdkDidRegisterClient:(NSString *)clientId { // [4-EXT-1]: 個推SDK已註冊,返回clientId NSLog(@">>>[GeTuiSdk RegisterClient]:----%@", clientId); // 將clientId寫入本地 [USER_DEFAULT setObject:clientId forKey:kPushClientId]; } /** SDK遇到錯誤回調 */ - (void)GeTuiSdkDidOccurError:(NSError *)error { // [EXT]:個推錯誤報告,集成步驟發生的任何錯誤都在這裏通知,若是集成後,沒法正常收到消息,查看這裏的通知。 NSLog(@"\n>>[GTSdk error]:%@\n\n", [error localizedDescription]); }
/** SDK收到透傳消息回調 */
/** SDK收到透傳消息回調 */ - (void)GeTuiSdkDidReceivePayloadData:(NSData *)payloadData andTaskId:(NSString *)taskId andMsgId:(NSString *)msgId andOffLine:(BOOL)offLine fromGtAppId:(NSString *)appId { // 彙報個推自定義事件 [GeTuiSdk sendFeedbackMessage:90001 andTaskId:taskId andMsgId:msgId]; // [4]: 收到個推消息 //這裏收到透傳消息,根據本身服務器返回的格式處理 NSDictionary * jsonDict = [NSJSONSerialization JSONObjectWithData:payloadData options:NSJSONReadingMutableLeaves error:nil]; // 當app不在前臺時,接收到的推送消息offLine值均爲YES // 判斷app是不是點擊通知欄消息進行喚醒或開啓 // 若是是點擊icon圖標使得app進入前臺,則不作操做,而且同一條推送通知,此方法只執行一次 if (offLine) { // 離線消息,說明app接收推送時不在前臺 if (self.isLaunchedByNotification) { // app是經過點擊通知欄進入前臺 } else { // app是經過點擊icon進入前臺,在這裏不作操做 } } else { // app已經處於前臺,提示框提示 //調用系統震動系統聲音 AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); AudioServicesPlaySystemSound(1007); } // 控制檯打印日誌 NSString *msg = [NSString stringWithFormat:@"SDK收到透傳消息回調taskId=%@,messageId:%@,payloadMsg:%@%@", taskId, msgId, jsonDict, offLine ? @"<離線消息>" : @""]; NSLog(@"\n>>[GTSdk ReceivePayload]:%@\n\n", msg); #pragma mark--- 接收到推送後,進行提示或怎樣 }
/** SDK收到sendMessage消息回調 */ - (void)GeTuiSdkDidSendMessage:(NSString *)messageId result:(int)result { // 發送上行消息結果反饋 NSString *msg = [NSString stringWithFormat:@"sendmessage=%@,result=%d", messageId, result]; NSLog(@"\n>>[GTSdk DidSendMessage]:%@\n\n", msg); } /** SDK運行狀態通知 */ - (void)GeTuiSDkDidNotifySdkState:(SdkStatus)aStatus { // 通知SDK運行狀態 NSLog(@"\n>>[GTSdk SdkState]:%u\n\n", aStatus); }
#pragma mark ---application - (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings { NSLog(@"推送的內容:%@",notificationSettings); [application registerForRemoteNotifications]; }
注意: app 運行在後臺時並不會走 APNS 推送,由個推服務器推送,咱們要讓 app在後臺第一時間讓個推 SDK 斷線,先用 APNS 推送, app 進入前臺從新激活 SDK, 若是由個推服務器推送 app 能夠收到透傳的消息,但不會在通知欄提示.
- (void)applicationDidEnterBackground:(UIApplication *)application { ///切後臺關閉SDK,讓SDK第一時間斷線,讓個推先用APN推送 [GeTuiSdk destroy]; } - (void)applicationWillEnterForeground:(UIApplication *)application { //設置角標爲0 至關於復位 [GeTuiSdk setBadge:0]; [[UIApplication sharedApplication]setApplicationIconBadgeNumber:0];//進入前臺取消應用消息圖標搜索 [[UIApplication sharedApplication] cancelAllLocalNotifications]; } - (void)applicationDidBecomeActive:(UIApplication *)application { [DeviceDelegateHelper sharedInstance].preDate = [NSDate date]; /// 從新上線 [self startSdkWith:kGtAppId appKey:kGtAppKey appSecret:kGtAppSecret]; }
關於推送開關的設置,我這裏使用單例類屬性接收,
//SDK設置推送模式回調 - (void)GeTuiSdkDidSetPushMode:(BOOL)isModeOff error:(NSError *)error { if (error) { NSLog(@"\n>>[GTSdk SetModeOff Error]:%@\n\n", [error localizedDescription]); return; } NSLog(@"---ss-%d____",isModeOff); NSLog(@"\n>>[GTSdk SetModeOff]:%@\n\n----", isModeOff ? @"開啓" : @"關閉"); [GlobalData shareIntance].isMessagePush = isModeOff; }
在須要設置 UISwitch 開關的地方來設置
[pushBtn setOn:[DemoGlobalClass sharedInstance].isMessageShake];
- (void)getValue:(UISwitch*)sender { [GlobalData shareIntance].isMessagePush = sender.isOn; NSLog(@"-----%d__--",!sender.isOn); //發送開關結果告訴個推服務器 [GeTuiSdk setPushModeForOff:!sender.isOn]; }
角標的處理,其實個推 SDK 已經封裝好了,iOS 前端只須要把收到推送的消息個數,已讀所有通知,設置角標爲0而且發送個推服務器,若有未讀推送通知,把剩餘的通知發送給個推服務器,咱們服務器從個推服務器上獲取角標,來設置推送的消息個數,並有咱們服務器發送透傳消息過來.
//設置角標爲0 至關於復位 [GeTuiSdk setBadge:0]; [[UIApplication sharedApplication]setApplicationIconBadgeNumber:0];//進入前臺取消應用消息圖標搜索 [[UIApplication sharedApplication] cancelAllLocalNotifications];