iOS極光推送封裝

通常來說項(xiàng)目中的推送功能一般是使用第三方來實(shí)現(xiàn)轻抱,可以極大的降低開發(fā)時間及成本祈搜,下面就簡單介紹下關(guān)于極光推送的一個簡易封裝使用

集成步驟及使用注意點(diǎn)

/*  遠(yuǎn)程推送集成指南 (使用極光SDK)
 
 1、準(zhǔn)備生產(chǎn)泽西、開發(fā)環(huán)境.p12文件  http://docs.jpush.io/client/ios_tutorials/#ios_1
 
 2缰趋、下載需要集成SDK    http://docs.jpush.io/resources/#sdk
 
 2.1 下載 JPush-iOS-SDK 秘血,得到一個lib 和一個Demo,將lib 導(dǎo)入項(xiàng)目中仔涩;
 libz.tbd  ---》 注:Xcode7需要的是libz.tbd粘舟;Xcode7以下版本是libz.dylib
 2.2 同時創(chuàng)建并配置PushConfig.plist文件在 SDK目錄下
 2.2 注冊帳號:https://www.jpush.cn柑肴;
 2.3 添加應(yīng)用名,上傳對應(yīng)環(huán)境的.p12文件适秩;此步完成后得到一對字符串 AppKey 和 MasterSecret秽荞;
 
 3抚官、在 AppDelegate.m 中復(fù)制如下代碼:

------AppDelegate.m 的調(diào)用示例------------------------------------------------------------
 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
 
 //配置推送
 [ZQPushManager configurePushWithOptions:launchOptions];
 
 return YES;
 }
 - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
 {
 [ZQPushManager registerDeviceToken:deviceToken];
 }
 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
 {
 [ZQPushManager handleRemoteNotification:userInfo];
 }
 -(void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler
 {
 [ZQPushManager handleRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
 }
 
 - (void)application:(UIApplication *)application didReceiveLocalNotification:(nonnull UILocalNotification *)notification
 {
 [ZQPushManager handleLocalNotificationForRemotePush:notification];
 }
 - (void)applicationWillEnterForeground:(UIApplication *)application {
 [ZQPushManager configurePushWithOptions:nil];
 }
 - (void)applicationWillResignActive:(UIApplication *)application {
 [ZQPushManager sharedManager].justInBack = YES;
 }
 ------AppDelegate.m 的調(diào)用完成---------------------------------------------------------- 

 4胁住、打包給測試開發(fā)刊咳、生產(chǎn)環(huán)境,發(fā)布appstore配置余指;
    測試地址包:端口地址為測試環(huán)境酵镜,證書使用開發(fā)證書,測試手機(jī)直接連接電腦安裝垢粮;
    正式地址包(避免線上正式用戶收到):端口地址為正式環(huán)境靠粪,證書使用生產(chǎn)證書,測試手機(jī)用ad-hoc包安裝昔善;
    發(fā)布appstore:端口地址為正式君仆,證書使用生產(chǎn)證書牲距,發(fā)布;
 
 4.1 PushConfig.plist配置說明洛姑;
    APS_FOR_PRODUCTION (備用參數(shù),暫時不需要配置):0表示開發(fā)證書参咙,1表示生產(chǎn)證書;
    CHANNEL(不需要配置):在工程 - TARGETS - BuildSetting - SearchPaths - User Header Search Paths
            添加PushConfig.plist在工程中的相對路徑(列如:$(SRCROOT)/plugIn/JPush/PushConfig.Plist择同,plugIn敲才、JPush為文件夾))
    APP_KEY:配置為極光開發(fā)或者生產(chǎn)AppKey择葡;
    
    注意:極光目前通過同一個賬號來區(qū)分開發(fā)和生產(chǎn)環(huán)境敏储,而我們后臺是通過兩個極光賬號區(qū)別環(huán)境(測試賬號對應(yīng)極光開發(fā)環(huán)境,正式賬號對應(yīng)生產(chǎn)環(huán)境)妥箕,極光并不通過賬號來區(qū)分ios的環(huán)境。
 4.2 ZQPushManager.m里在clickRemoteNotification里配置app端口地址坎吻;
    

 5宇葱、細(xì)節(jié)注意:
     method_2 didReceiveLocalNotification
     method_1 didReceiveRemoteNotification:(NSDictionary *)userInfo
     fetchCompletionHandler:
     
     * 在iOS7.0之后,在前臺收到遠(yuǎn)程通知吗氏,或者點(diǎn)擊了后臺的通知弦讽,都會調(diào)用method_1的方法 膀哲,userInfo就是收到的通知,可根據(jù)需要做相應(yīng)的處理仿村;
     
     5.1 后臺收到的遠(yuǎn)程通知蔼囊,會自動下拉彈出衣迷,而前臺收到時,不會彈出云矫,需要單獨(dú)處理让禀,一般的做法有3種:
     5.1.1 轉(zhuǎn)化成本地通知陨界,丟到通知欄;
     5.1.2 轉(zhuǎn)化成AlertView彈出吼肥;
     5.1.3 定義一個和系統(tǒng)通知一樣的效果彈出缀皱; (PS:這個我還沒實(shí)現(xiàn) )
 
     5.2 判斷用戶是否允許通知;
     5.2 5.1.1轉(zhuǎn)換成本地通知時表箭,會調(diào)用一次method_2钮莲;點(diǎn)擊通知欄的本地通知時會再調(diào)用一次,要做區(qū)分极舔;
     5.3 未獲得通知授權(quán)時候的跳轉(zhuǎn): @"prefs:root=NOTIFICATIONS_ID&path=com.365sji.iChanl"拆魏;
     5.4 應(yīng)用內(nèi)注銷遠(yuǎn)程通知慈俯;發(fā)送一條極光指定的通知 kJPFNetworkDidCloseNotification贴膘;
     5.5 開啟和注銷之間的快速轉(zhuǎn)換:
     當(dāng)用戶前往5.2,就判斷可能重新激活通知洋闽,此時在willEnterForground重新注冊通知氛琢;
 
 */
  • 創(chuàng)建一個Nsobjct 的類 ( ZQLPushManager )

.h文件

#import <Foundation/Foundation.h>

@interface ZQLPushManager : NSObject

@property (nonatomic) BOOL justInBack;
@property (nonatomic) BOOL clickNotification;

+ (ZQLPushManager *)shareManager;

/// 配置推送
+ (void)configurePushWithOptions:(NSDictionary*)launchOptions;

///注冊token
+ (void)registerDeviceToken:(NSData *)deviceToken;

/// 操作收到的遠(yuǎn)程消息
+ (void)handleRemoteNotification:(NSDictionary*)notification;

/// 遠(yuǎn)程消息操作完成
+ (void)handleRemoteNotification:(NSDictionary*)notification fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler;

///處理遠(yuǎn)程通知轉(zhuǎn)化而來的本地通知
+ (void)handleLocalNotificationForRemotePush:(UILocalNotification*)notification;

/// 處理消息內(nèi)容
+ (void)clickRemoteNotification:(NSDictionary*)notification;

///清理角標(biāo)
+ (void)clearBadge;

///是否開啟了允許通知
+ (BOOL)isOpenRemoteNotification;

///取消注冊通知
+ (void)unregisterRemoteNotifications;

///允許/取消允許通知switch事件 on == 允許通知
+ (void)changeRemotePushState:(UISwitch*)sender;

@end

** .m文件**

#import "ZQLPushManager.h"
#import "JPUSHService.h"


@implementation ZQLPushManager

static ZQLPushManager* manager = nil;

+(ZQLPushManager *)shareManager
{
    static dispatch_once_t onceToken;
    
    dispatch_once(&onceToken, ^{
        manager = [[ZQLPushManager alloc] init];
    });
    return manager;
}
- (instancetype)init
{
    self = [super init];
    if (self) {
        
        self.justInBack = NO;
        self.clickNotification = NO;
    }
    return  self;
}

/// 配置推送
+ (void)configurePushWithOptions:(NSDictionary*)launchOptions
{
    if (![DataManager sharedManager].allowRemotePush){ // 如果用戶不允許通知
        return;
    }else{
        // 注冊
        [self registerRemoteNotification];
        
        [DataManager sharedManager].remotePushStateMaybeChange = NO;
    }
    
    // 初始化
    [JPUSHService setupWithOption:launchOptions];
    
    // 設(shè)置tag和標(biāo)簽
    //    [self setTagsAndAlias];
    
    // 如果通過點(diǎn)擊推送通知啟動應(yīng)用
    if (launchOptions != nil) {
        NSDictionary *dictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
        if (dictionary != nil) {
            [self clickRemoteNotification:dictionary];
            
            [self clearBadge];
        }
    }
}
/// 注冊遠(yuǎn)程通知
+ (void)registerRemoteNotification
{
    // Required
    if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
        //可以添加自定義categories
        [JPUSHService registerForRemoteNotificationTypes:(UIUserNotificationTypeBadge |
                                                       UIUserNotificationTypeSound |
                                                       UIUserNotificationTypeAlert)
                                           categories:nil];
    } else {
        //categories 必須為nil
        [JPUSHService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
                                                       UIRemoteNotificationTypeSound |
                                                       UIRemoteNotificationTypeAlert)
                                           categories:nil];
    }
}
///在前臺和狀態(tài)欄收到遠(yuǎn)程消息
+(void)handleRemoteNotification:(NSDictionary*)notification fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler
{
    [ZQLPushManager handleRemoteNotification:notification];
    
    //獲取通知的標(biāo)題和描述
    NSString* messageTitle = [[notification objectForKey:@"aps"]objectForKey:@"alert"];
    NSString* description = [notification objectForKey:@"videoDesc"];
    // 應(yīng)用從后臺點(diǎn)擊消息進(jìn)入
    if ([UIApplication sharedApplication].applicationState == UIApplicationStateInactive && ([ZQLPushManager shareManager].justInBack)){
        [ZQLPushManager clickRemoteNotification:notification];
        
    }else{ //正在通知欄或前臺
        
        UILocalNotification *localNotification = [[UILocalNotification alloc] init];
        localNotification.userInfo = notification;
        localNotification.soundName = UILocalNotificationDefaultSoundName;
        localNotification.alertBody = description;
        [ZQLPushManager shareManager].clickNotification = NO;
        [[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
        
        // 應(yīng)用正在前臺
        if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive) {
#warning 后續(xù)自定義通知效果撮奏,仿原生畜吊;
            //  如果當(dāng)前控制器不是視頻播放控制器
            //  if (![DataManager sharedManager].isMovieDetailVC) {
            kSelfWeak;
            UIAlertView* alert = [UIAlertView alertViewWithTitle:messageTitle message:description cancelButtonTitle:@"取消" otherButtonTitles:@[@"前往"] onDismiss:^(NSInteger buttonIndex, NSString *buttonTitle) {
                if ([buttonTitle isEqualToString:@"前往"]) {
                    [weakSelf clickRemoteNotification:notification];
                }
            } onCancel:^{
                [weakSelf clearBadge];
            }];
            
            [alert show];
        }
        // }
    }
    completionHandler(UIBackgroundFetchResultNewData);
}
///處理遠(yuǎn)程通知轉(zhuǎn)化而來的本地通知
+ (void)handleLocalNotificationForRemotePush:(UILocalNotification*)notification
{
    if ([UIApplication sharedApplication].applicationState == UIApplicationStateInactive&&[ZQLPushManager shareManager].justInBack)
    { // 如果用戶點(diǎn)擊通知進(jìn)入
        [ZQLPushManager clickRemoteNotification:notification.userInfo];
    }
    [ZQLPushManager shareManager].clickNotification = YES;
}
/// 處理消息
+ (void)clickRemoteNotification:(NSDictionary*)notification
{
    [ZQLPushManager shareManager].justInBack = NO;
    [self clearBadge];
    
    NSString* videoType = [notification objectForKey:@"videoType"];
    NSString* videoTypeValue = [notification objectForKey:@"videoTypeValue"];
    
    UIViewController* destinationVC = nil;
    
    // 如果是通過messageId跳轉(zhuǎn)
    if ([[NSString stringBySpaceTrim:videoTypeValue] isEqualToString:@""]) {
        
        NSString* messageId = [notification objectForKey:@"messageId"];
        NSString* contentStr = isTrueEnvironment ? @"view/messageDetails.html?newsId=" : @"daziboApp/view/messageDetails.html?newsId=";
        NSString* urlStr = [NSString stringWithFormat:@"%@://%@/%@%@",kHttpHead,kServerResourceHost, contentStr,messageId];
        NSLog(@"**************%@",urlStr);
        
//        destinationVC = [[XYWebVC alloc] initWithURLString:urlStr];
//        destinationVC.navigationItem.title = @"消息";
        
    }else if ([videoType isEqualToString:@"1"]) { //如果是視頻ID
        //        destinationVC = [[MovieDetialVC alloc] initWithVideoId:videoTypeValue];
        
        
    }else if ([videoType isEqualToString:@"2"]){ //如果是視頻網(wǎng)址
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:videoTypeValue]];
        //        destinationVC = [[XYWebVC alloc] initWithURLString:videoTypeValue];
    }else{
        return;
    }
    
    id rootVC = [[UIApplication sharedApplication] keyWindow].rootViewController;
    
    if ([rootVC isKindOfClass:[CLNavigationController class]]) {
        CLNavigationController * navc = (CLNavigationController *)rootVC;
        [navc pushViewController:destinationVC animated:YES];
    }else{
        [rootVC presentViewController:destinationVC animated:YES completion:^{
        }];
    }
}
///清除角標(biāo)
+ (void)clearBadge
{
    [JPUSHService resetBadge];
    [UIApplication sharedApplication].applicationIconBadgeNumber = 1;
    [UIApplication sharedApplication].applicationIconBadgeNumber = 0;
}
/// 設(shè)置tag和標(biāo)簽
+ (void)setTagsAndAlias
{
    [JPUSHService setAlias:@"159" callbackSelector:nil object:nil];
    [JPUSHService setTags:[NSSet set] callbackSelector:nil object:nil];
    [JPUSHService setTags:[NSSet set] alias:nil callbackSelector:nil target:nil];
}
+ (BOOL)isOpenRemoteNotification
{
    BOOL isOpenNotification;
    if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
        isOpenNotification = !([[UIApplication sharedApplication]currentUserNotificationSettings].types == 0) ;
        
    } else {
        isOpenNotification = !([[UIApplication sharedApplication]enabledRemoteNotificationTypes] == UIRemoteNotificationTypeNone);
    }
    return isOpenNotification;
}
+ (void)unregisterRemoteNotifications
{
    [[UIApplication sharedApplication] unregisterForRemoteNotifications];
    [[NSNotificationCenter defaultCenter] postNotificationName:kJPFNetworkDidCloseNotification object:nil];
}
+ (void)changeRemotePushState:(UISwitch*)sender
{
    if (!sender.on){ //關(guān)閉通知
        [ZQLPushManager unregisterRemoteNotifications];
    }else{ // 打開通知
        
        // 先檢查用戶在手機(jī)設(shè)置中是否打開了小自播通知
        
        // 如果未打開,提示用戶打開
        if (![ZQLPushManager isOpenRemoteNotification]) {
            UIAlertView* alert = [UIAlertView alertViewWithTitle:@"提示" message:@"請?jiān)?設(shè)置 - 通知 中找到iChanl應(yīng)用瓢娜,\n勾選允許通知" cancelButtonTitle:@"取消" otherButtonTitles:@[@"確定"] onDismiss:^(NSInteger buttonIndex, NSString *buttonTitle) {
                [DataManager sharedManager].remotePushStateMaybeChange = YES;
                [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"prefs:root=NOTIFICATIONS_ID&path=com.365sji.iChanl"]];
                
            } onCancel:^{
                sender.on = NO;
                [DataManager sharedManager].allowRemotePush = sender.on;
            }];
            [alert show];
            
        }else{ //如果已打開礼预,馬上注冊推送通知
            [ZQLPushManager configurePushWithOptions:nil];
        }
        [DataManager sharedManager].allowRemotePush = sender.on;
    }
}

/*   調(diào)用極光API   */
+ (void)registerDeviceToken:(NSData *)deviceToken
{
    [JPUSHService registerDeviceToken:deviceToken];
}
+ (void)handleRemoteNotification:(NSDictionary*)notification
{
    [JPUSHService handleRemoteNotification:notification];
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末褒颈,一起剝皮案震驚了整個濱河市励堡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌应结,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,946評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件币狠,死亡現(xiàn)場離奇詭異漩绵,居然都是意外死亡肛炮,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,336評論 3 399
  • 文/潘曉璐 我一進(jìn)店門碍扔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來不同,“玉大人溶耘,你說我怎么就攤上這事“傩拢” “怎么了庐扫?”我有些...
    開封第一講書人閱讀 169,716評論 0 364
  • 文/不壞的土叔 我叫張陵仗哨,是天一觀的道長厌漂。 經(jīng)常有香客問我巷挥,道長,這世上最難降的妖魔是什么雏节? 我笑而不...
    開封第一講書人閱讀 60,222評論 1 300
  • 正文 為了忘掉前任钩乍,我火速辦了婚禮怔锌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘涝涤。我一直安慰自己岛杀,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,223評論 6 398
  • 文/花漫 我一把揭開白布糊肠。 她就那樣靜靜地躺著遗锣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪弧圆。 梳的紋絲不亂的頭發(fā)上笔咽,一...
    開封第一講書人閱讀 52,807評論 1 314
  • 那天拓轻,我揣著相機(jī)與錄音经伙,去河邊找鬼勿锅。 笑死溢十,一個胖子當(dāng)著我的面吹牛达吞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播吞鸭,決...
    沈念sama閱讀 41,235評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼覆糟,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了造虏?” 一聲冷哼從身側(cè)響起麦箍,我...
    開封第一講書人閱讀 40,189評論 0 277
  • 序言:老撾萬榮一對情侶失蹤挟裂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后话瞧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,712評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡划滋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,775評論 3 343
  • 正文 我和宋清朗相戀三年处坪,在試婚紗的時候發(fā)現(xiàn)自己被綠了架专。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,926評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡想邦,死狀恐怖丧没,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情呕童,我是刑警寧澤,帶...
    沈念sama閱讀 36,580評論 5 351
  • 正文 年R本政府宣布奸汇,位于F島的核電站往声,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏烁挟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,259評論 3 336
  • 文/蒙蒙 一柬采、第九天 我趴在偏房一處隱蔽的房頂上張望粉捻。 院中可真熱鬧,春花似錦肩刃、人聲如沸杏头。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,750評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽寓娩。三九已至,卻和暖如春棘伴,著一層夾襖步出監(jiān)牢的瞬間寞埠,已是汗流浹背仁连。 一陣腳步聲響...
    開封第一講書人閱讀 33,867評論 1 274
  • 我被黑心中介騙來泰國打工阱穗, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留帅容,地道東北人。 一個月前我還...
    沈念sama閱讀 49,368評論 3 379
  • 正文 我出身青樓遣钳,卻偏偏與公主長得像,于是被迫代替她去往敵國和親劝评。 傳聞我的和親對象是個殘疾皇子倦淀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,930評論 2 361

推薦閱讀更多精彩內(nèi)容