序言
推送消息是APP中重要的一个部分,它可以在用户不打开APP的情况下,告知用户一些APP内的消息,甚至是进行一些简易操作。推送一般分为两种,本地推送和远程推送。本篇文章主要介绍本地推送。
UserNotification
在iOS10中,苹果升级了推送系统,使推送不仅仅能显示文字,还能够显示更多类型的信息,以及进行操作。因此,苹果废弃了UILocalNotification等API,而改用UserNotification来实现推送的功能。
让我们先来看看UserNotification都由哪些部分组成。
从上至下依次来解释一下这些文件的作用。
NSString+UserNotifications.h
该文件是NSString的Category,提供了一个方法用来将文本信息进行本地化处理。UNError.h
该文件定义了一个枚举类UNErrorCode,用来标示不同种类的错误。UNNotification.h
这个类是推送的基础类。UNNotificationAction.h
这个类定义了推送通知中的交互操作。
它还有个子类UNTextNotificationAction,负责定义推送通知中的文本框。UNNotificationAttachment.h
这个类定义了推送通知中的附件。UNNotificationCategory.h
这个类定义了推送通知的类别,与UNNotificationAction搭配使用。UNNotificationContent.h
这个类定义了推送通知中的内容。
它还有个子类UNMutableNotificationContent,是可变版本。UNNotificationRequest.h
这个类是用来发起推送请求的UNNotificationResponse.h
这个类是在推送的回调中用来返回一些信息的。UNNotificationServiceExtension.h
这个类是在收到远程推送后更改推送内容再向用户展示的。UNNotificationSettings.h
这个类定义了推送通知的详细设置,例如声音、弹窗、红点等。UNNotificationSound.h
这个类定义了推送通知的声音。UNNotificationTrigger.h
这个类定义了推送通知的触发器。
它有个子类UNPushNotificationTrigger,定义了基于远程推送的触发器。
它有个子类UNTimeIntervalNotificationTrigger,定义了基于定时器的触发器。
它有个子类UNCalendarNotificationTrigger,定义了基于日期的触发器。
它有个子类UNLocationNotificationTrigger,定义了基于位置的触发器。UNUserNotificationCenter.h
这个类定义了管理中心,管理所有推送通知的行为。UserNotifications.apinotes
包含了这个模块的一些注释,主要是方便swift调用框架时的映射。UserNotifications.h
该文件引入了上述头文件,方便外界引用。
实际应用
1. 获取用户授权
[[UNUserNotificationCenter currentNotificationCenter]requestAuthorizationWithOptions:UNAuthorizationOptionAlert|
UNAuthorizationOptionSound|
UNAuthorizationOptionBadge|
UNAuthorizationOptionCarPlay
completionHandler:^(BOOL granted, NSError * _Nullable error) {
//granted代表用户是否同意授权。
}];
UNAuthorizationOptions的定义如下,每一条的作用已经标在注释里
typedef NS_OPTIONS(NSUInteger, UNAuthorizationOptions) {
UNAuthorizationOptionBadge = (1 << 0),//是否可以更新App的小红点
UNAuthorizationOptionSound = (1 << 1),//是否可以播放声音
UNAuthorizationOptionAlert = (1 << 2),//是否可以显示消息
UNAuthorizationOptionCarPlay = (1 << 3),//是否可以在车载模式下推送
UNAuthorizationOptionCriticalAlert __API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) = (1 << 4),//是否可以播放警告消息的声音
UNAuthorizationOptionProvidesAppNotificationSettings __API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) = (1 << 5),//是否可以显示推送设置的按钮
UNAuthorizationOptionProvisional __API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) = (1 << 6),//是否为临时授权,临时授权下用户可以在收到推送的时候设置授权
UNAuthorizationOptionAnnouncement __API_AVAILABLE(ios(13.0), watchos(6.0)) __API_UNAVAILABLE(macos, tvos) = (1 << 7),//是否允许Siri自动播报
} __API_AVAILABLE(macos(10.14), ios(10.0), watchos(3.0), tvos(10.0));
2. 带文字的通知
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc]init];
content.title = [NSString localizedUserNotificationStringForKey:@"title" arguments:nil];
content.subtitle = [NSString localizedUserNotificationStringForKey:@"subtitle" arguments:nil];
content.body = [NSString localizedUserNotificationStringForKey:@"body" arguments:nil];
UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:10.0
repeats:NO];
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"identifier"
content:content
trigger:trigger];
[[UNUserNotificationCenter currentNotificationCenter]addNotificationRequest:request
withCompletionHandler:^(NSError * _Nullable error) {
}];
显示效果如下
3. 带图片的通知
在原有代码上额外添加下面几行
NSString *path = [[NSBundle mainBundle]pathForResource:@"TestImage" ofType:@"png"];
NSURL *URL = [NSURL fileURLWithPath:path];
UNNotificationAttachment *attachment = [UNNotificationAttachment attachmentWithIdentifier:@"attachment"
URL:URL
options:nil
error:nil];
content.attachments = @[attachment];
显示效果如下
4. 带视频的通知
和带图片的通知是一样的创建方式
NSString *path = [[NSBundle mainBundle]pathForResource:@"TestVideo" ofType:@"mov"];
NSURL *URL = [NSURL fileURLWithPath:path];
UNNotificationAttachment *attachment = [UNNotificationAttachment attachmentWithIdentifier:@"attachment"
URL:URL
options:nil
error:nil];
content.attachments = @[attachment];
显示效果如下
5. 推送声音设置
content.sound = [UNNotificationSound soundNamed:@"sound.caf"];//自定义声音
//or
content.sound = [UNNotificationSound defaultSound];//默认声音
//or
content.sound = [UNNotificationSound defaultCriticalSound];//默认警告声
6. UNNotificationAction
UNNotificationAction * action = [UNNotificationAction actionWithIdentifier:@"action"
title:@"action"
options:UNNotificationActionOptionForeground];
NSArray *actionArr = @[action];
UNNotificationCategory * categoryNotification = [UNNotificationCategory categoryWithIdentifier:@"categoryOperationAction"
actions:actionArr
intentIdentifiers:@[]
options:UNNotificationCategoryOptionCustomDismissAction];
NSSet *categories = [NSSet setWithObject:categoryNotification];
[[UNUserNotificationCenter currentNotificationCenter]setNotificationCategories:categories];
content.categoryIdentifier = @"categoryOperationAction";
其中UNNotificationAction定义的是一个按钮,动作,UNNotificationCategory则相当于一组Action的容器,方便管理。
UNNotificationActionOptions的定义如下。
typedef NS_OPTIONS(NSUInteger, UNNotificationActionOptions) {
// 该操作是否只能在一个已解锁的设备上执行
UNNotificationActionOptionAuthenticationRequired = (1 << 0),
// 该操作是否是一个破坏性的操作,例如删除
UNNotificationActionOptionDestructive = (1 << 1),
// 该操作是否会导致APP进入前台
UNNotificationActionOptionForeground = (1 << 2),
} __API_AVAILABLE(macos(10.14), ios(10.0), watchos(3.0)) __API_UNAVAILABLE(tvOS);
UNNotificationCategoryOptions的定义如下。
typedef NS_OPTIONS(NSUInteger, UNNotificationCategoryOptions) {
// 是否要让Dismiss的操作也通过UNUserNotificationCenter的delegate回调
UNNotificationCategoryOptionCustomDismissAction = (1 << 0),
// 是否可以在车载模式中出现
UNNotificationCategoryOptionAllowInCarPlay __API_UNAVAILABLE(macos) = (1 << 1),
// 是否要显示标题,即使用户已经设置不可预览通知
UNNotificationCategoryOptionHiddenPreviewsShowTitle __API_AVAILABLE(macos(10.14), ios(11.0)) __API_UNAVAILABLE(watchos, tvos) = (1 << 2),
// 是否要显示副标题,即使用户已经设置不可预览通知
UNNotificationCategoryOptionHiddenPreviewsShowSubtitle __API_AVAILABLE(macos(10.14), ios(11.0)) __API_UNAVAILABLE(watchos, tvos) = (1 << 3),
// 是否允许Siri自动播报
UNNotificationCategoryOptionAllowAnnouncement __API_AVAILABLE(ios(13.0), watchos(6.0)) __API_UNAVAILABLE(macos, tvos) = (1 << 4),
} __API_AVAILABLE(macos(10.14), ios(10.0), watchos(3.0)) __API_UNAVAILABLE(tvOS);
显示效果如下
7. UNTextInputNotifactionAction
UNTextInputNotificationAction *action = [UNTextInputNotificationAction actionWithIdentifier:@"textAction"
title:@"textAction"
options:UNNotificationActionOptionNone
textInputButtonTitle:@"send"
textInputPlaceholder:@"placeholder"];
剩余代码与UNNotificationAction的一样。
点击后会显示输入框,显示效果如下
8. Action回调
Action的回调是通过UNNotificationDelegate中的方法返回的
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void(^)(void))completionHandler {
if ([response isKindOfClass:[UNTextInputNotificationResponse class]]) {
UNTextInputNotificationResponse *textResponse = (UNTextInputNotificationResponse *)response;
NSString *text = textResponse.userText;
// text为用户输入的文本
} else {
if ([response.actionIdentifier isEqualToString:@"action"]) {
// 此为标识符为action的操作
}
}
completionHandler();
}
尾声
创建一个本地推送的基本流程就是这样,不过iOS上推送能做到的远不止如此。通过UserNotificationsUI库,开发者还可以自定义推送展开页面,限于篇幅,本篇文章就不作展开了。