苹果 APNs 介绍

news/2024/11/20 9:31:33/

APNs 是 Apple 的推送通知服务,它使第三方开发人员能够向安装在 Apple 设备上的App发送消息通知。

此文主要介绍如何让App支持 APNs。

开启推送功能

App ID 支持推送

登录苹果开发者网站,进入 Certificates, Identifiers & Profiles 页面,点击侧边栏中的 Identifiers,然后在列表中找到项目对应的 App ID(即 Xcode 项目中的 Bundle Identifier),点击并进入配置编辑页面,然后选择 Push Notifications 旁边的复选框,最后点击右上的 Save(保存)按钮,结果如下图所示:
在这里插入图片描述

App 工程配置推送功能

要在App中添加推送权限,请在 Xcode 项目中启用推送通知功能。
打开 Xcode 项目,在 Project > Target > Capabilities 页面中点击红框中的加号按钮,然后选择并添加 Push Notifications,添加后的结果如图中黄框所示:
在这里插入图片描述
在这里插入图片描述

App 代码设置流程

客户端App基本流程

  1. 注册通知;
  2. 向苹果APNs服务请求deviceToken;
  3. 把拿到的deviceToken发给消息推送服务器;(三方的or自己的)
  4. 处理通知相关回调方法;

关于deviceToken

  1. 同手机不同App, deviceToken不同;
  2. 同一个App删除, 重新安装deviceToken会变化;
    (以上结论由实测验证得出)

注册通知

App Code


Podfile
pod 'LeanCloudObjc'   # 集成所有服务模块#import <UserNotifications/UserNotifications.h>
#import <LeanCloudObjc/Foundation.h>- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {// Override point for customization after application launch./// necessary code ignore...[self setNormalPushNotification];return YES;
}#pragma mark -
#pragma mark APNs/// 初始化普通推送
- (void)setNormalPushNotification {[self initPushSrv];if (@available(iOS 10.0, *)) {[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:(UNAuthorizationOptionBadge|UNAuthorizationOptionSound|UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {NSLog(@"是否允许通知: %d", granted);}];} else {// Fallback on earlier versions}[[UIApplication sharedApplication] registerForRemoteNotifications];// ⚠️注意: 如果不设置delegate,普通推送也会走didReceiveRemoteNotificationif (@available(iOS 10.0, *)) {[[UNUserNotificationCenter currentNotificationCenter] setDelegate:self];} else {// Fallback on earlier versions}
}/// APNS注册成功,返回token
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {//** 解析token string */if (![deviceToken isKindOfClass:[NSData class]]) return;if ([self didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]) {//** 发送到自己的消息推送应用服务器(应用服务器通过 token 及证书向苹果的消息服务器发送消息) */NSLog(@"self.deviceTokenString:%@.", self.deviceTokenString);}
}/// APNS注册失败
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {NSLog(@"Error: %@", error);
}/// App在任何状态下收到静默推送
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {NSLog(@"收到静默推送: %@", userInfo);[[NSNotificationCenter defaultCenter] postNotificationName:@"Recieve" object:nil];UIApplicationState state = [UIApplication sharedApplication].applicationState;if(state == UIApplicationStateBackground) {NSLog(@"App在后台,运行5秒");}  else if (state == UIApplicationStateActive) {NSLog(@"App在前台");}// 5秒后通知系统将处于后台的App挂起(suspend)if (@available(iOS 10.0, *)) {[NSTimer scheduledTimerWithTimeInterval:5.f repeats:NO block:^(NSTimer * _Nonnull timer) {completionHandler(UIBackgroundFetchResultNewData);}];} else {// Fallback on earlier versions}
}#pragma mark -
#pragma mark UNUserNotificationCenterDelegate/// App在前台时收到普通推送  方法一
- (void)userNotificationCenter:(UNUserNotificationCenter*)center willPresentNotification:(UNNotification*)notification withCompletionHandler:(void(^)(UNNotificationPresentationOptions))completionHandler  API_AVAILABLE(ios(10.0)) {NSDictionary* userInfo = notification.request.content.userInfo;NSLog(@"前台收到普通推送: %@", userInfo);
}/// App在后台时点击普通推送栏  方法二
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler  API_AVAILABLE(ios(10.0)) {NSDictionary* userInfo = response.notification.request.content.userInfo;NSLog(@"后台收到普通推送: %@", userInfo);completionHandler();
}- (void)userNotificationCenter:(UNUserNotificationCenter *)center openSettingsForNotification:(nullable UNNotification *)notification API_AVAILABLE(ios(10.0)) {}#pragma mark -
#pragma mark internal method
/*!*  @brief 接收并存储deviceToken**  @param deviceToken deviceToken**  @return 是否有变化(有变法则需要发送网络请求将deviceToken提交到push provider推送服务器)*/
- (BOOL)didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {const unsigned *tokenBytes = [deviceToken bytes];NSString *hexToken = [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])];/// deviceToken有变化则需修改本地及提交到服务器if(![self.deviceTokenString isEqualToString:hexToken]){self.deviceTokenString = hexToken;/// 返回YES表示deviceToken有变化,需要发送网络请求将deviceToken提交到push provider(业务服务器)return YES;}return NO;
}/// 首先需要初始化应用
- (void)initPushSrv {[LCApplication setApplicationId:kAppId clientKey:kAppKey serverURLString:kAPNsSrvUrl];if (@available(iOS 10.0, *)) {[[UNUserNotificationCenter currentNotificationCenter] getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {switch ([settings authorizationStatus]) {case UNAuthorizationStatusAuthorized:dispatch_async(dispatch_get_main_queue(), ^{[[UIApplication sharedApplication] registerForRemoteNotifications];});break;case UNAuthorizationStatusNotDetermined:[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {if (granted) {dispatch_async(dispatch_get_main_queue(), ^{[[UIApplication sharedApplication] registerForRemoteNotifications];});}}];break;default:break;}}];} else {// Fallback on earlier versions}
}

静默推送和普通推送的区别

测试环境:
iPhone12 Pro
iOS 16.0.2 (20A380)

静默推送消息格式

{"aps": {"content-available": 1,"sound": "default","key1": "value1","key2": "value2"}
}

其中"content-available": 1, “sound”: “default”, 是必填项key-value.(根据实测)
“alert”:“”, alert配置与否, 不影响结果.

但是, 在后台时,
如果alert配置了内容, 会有default提示音.并且顶部有消息提示.
触发的方法一致, 是didReceiveRemoteNotification.
这时点击顶部消息提示, 会触发didReceiveNotificationResponse.

静默推送会触发didReceiveRemoteNotification, (无论前后台)
但是, 在前台时,
会先触发willPresentNotification,
再触发didReceiveRemoteNotification.

App挂起时(或者未启动)(不在前台也不在后台)
会先触发didFinishLaunchingWithOptions,
再触发didReceiveRemoteNotification.

普通推送

{"aps": {"alert": "New weixin message.","badge": 1,"sound": "default"}
}

在后台时,

根据sound配置提示声音(默认),
根据alert显示顶部消息.
点击消息, 触发didReceiveNotificationResponse.

在前台时,

直接触发willPresentNotification, 无默认提示音.

App挂起时(或者未启动)(不在前台也不在后台)
同在后台时,

代理没设置时

如果未设置代理,
[[UNUserNotificationCenter currentNotificationCenter] setDelegate:self];
通通走方法didReceiveRemoteNotification

服务端推送方式

苹果提供了两种方式来发送通知,这两种方式各有优点和缺点,云服务对这两种方式都支持,可以根据需要选择其中一种推送方式。

基于 Token 的推送方式(推荐)。

  • 理论上它比基于证书的方式更快。
  • 支持多个云服务应用使用同一个 Key。
  • 支持用同一个 Key 给苹果开发者账号下的多个应用推送通知。
  • 支持用同一个 Key 给苹果开发者账号下的测试、正式应用推送通知。
  • 生成的 Key 不再有过期时间,无需像证书方式那样需要定期重新生成证书。

基于证书的推送方式。

  • 证书和苹果的 App ID 绑定,一个证书只能向其绑定的苹果应用推送通知。
  • APNs 有开发、生产两个环境,可能需要为不同环境下的苹果应用配置对应的证书。
  • 证书有过期时间,需要定期重新生成并配置。

总的来说,基于 Token 的推送方式在配置步骤、易用性以及功能性上,都要优于基于证书的推送方式,因此我们推荐使用基于 Token 的推送方式。

参考&感谢

leancloud 文档


http://www.ppmy.cn/news/356337.html

相关文章

iOS 图形绘制

文章目录 需求重绘视图CGContextRef 篇UIBezierPath 篇 外部绘制图层代理CAShapeLayer CGContextRef 和 UIBezierPathCAShapeLayer 对比总结 需求 在许多需要图形显示数据的应用中常常需要进行图形绘制&#xff0c;例如股票金融。在一些特定动画中&#xff0c;我们同样需要结合…

2021年我国山西苹果产业发展现状:苹果产量430.2万吨,占山西省园林水果总产量的46.8% [图]

一、现状 山西省位于黄土高原东部&#xff0c;70%是丘陵和山地&#xff0c;全省土地面积为15.63万km2 &#xff0c;土地资源较丰富&#xff0c;全省农业人口人均土地面积9.58亩&#xff0c;可耕地面积约2亿亩&#xff1b;据统计&#xff0c;全省有荒坡、荒山、盐碱地、河滩地、…

ios图片处理

圖片的處理大概就分這幾樣了截圖(capture), 縮放(scale), 設定大小(resize), 儲存(save) 這幾樣比較好處理, 另外還有濾鏡, 擦拭等, 以後再說 在這個Demo code裡, 我寫了幾個方法 1.等比率縮放 - (UIImage *)scaleImage:(UIImage *)image toScale:(float)scaleSize { UIG…

苹果启动图尺寸详情

机型屏幕尺寸启动图尺寸英寸XS Max414 * 8961242 * 26886.5XS375 * 8121125 * 24365.8XR414 * 896828 * 17926.1X375 * 8121125 * 24365.88P/7P/6P/6SP414 * 7361242 * 22085.58/7/6/6s375 * 667750 * 13344.7se/5s/5320 * 568640 * 11364 官方链接 https://developer.apple.c…

2021年中国陕西苹果产量分布及出口情况分析:陕西苹果产量约占全国总产量的26.89% [图]

一、概述 陕西苹果是全球知名品牌&#xff0c;被誉为国礼&#xff0c;产量品质居中国第一。陕西是联合国粮农组织认定的世界苹果最佳优生区&#xff0c;是全球集中连片种植苹果最大区域。陕西苹果生长在海拔高、光照足、昼夜温差大、土层深厚的渭北黄土高原&#xff0c;独特的自…

图解苹果iOS 5的24个秘密功能(图)

原文地址&#xff1a;http://www.techweb.com.cn/world/2011-10-18/1107209.shtml TechWeb报道】10月18日消息&#xff0c;据国外媒体报道&#xff0c;苹果新操作系统iOS 5拥有数百个新功能&#xff0c;但该公司网站仅展示了一小部分。科技博客Business Insider知名科技写手埃利…

开源一款苹果 macOS 工具 - AppleParty(苹果派)

AppleParty 是 37手游 iOS 团队研发&#xff0c;实现快速操作 App Store Connect 后台的自动化 macOS 工具。本文会介绍工具诞生的背景、使用教程和代码实现的简介&#xff0c;希望通过开源与大家分享成果&#xff0c;让更多人一起参与改进和完善&#xff0c;最后一起提高效率和…

2021年山东省苹果产量分布及出口情况[图]

一、现状 山东省是我国苹果种植的核心产区&#xff0c;烟台苹果和栖霞苹果享誉海内外。2020年山东园林水果产量中&#xff0c;苹果产量为953.63万吨&#xff0c;占全省园林水果产量的52.12%&#xff0c;占据一半以上。 2020年山东园林水果产量情况 资料来源&#xff1a;山东统…