在 iOS 10 中,Apple 已弃用 UILocalNotification,这意味着是时候熟悉新的通知框架了。
设置
这是一篇很长的文章,所以让我们从导入新的通知框架开始吧:
// Swift
import UserNotifications
// Objective-C (with modules enabled)
@import UserNotifications;
您通过共享的 UNUserNotificationCenter 对象管理通知:
// Swift
let center = UNUserNotificationCenter.current()
// Objective-C
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
授权
与旧的通知框架一样,您需要获得用户对您的应用程序将使用的通知类型的许可。在您的应用生命周期的早期提出请求,例如在 application:didFinishLaunchingWithOptions:. 您的应用第一次请求授权时,系统会向用户显示警报,之后他们可以从设置中管理权限:
// Swift
let options: UNAuthorizationOptions = [.alert, .sound];
// Objective-C
UNAuthorizationOptions options = UNAuthorizationOptionAlert + UNAuthorizationOptionSound;
您使用共享通知中心提出实际授权请求:
// Swift
center.requestAuthorization(options: options) { (granted, error) in
if !granted {
print("Something went wrong")
}
}
// Objective-C
[center requestAuthorizationWithOptions:options
completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (!granted) {
NSLog(@"Something went wrong");
}
}];
框架调用完成处理程序,并使用一个布尔值指示访问是否被授予,以及一个错误对象,如果没有发生错误,该对象将为 nil。
注意:用户可以随时更改您应用的通知设置。您可以使用 getNotificationSettings 检查允许的设置。这将使用 UNNotificationSettings 对象异步调用完成块,您可以使用它来检查授权状态或单个通知设置:
// Swift
center.getNotificationSettings { (settings) in
if settings.authorizationStatus != .authorized {
// Notifications not allowed
}
}
// Objective-C
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
if (settings.authorizationStatus != UNAuthorizationStatusAuthorized) {
// Notifications not allowed
}
}];
创建通知请求
UNNotificationRequest 通知请求包含内容和触发条件:
通知内容
通知的内容是 UNMutableNotificationContent 的一个实例,并根据需要设置了以下属性:
title:包含警报主要原因的字符串。
subtitle:包含警报字幕的字符串(如果需要)
body:包含警报消息文本的字符串
徽章:应用图标上显示的数字。
声音:发出警报时播放的声音。使用 UNNotificationSound.default() 或从文件创建自定义声音。
launchImageName:启动应用程序响应通知时使用的启动图像名称。
userInfo:要传入通知的自定义信息字典
附件:一组 UNNotificationAttachment 对象。用于包含音频、图像或视频内容。
请注意,在本地化像标题这样的警报字符串时,最好使用localizedUserNotificationString(forKey:arguments:),它会延迟加载本地化,直到通知发送。
一个简单的例子:
// Swift
let content = UNMutableNotificationContent()
content.title = "Don't forget"
content.body = "Buy some milk"
content.sound = UNNotificationSound.default()
// Objective-C
UNMutableNotificationContent *content = [UNMutableNotificationContent new];
content.title = @"Don't forget";
content.body = @"Buy some milk";
content.sound = [UNNotificationSound defaultSound];
通知触发器
根据时间、日历或位置触发通知。触发器可以重复:
时间间隔:在几秒钟后安排通知。比如五分钟触发:
// Swift
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 300, repeats: false)
// Objective-C
UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:300
repeats:NO];
日历:在特定日期和时间触发。触发器是使用日期组件对象创建的,这使得某些重复间隔更容易。要将 Date 转换为其日期组件,请使用当前日历。例如:
// Swift
let date = Date(timeIntervalSinceNow: 3600)
let triggerDate = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute, .second], from: date)
// Objective-C
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:3600];
NSDateComponents *triggerDate = [[NSCalendar currentCalendar]
components:NSCalendarUnitYear +
NSCalendarUnitMonth + NSCalendarUnitDay +
NSCalendarUnitHour + NSCalendarUnitMinute +
NSCalendarUnitSecond fromDate:date];
从日期组件创建触发器:
// Swift
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDate, repeats: false)
// Objective-C
UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:triggerDate
repeats:NO];
要创建以特定间隔重复的触发器,请使用正确的日期组件集。例如,要让通知每天在同一时间重复,我们只需要小时、分钟和秒:
let triggerDaily = Calendar.current.dateComponents([hour, .minute, .second], from: date)
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDaily, repeats: true)
要让它每周重复一次,同时我们还需要工作日:
let triggerWeekly = Calendar.current.dateComponents([.weekday, .hour, .minute, .second], from: date)
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerWeekly, repeats: true)
调度
内容和触发器都准备好后,我们创建一个新的通知请求并将其添加到通知中心。每个通知请求都需要一个字符串标识符以供将来参考:
// Swift
let identifier = "UYLLocalNotification"
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
center.add(request, withCompletionHandler: { (error) in
if let error = error {
// Something went wrong
}
})
// Objective-C
NSString *identifier = @"UYLLocalNotification";
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:identifier
content:content trigger:trigger]
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
if (error != nil) {
NSLog(@"Something went wrong: %@",error);
}
}];