ios 個推推送集成

個推推送總結:

個推第三方平臺官網地址:http://www.getui.com/cn/index.htmlhtml

首先去官網註冊帳號,建立應用,應用的配置信息,建立APNs推送證書上傳 P12證書(開發對應開發證書,上線對應生產證書)包括導入 SDK 添加依賴庫...這些繁瑣的事請移步個推官網查看 xcode 集成教程.前端

一.推送的流程

個推 iOS 推送服務框架以下圖所示:ios

  • 綠色部分是 APNs 推送,個推平臺替開發者的應用經過蘋果 APNs 服務器向指定的目標設備進行推送。由 APNs Server 將通知推送到相應的 iOS 設備上。
  • 紅色部分是個推應用內推送部分,即 App 啓動時,應用內集成的個推SDK會開啓長鏈接到個推服務器,從而開發者可經過個推服務器推送消息到 App 裏,這條鏈路性能和穩定性更強,是APNs的一個很重要的補充。

  app 在收到推送消息時分爲三種狀況

1.app 在前臺接收到通知web

APP接收到推送後推送後首先彈出一個Alert提示是否跳轉頁面json

2.app 在後臺接收到通知xcode

點擊通知欄使APP進入前臺後,直接跳轉頁面服務器

點擊icon圖標使APP進入前臺後,不做操做app

3.app 處於關閉狀態接收到通知框架

點擊通知欄啓動APP,直接跳轉頁面性能

點擊icon圖標啓動APP,不做操做

 

二.iOS 集成個推只支持透傳消息(透傳消息而且支持安卓)

 

三.集成個推官網 SDK 配置AppID,AppKey,AppSecret

首先爲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];
 
}

五.關於iOS icon 角標顯示

角標的處理,其實個推 SDK 已經封裝好了,iOS 前端只須要把收到推送的消息個數,已讀所有通知,設置角標爲0而且發送個推服務器,若有未讀推送通知,把剩餘的通知發送給個推服務器,咱們服務器從個推服務器上獲取角標,來設置推送的消息個數,並有咱們服務器發送透傳消息過來.

 //設置角標爲0 至關於復位
    [GeTuiSdk setBadge:0];
    [[UIApplication sharedApplication]setApplicationIconBadgeNumber:0];//進入前臺取消應用消息圖標搜索
    [[UIApplication sharedApplication] cancelAllLocalNotifications];
相關文章
相關標籤/搜索