衆所周知,蘋果的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
}
}