天天看點

百度推送ios

一.百度雲推送

目前免費(cocoapod不支援)

1.效果圖:

如果程式在背景(首頁面tab在第一個),收到通知後的效果 【操作流程:點選鮮花通知-點選傳回】

百度推送ios

Paste_Image.png

如果程式預設是開啟狀态,效果圖如下:【操作流程:點選立即前往-點選傳回】

百度推送ios

Paste_Image.png

2.如何加載第三方庫,參考官網文檔

基本原理圖:

百度推送ios

Paste_Image.png

其實蘋果用的是deviceToken,我們在如下接口擷取到deviceToken後 - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken

注冊到百度雲庫裡面,百度雲會傳回一個對應token的userid(之後就是以這個做裝置識别)。也就是百度雲對應的 getChannelId,appd用戶端擷取後,發送到appServer既可(該值我們是和賬号綁定的,是以背景要設定綁定關系),這樣appServer就可以通過這個id來推送消息了(群發的不需要id)。

2.建立好應用後,關鍵是如下制作證書上傳

具體參照如下:蘋果push證書制作全過程(含測試過程)

二.實作(工程和代碼相關設定)

1.工程設定

百度推送ios

Paste_Image.png

百度推送ios

Paste_Image.png

百度雲SDK

百度推送ios

Paste_Image.png

2.代碼設定

頭檔案設定

//  AppDelegate.m
#import "BPush.h"
#ifdef NSFoundationVersionNumber_iOS_9_x_Max
#import <UserNotifications/UserNotifications.h>
#endif

static BOOL isBackGroundActivateApplication;
           

第一步:程式啟動接口 綁定api key(百度 無賬号登入體系)

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//初始化百度推送元件
    [self startBaiDuPush:launchOptions];
    return YES;
}

- (void)startBaiDuPush:(NSDictionary *)launchOptions
{
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 10.0) {
#ifdef NSFoundationVersionNumber_iOS_9_x_Max
        UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];

        [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert + UNAuthorizationOptionSound + UNAuthorizationOptionBadge)
                              completionHandler:^(BOOL granted, NSError * _Nullable error) {
                                  // Enable or disable features based on authorization.
                                  if (granted) {
                                      [[UIApplication sharedApplication] registerForRemoteNotifications];
                                  }
                              }];
#endif
    }
    else if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
        UIUserNotificationType myTypes = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;

        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:myTypes categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
    }else {
        UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeSound;
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:myTypes];
    }

    //#warning 測試 開發環境 時需要修改BPushMode為BPushModeDevelopment 需要修改Apikey為自己的Apikey
    BPushMode pMode =  BPushModeDevelopment;
#ifdef HuBPushModeProduction_ON
    pMode = BPushModeProduction;
#endif
    NSString *key = Baidu_PUSH_API_KEY;
    [BPush registerChannel:launchOptions apiKey:key pushMode:pMode withFirstAction:@"打開" withSecondAction:@"回複" withCategory:@"test" useBehaviorTextInput:YES isDebug:YES];

    // 禁用地理位置推送 需要再綁定接口前調用。
    [BPush disableLbs];

    // App 是使用者點選推送消息啟動
    NSDictionary *userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
    if (userInfo) {
        [BPush handleNotification:userInfo];
    }
    //角标清0  角标結合我們自己的邏輯不能清空
//    [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
}

// 在 iOS8 系統中,還需要添加這個方法。通過新的 API 注冊推送服務
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
    [application registerForRemoteNotifications];
}
           

第二步:将蘋果傳回的deviceToken,注冊如百度庫,接着綁定,之後都用channel_id 替代deviceToken

//擷取手機唯一标示  消息中心push 主推想
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    [BPush registerDeviceToken:deviceToken];
    //綁定
    [BPush bindChannelWithCompleteHandler:^(id result, NSError *error) {
        if (error) return ;
        if (result) {
            // 确認綁定成功
            if ([result[@"error_code"]intValue]!=0) {
                return;
            }
            // 擷取channel_id
            NSString *BaiDu_Channel_id = [BPush getChannelId];

            [[NSUserDefaults standardUserDefaults]setObject:BaiDu_Channel_id forKey:@"BaiDu_Channel_id"];
        }
    }];
}

// 當 DeviceToken 擷取失敗時,系統會回調此方法
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
    NSLog(@"DeviceToken 擷取失敗,原因:%@",error);
}
           

第三步:處理通知接口

// ios7後的新接口, 此方法是 使用者點選了通知,應用在前台 或者開啟背景并且應用在背景 時調起
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    // App 收到推送的通知
    [BPush handleNotification:userInfo];
    _ps_Type=[userInfo[@"psType"] intValue];//自定義type消息(和背景約定)
    NSString *message = userInfo[@"aps"][@"alert"];

    completionHandler(UIBackgroundFetchResultNewData);

    // 應用在前台,不跳轉頁面,讓使用者選擇。
    if (application.applicationState == UIApplicationStateActive) {
        [self showAlertView:message];
    }
//    殺死狀态下,直接跳轉到需要添置跳轉頁面。
    if (application.applicationState == UIApplicationStateInactive && !isBackGroundActivateApplication)
    {
        [self dealPushMessage:_ps_Type];
    }
    // 應用在背景。當背景設定aps字段裡的 content-available 值為 1 并開啟遠端通知激活應用的選項
    if (application.applicationState == UIApplicationStateBackground) {
        // 此處可以選擇激活應用提前下載下傳郵件圖檔等内容。
        isBackGroundActivateApplication = YES;
        [self showAlertView:message];
    }
}
           

3.1添加個人處理相關個性化頁面

- (void)showAlertView:(NSString *)message
{
    UIAlertView *alertView =[[UIAlertView alloc]initWithTitle:@"消息提醒" message:message delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"立即前往", nil];
    [alertView show];
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 1) {
        [self dealPushMessage:_ps_Type];
    }
}

//程式主界面首頁底部menutar類型
typedef NS_ENUM(NSInteger, HuMainPageMenuBarType) {
    HuMainPageMenuBarTypeWardPatient  = 1,//病區患者
    HuMainPageMenuBarTypeEducationClass  = 2,//宣教課程
    HuMainPageMenuBarTypePersonalCenter  = 3,//個人中心
};
- (void)dealPushMessage:(HuMessagePushType)pushType
{
    if (![HuConfigration loginStatus]) {
        loginViewController * loginVC = [[loginViewController alloc] init];
        [[[UIApplication sharedApplication] delegate] window].rootViewController = loginVC;
    }
    else
    {
        switch (pushType) {
            case HuMessagePushTypeMain:
            {
                [self goToMainPage:HuMainPageMenuBarTypeWardPatient];
            }
                break;
           case HuMessagePushTypeDonateFlowerMessage:
            {
                [self gotoViewControllerStr:@"FlowerMessViewController" WithMenuBar:HuMainPageMenuBarTypePersonalCenter];
            }
                break;
            case HuMessagePushTypeSystemMessage:
            {
                [kNotificationCenter postNotificationName:kNotificationRed object:nil];
                [self gotoViewControllerStr:@"SystemMessagesViewController" WithMenuBar:HuMainPageMenuBarTypePersonalCenter];
            }
                break;

            default:
                break;
        }

    }
}

- (void)gotoViewControllerStr:(NSString*)vcStr WithMenuBar:(HuMainPageMenuBarType)type
{
    [self goToMainPage:type];
    NSInteger i = type - 1;
      //選擇對應的控制器數組,在将其push進入
    UINavigationController *nav = [[_customVc childViewControllers] objectAtIndex:i];
    UIViewController *vc = [[NSClassFromString(vcStr) alloc] init];
    [nav pushViewController:vc animated:YES];
    [_customVc hiddenTabBar];

}

- (void)goToMainPage:(HuMainPageMenuBarType)type
{
    if (!_customVc)
    {
        CustomMyViewController *custom = [[CustomMyViewController alloc]init];
        custom.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
        _window.rootViewController = custom;
        _customVc = custom;
    }
    if(type >= HuMainPageMenuBarTypeWardPatient  && type <= HuMainPageMenuBarTypePersonalCenter){
          //将首頁底部點選下班設定正确
        [_customVc tabMenuBarWithType:type];
    }
}
           

第四步.如果擷取的channel_id,需要跟對應的賬号綁定,我們就需要程式賬号登入後,告訴背景appServer綁定關系。之後推送相關都從背景appServer發起。

程式程式之後主界面 綁定下就可以

- (void)viewDidLoad
{
   [self bindChannelIdWithAccount];
}

- (void)bindChannelIdWithAccount
{
    NSString *BaiDu_Channel_id = [[NSUserDefaults standardUserDefaults]objectForKey:@"BaiDu_Channel_id"];
    NSDictionary *param = @{@"deviceChannelId":BaiDu_Channel_id};

    NSString *url=[NSString stringWithFormat:@"%@/api/testModle/bindDevice",quanQaunURL];
    [QQRequest post:url param:param view:nil success:^(NSDictionary *dic) {
    } error:nil failure:nil];
}
           

三.其他

1.請求Push 常見錯誤碼

BPushErrorCode_Success = 0,

BPushErrorCode_MethodTooOften = 22, // 調用過于頻繁

BPushErrorCode_NetworkInvalible = 10002, // 網絡連接配接問題

BPushErrorCode_InternalError = 30600, // 伺服器内部錯誤

BPushErrorCode_MethodNodAllowed = 30601, // 請求方法不允許

BPushErrorCode_ParamsNotValid = 30602, // 請求參數錯誤

BPushErrorCode_AuthenFailed = 30603, // 權限驗證失敗

BPushErrorCode_DataNotFound = 30605, // 請求資料不存在

BPushErrorCode_RequestExpired = 30606, // 請求時間戳驗證逾時

BPushErrorCode_BindNotExists = 30608, // 綁定關系不存在

2.目前暫時沒用到(以後可能會設計,給特點标簽的裝置推送消息)

标簽多點傳播:推送給打上某一個标簽的一組裝置。為iOS裝置打标簽需要通過調用iOS用戶端SDK中的setTags方法來設定所屬的Tag 每個應用最多可以定義10000個标簽;每個标簽對應的裝置數沒有限制

3.背景推送參數添加content-available: 1 (靜默推送)【暫時也沒用】

4.ios9新特性 【 暫時也沒用】

百度推送ios

Paste_Image.png

5.ios10富文本消息 【暫時也沒用】

百度推送ios

Paste_Image.png

2016年11月16日

一.百度雲推送測試流程總結

第一步:登入如下賬号(百度雲網站部署狀态改變,不會影響生産的<生産上客服推送是另一套機制推送>,代碼推送狀态修改就會有影響了)

http://push.baidu.com/

百度推送ios

Paste_Image.png

二.代碼斷點調試 擷取百度傳回的 BaiDu_Channel_id

百度推送ios

Paste_Image.png

三.一般指定裝置id 推送消息

百度推送ios

Paste_Image.png

正常現象:

百度推送ios

Paste_Image.png

ps:

注意測試的時候appid一定要選對

百度推送ios

Paste_Image.png

百度推送ios

作者:wangyu2488

連結:https://www.jianshu.com/p/d4f2ae6e4de3

來源:簡書

簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權并注明出處。