众所周知,苹果的apns推送,在我们不点击通知时,app是不会执行任何代码的,且apns推送的保活时间是30s左右,如果我们想对推送内容进行修改,可以通过Notification Service Extension进行动态修改
一、Notification Service Extension
1、点击 file->new->target
2、选择 iOS->Notification Service Extension
3、选择创建extension的项目target,输入扩展名称,点击finish,即创建扩展完成
二、配置Extension
创建完成后,主要有两个文件NotificationService.swift 和 info.plist
1、首先,需要在扩展对应的target->Signing&Capabilities,点击+Capability,添加push notification
2、NotificationService.swift中主要有两个方法
1)override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void)
该方法主要是用于在接受到推送时,针对推送内容进行修改,修改完成后展示给用户
2)override func serviceExtensionTimeWillExpire()
该方法是用于在方法1)中如果没有向用户展示推送,可以在这里(即apns即将到30s时)向用户推送
3、推送的消息中必须具备alert和"mutable-content":"1"(表示推送可修改)
三、如何充分利用30s的apns
1、如果你的需求只是一般的推送,不需要重复的提示用户,可以只是简单的修改推送内容即可
2、如果是有特殊需求,例如需要30s内不断提示用户,有重要视频/来电,需要重复提醒
目前的方案是:创建本地通知,每7秒响铃通知一次,最后一次采用扩展的推送通知,同时取消已发送的本地通知
代码如下
var Count = 0
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
bestAttemptContent!.title = "新来电"
bestAttemptContent!.subtitle = ""
bestAttemptContent!.body = "您收到xxxxxxx的来电"
//创建重复本地通知提醒
self.addTimer()
@objc func addTimer(){
// 创建本地通知
repeateNoti()
self.Count += 1
if self.Count < 5{
DispatchQueue.global(qos: .default).async {
let timer = Timer.scheduledTimer(timeInterval: 7, target: self, selector: #selector(self.addTimer), userInfo: nil, repeats: false)
RunLoop.current.add(timer, forMode: RunLoop.Mode.default)
RunLoop.current.run()
}
}else{
print("移除本地通知")
UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: [identifier])
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [identifier])
bestAttemptContent!.sound = UNNotificationSound(named:UNNotificationSoundName(rawValue: "5s.wav"))
contentHandler!(bestAttemptContent!)
}
}
func repeateNoti(){
print("repeateNoti")
content.title = "新来电"//标题
content.body = "您收到xxxxxx的来电"//内容
content.badge = 1 //通知个数
content.sound = UNNotificationSound(named:UNNotificationSoundName(rawValue: "5s.wav"))
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 0.1, repeats: false)
let request = UNNotificationRequest.init(identifier: identifier, content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) { erro in
}
}