通常來說項(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];
}