1.概述
经过很长时间熬夜脱发的开发,我又双叒叕遇到一个小问题。嗯~就是很小,也就这么大👌。借用上家公司CTO经常对我说的话:这世界不可能存在完全没有bug的应用,如果有,那是测试案例还不够全!!!
先附短视频符合你的需求就继续看,不符合你就赶紧换一家,别浪费时间。
Emmm…视频还是算了,看图说话
点击按钮后:
2.背景
经过3年前跟BlueTooth成为朋友以后,最近感觉又交到一个新朋友——PassKit。但这不重要,重要的是PassKit又想给我介绍一个新朋友——UserNotifications,这个朋友性格比较怪,你不了解他的时候感觉它挺简单的,干净方便。就像这样
但当有些人想让你多了解一下它的时候你会发现它变了,变得你不认识了。就像这样
所以这就是君子之交淡如水的原因?如果是这样我宁愿没有认识过它…
但,生活还得继续,只能留着过年!
3.开始
a.新建项目
这个不用说了吧,不会的我感觉接下来也不用看了
b.自定义通知UI
自定义通知UI是通过UNNotificationContentExtension这个扩展实现的。
你可以在项目中新增一个UNNotificationContentExtension的扩展Target
点击Finish以后,会有一个弹窗确认界面点击 Activate 激活。
最后在你的项目中会多出一个文件夹
我们来详细看看文件夹里面都包含哪些内容:
- NotificationViewController
可以看到其继承自UIViewController。ViewController 中能干的事情它都能干。还配套了一个Storyboard 构建界面更加的方便。
在 .m 文件中可以看到其实现了UNNotificationContentExtension协议,
进入该协议可以看到只有两个方法:
//当接收到推送需要展示时,会调用这个方法,每一条推送都会调用这个方法。
- (void)didReceiveNotification:(UNNotification *)notification;
//用于获取用户的交互事件(Notification Actions)
- (void)didReceiveNotificationResponse:(UNNotificationResponse *)response completionHandler:(void (^)(UNNotificationContentExtensionResponseOption option))completion;
- info.plist
这里面是 NotificationContent 的一些配置信息,其中需要注意几个关键的Key:
UNNotificationExtensionCategory
此条目的值必须与传入的推送内容中的一个值相匹配。iOS 需要它来决定使用哪个 UI 来显示通知。
您需要它,因为您可能希望为不同类别的推送通知提供自定义用户界面。
如果缺少此值,iOS 将不会调用您的扩展。
UNNotificationExtensionInitialContentSizeRatio
这个值是一个介于 0 和 1 之间的数字,它代表了你的自定义界面的长宽比。
默认值为 1,它告诉 iOS,你的初始界面高度和宽度是一样的。
例如,如果你把这个值设置为 0.5,那么这将告诉 iOS 你的界面高度是宽度的一半。
这是一个估计值,允许 iOS 设置你界面的初始大小,防止不必要的调整大小。
UNNotificationExtensionDefaultContentHidden
当设置为 YES 时,推送内容的标准标题、副标题和正文不可见。
当设置为 NO 时,标准推送内容显示在自定义 UI 下方。
UNNotificationExtensionUserInteractionEnabled
这属性很重要,请不要一目十行忽略它。
当设置为 YES 时,可以实现用户与 UIKit 元素的交互。
了解完以上信息,还等什么?不管使用storyboard还是在didReceiveNotification协议中,快自己搞个按钮试试吧
c.测试通知
想测试通知,你必须先在Delegate中注册通知
- (void)authorizationPushNotificaton:(UIApplication *)application
{
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self; //必须写代理
[center requestAuthorizationWithOptions:UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionCarPlay completionHandler:^(BOOL granted, NSError * _Nullable error) {
//注册之后的回调
if (!error && granted) {
NSLog(@"注册成功...");
}
else{
NSLog(@"注册失败...");
}
}];
//获取注册之后的权限设置
//之前注册推送服务,用户点击了同意还是不同意,以及用户之后又做了怎样的更改我们都无从得知,现在 apple 开放了这个 API,我们可以直接获取到用户的设定信息了。注意UNNotificationSettings是只读对象哦,不能直接修改!
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
NSLog(@"通知配置信息:\n%@",settings);
}];
//注册通知获取token
[application registerForRemoteNotifications];
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
NSString *deviceTokenString = [self hexStringWithData:deviceToken];
NSLog(@"deviceTokenString:%@", deviceTokenString);
//存储得到的token,后面备用
[[NSUserDefaults standardUserDefaults] deviceTokenString forKey:@"deviceToken"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
NSLog(@"获取token失败:%@\n",error.localizedDescription);
}
- (NSString *)hexStringWithData:(NSData *)data {
Byte *bytes = (Byte *)[data bytes];
NSString *hexStr=@"";
for(int i=0;i<[data length];i++) {
NSString *newHexStr = [NSString stringWithFormat:@"%x",bytes[i]&0xff];///16进制数
if([newHexStr length]==1){
hexStr = [NSString stringWithFormat:@"%@0%@",hexStr,newHexStr];
} else {
hexStr = [NSString stringWithFormat:@"%@%@",hexStr,newHexStr];
}
}
return hexStr;
}
发远程通知的话,你还得为你的App颁发一个通知证书,这个就不讲了,参考推送通知的证书
那么,综上所述…谢谢,我的话讲完了。
4.FAQ
Q:远程推送通知工具有推荐的吗?
A:Push Notifications Tester
Q:NotificationContent面板上不支持自定义交互?
A:请认真看文章!
Q:copy的扩展文件无法显示?
A:记得把所有无关的关联去掉
Q:F:NotificationContent数据可以从App拿吗?
A:App Group共享了解一下
Q:有Demo吗?
A:必须有啊
5.文献
iOS推送通知教程:Rich Push Notification
iOS 10 推送 UNNotificationContent 与 UNNotificationService
Push Notifications Tutorial for iOS: Rich Push Notifications