ios 個推推送集成


個推推送總結:

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

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

一.推送的流程

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

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

  app 在收到推送消息時分為三種情況

1.app 在前台接收到通知

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

2.app 在后台接收到通知

點擊通知欄使APP進入前台后,直接跳轉頁面

點擊icon圖標使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];

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM