推送服务可以说是所有 App 的标配,不论是哪种类型的 App,推送都从很大程度上决定了 App 的 打开率、使用率、存活率 。因此,熟知并掌握推送原理及方法,对每一个开发者来说都是必备技能,对每一个依赖 App 的公司来说都至关重要。本文主要讨论项目中使用极光推送来实现推送业务。
自己做推送从开发成本上来说需要专人进行开发,并且需要一定数量的服务器和带宽支持,在开发完成后的使用过程中还需要有专人进行维护。 但是如果使用第三方,你只需要集成SDK就可以实现功能,不仅减小了开发成本与维护成本,甚至在推送稳定性上第三方也会比自己做的推送更好一些。第三方推送目前开始尝试精准推送,说白了就是将不同的内容推送给不同的人群,比如将北京的新闻推送给北京的用户。 现在做第三方推送的服务提供商有百度云推送、友盟推送、极光推送等,各有各的优势,但是实现底层都差不多。因此除非公司特别大,特别有实力,不然使用第三方推送服务提供商要远比自己开发好的多。
// 引 JPush功能所需头 件
#import "JPUSHService.h"
// iOS10注册APNs所需头 件
#ifdef NSFoundationVersionNumber_iOS_9_x_Max
#import <UserNotifications/UserNotifications.h>
#endif
<JPUSHRegisterDelegate>
- (void)appSetForLaunchOptions :(NSDictionary *)launchOptions
{
//*******************************************************************
// Required
// notice: 3.0.0及以后版本注册可以这样写,也可以继续 旧的注册 式
JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init];
entity.types = JPAuthorizationOptionAlert|JPAuthorizationOptionBadge|JPAuthorizationOptionSound;
if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
// 可以添加 定义categories
// NSSet<UNNotificationCategory *> *categories for iOS10 or later
// NSSet<UIUserNotificationCategory *> *categories for iOS8 and iOS9
}
[JPUSHService registerForRemoteNotificationConfig:entity delegate:self];
// Required
// init Push
// notice: 2.1.5版本的SDK新增的注册 法,改成可上报IDFA,如果没有使 IDFA直接传nil
// 如需继续使 pushConfig.plist 件声明appKey等配置内容,请依旧使 [JPUSHService setupWithOption:launchOptions] 式初始化。
[JPUSHService setupWithOption:launchOptions
appKey:@"a8731XXXXXXXXXXXXXXXX"
channel:@"App Store"
apsForProduction:0
advertisingIdentifier:nil];
[JPUSHService registrationIDCompletionHandler:^(int resCode, NSString *registrationID) {
if(resCode == 0){
NSLog(@"registrationID获取成功:%@",registrationID);
[[MethodTool shareTool]setUserDefaults:registrationID :@"registrationID"];
}
else{
NSLog(@"registrationID获取失败,code:%d",resCode);
}
}];
//*******************************************************************
}
// 调用
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self appSetForLaunchOptions:launchOptions];
}
#pragma mark ----------------------推送注册结果返回--------------
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
/// Required - 注册 DeviceToken
[JPUSHService registerDeviceToken:deviceToken];
}
-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
//Optional
NSLog(@"did Fail To Register For Remote Notifications With Error: %@", error);
}
这个系统级别的方法,被触发的条件:
//ios 7 前端 、点击、静默式推送有 包括iOS10的静默式推送
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
NSLog(@"fetchCompletionHandler: /n %@",userInfo);
[[MethodTool shareTool]setUserDefaults:@"推送后台" :@"tuisong" ];
// Required, iOS 7 Support
[JPUSHService handleRemoteNotification:userInfo];
completionHandler(UIBackgroundFetchResultNewData);
[JPUSHService setBadge:0];//清空JPush服务器中存储的badge值。
[self getMessageDetail:[[MethodTool shareTool]cleanData:userInfo[@"fid"]]];
}
这个方法可以不用实现
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
// Required,For systems with less than or equal to iOS6
NSLog(@"didReceiveRemoteNotification: /n %@",userInfo);
[JPUSHService handleRemoteNotification:userInfo];
}
这个方法是推送横幅出现之前会被调用
// iOS 10 Support
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger)
)completionHandler {
// Required
NSDictionary * userInfo = notification.request.content.userInfo;
NSLog(@"111111 didReceiveNotificationResponse: /n %@",userInfo);
if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]
]) {
[JPUSHService handleRemoteNotification:userInfo];
}
completionHandler(UNNotificationPresentationOptionAlert);
}
这个方法被触发的条件:
// iOS 10 Support
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)
())completionHandler {
// Required
NSDictionary * userInfo = response.notification.request.content.userInfo;
if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
[JPUSHService handleRemoteNotification:userInfo];
}
completionHandler(); // 系统要求执 这个 法
[JPUSHService setBadge:0];//清空JPush服务器中存储的badge值。
[self getMessageDetail:[[MethodTool shareTool]cleanData:userInfo[@"fid"]]];
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
}
APP收到的推送信息 { "_j_business" = 1; "_j_msgid" = 36028797200845676; "_j_uid" = 6126767282; aps = { alert = "\U6d4b\U8bd5"; badge = 1; sound = default; }; fid = 1; }
静默式推送
Paste_Image.png
image.png
彻底杀掉程序,点击通知进入应用会加载 application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 然后才会加载通知的点击事件。
消息推送,有时候只想推送给指定的人或者指定的版本,那么这时候我们就需要对设备设置标签或者别名了,这样推送的时候可以根据标签或者别名推送给指定的用户
//设置极光标签
[JPUSHService setTags:[NSSet setWithObject:@"yk"]callbackSelector:@selector(tagsAliasCallback:tags:alias:) object:self];
//设置标签的回调
- (void)tagsAliasCallback:(int)iResCode
tags:(NSSet *)tags
alias:(NSString *)alias {
NSLog(@"TagsAlias回调:%d", iResCode);
// 0 的时候是设置成功了。
}
在实际的产品和运营中经常是使用组合技巧: Push,短信,微信推送组合协同,提高效率。可以在服务端来统计分析用户行为,然后将指定的 tags 发送至手机,手机接收后再为用户打上对应的 tags。这样就可以做到定向产品推广了。