有些时候需要用到苹果原生的消息推送,最近整理了一下
准备工作
- 下载推送测试程序SmartPush ,并用xcode 运行安装
- 创建工程对应的推送证书,一个是
Apple Push Notification service SSL (Sandbox)
和Apple Push Notification service SSL (Sandbox & Production)
,前者只能给开发者用Xcode安装的app推送,后者可以给所有app推送
开发
- 获取权限并申请device token
- (void)notification:(UIApplication *)application{
//iOS 10 later
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
// 获取权限
[center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (!error && granted) {
//用户点击允许
NSLog(@"用户点击允许推送");
}else{
//
NSLog(@"用户点击不允许推送");
}
}];
// 可以通过 getNotificationSettingsWithCompletionHandler 获取权限设置
//之前注册推送服务,用户点击了同意还是不同意,以及用户之后又做了怎样的更改我们都无从得知,现在 apple 开放了这个 API,我们可以直接获取到用户的设定信息了。注意UNNotificationSettings是只读对象哦,不能直接修改!
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
NSLog(@"settings:%@",settings);
//打印结果 ========<UNNotificationSettings: 0x1740887f0; authorizationStatus: Authorized, notificationCenterSetting: Enabled, soundSetting: Enabled, badgeSetting: Enabled, lockScreenSetting: Enabled, alertSetting: NotSupported, carPlaySetting: Enabled, alertStyle: Banner>
}];
//注册远端消息通知获取device token
[application registerForRemoteNotifications];
}
2.接收device token 将device token 转为字符串可以传给服务器
/// 远程推送注册成功
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 13) {
if (![deviceToken isKindOfClass:[NSData class]]) {
//记录获取token失败的描述
return;
}
const unsigned *tokenBytes = (const unsigned *)[deviceToken bytes];
NSString *strToken = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x",
ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];
NSLog(@"deviceToken1:%@", strToken);
return;
} else {
NSString *token = [NSString
stringWithFormat:@"%@",deviceToken];
token = [token stringByReplacingOccurrencesOfString:@"<" withString:@""];
token = [token stringByReplacingOccurrencesOfString:@">" withString:@""];
token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
NSLog(@"deviceToken2 is: %@", token);
}
}
///注册失败
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
NSLog(@"注册失败 ---- %@",error);
}
3.收到推送
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler{
NSLog(@"%@",userInfo);
[[NSUserDefaults standardUserDefaults] setObject:userInfo forKey:@"notify"];
completionHandler(UIBackgroundFetchResultNewData);
}
4.点击推送
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler __API_AVAILABLE(macos(10.14), ios(10.0), watchos(3.0)) __API_UNAVAILABLE(tvos){
NSLog(@"%s",__func__);
completionHandler();
}
静默推送 slient push
{
"aps" : {
"content-available" : 1
},
"parame1" : "value1",
"parame2" : value2
}
如果不携带任何badge,sound 和消息内容等参数用户就感知不到,可以后台静默的干一些事情,用户感知不到但是整个过程只有30s