本地推送通知UserNotifications在Swift中的實現(xiàn)方式
簡介
消息推送相信在很多人的眼里都不陌生了吧?像即時聊天微信,好友發(fā)信息給你時會在頂部彈下小窗口提醒你。也像是在影院APP預訂了電影票,在開場前一小時你也會收到提醒。這類推送是需要經(jīng)過后端發(fā)送請求的,需要服務器發(fā)送推送請求,又或者使用如極光推送等第三方渠道。
那么如果我們的APP不需要連網(wǎng)呢?這是不是就不能使用消息推送了?不是的,蘋果還提供給我們本地消息通知服務,即便APP不連網(wǎng)也能使用,功能也很強大可靠。本地時鐘的應用場景很廣泛,例如手機上的時鐘、日歷等。
那么你知道如何去實現(xiàn)它嗎?這篇文章將告知你答案,同時以兩個小案例作為例子,以便更好地去理解它。
筆者環(huán)境
Xcode - Version 11.5 (11E608c)
Swift - version 5.2.4 (swiftlang-1103.0.32.9 clang-1103.0.32.53).
權(quán)限獲取
UserNotifications 是 iOS10 推出來的框架,因此你只能在 10 或以上的版本使用它。推送服務和以往一樣,也是需要用戶授權(quán)的,當用戶同意后才能正常注冊消息通知,當用戶拒絕時應該引導用戶去打開APP的通知權(quán)限。利用requestAuthorization方法彈出并獲取通知權(quán)限,接收的參數(shù)options是具體的授權(quán)選項,一般有彈窗、未讀數(shù)量圖標和聲音即可,并在回調(diào)閉包中可以獲取授權(quán)結(jié)果和錯誤。
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { (status, err) in if !status { print("用戶不同意授權(quán)通知權(quán)限") return } }
status 為布爾類型,true 表示用戶同意,false 即拒絕。在此種情況下,我們可以使用彈窗去引導用戶去打開通知權(quán)限,需要明確告知用戶打開后有什么好處,如果關(guān)閉會造成什么影響等等。如果讓用戶手動打開設置,找到APP,為APP開啟權(quán)限,這樣未免太過復雜,所幸的是可以通過以下代碼為用戶直接跳轉(zhuǎn)至該應用的權(quán)限設置中心。
guard let url = URL(string: UIApplication.openSettingsURLString) else { return } if UIApplication.shared.canOpenURL(url) { UIApplication.shared.open(url, completionHandler: nil) }
應彈窗提示用戶,待用戶同意后才跳轉(zhuǎn)至設置,不然容易引起用戶的不滿心理。
觸發(fā)器
本地消息通知一般有以下三種類型的觸發(fā)器,它們都是繼承于類UNNotificationTrigger:
- UNTimeIntervalNotificationTrigger - 在經(jīng)過特定的時間后觸發(fā)本地消息推送;
- UNCalendarNotificationTrigger - 在特定的時間點觸發(fā)本地消息推送;
- UNLocationNotificationTrigger - 在進入或離開特定的地理位置時觸發(fā)本地消息推送。
UNTimeIntervalNotificationTrigger
手機上的時鐘用過吧,里面的計時器功能就可以用UNTimeIntervalNotificationTrigger實現(xiàn),比如開始計時30分鐘,那么在計時器完成的時候就是使用通知提醒。
那么設置在經(jīng)過特定的時間后觸發(fā)本地消息推送,一般都經(jīng)由以下幾個步驟:
- 首先創(chuàng)建UNMutableNotificationContent類,設定標題和內(nèi)容,如果你有子標題還可以設置子標題,一般很少見到會設置子標題的應用。
- 創(chuàng)建觸發(fā)器,這里就是UNTimeIntervalNotificationTrigger,設定執(zhí)行秒數(shù)和是否循環(huán)通知。
- 創(chuàng)建通知請求UNNotificationRequest,這里需要指定通知的identifier,內(nèi)容和觸發(fā)器,至于identifier,你可以隨意定義。
- 最后將通知請求添加到系統(tǒng)的通知中心UNUserNotificationCenter即可。
例子,創(chuàng)建一個通知,在5秒后執(zhí)行消息推送。實例代碼展示如下:
let content = UNMutableNotificationContent() content.title = "添加朋友 對著月亮敲代碼" //content.subtitle = "子標題" content.body = "公眾號 gh_6a83a7c19315" content.badge = 1 let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false) let request = UNNotificationRequest(identifier: "Notification", content: content, trigger: trigger) UNUserNotificationCenter.current().add(request) { err in err != nil ? print("添加本地通知錯誤", err!.localizedDescription) : print("添加本地通知成功") }
有一處小 Tips,UNTimeIntervalNotificationTrigger創(chuàng)建時的repeats選項,如果你設定為循環(huán)通知時,即需要每隔N秒觸發(fā)一次通知,那么你必須至少設置為60秒的時間間隔,如若低于60秒,你將會得到這樣一條錯誤。
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'time interval must be at least 60 if repeating' *** First throw call stack: ( 0 CoreFoundation 0x00007fff23c7127e __exceptionPreprocess + 350 1 libobjc.A.dylib 0x00007fff513fbb20 objc_exception_throw + 48 2 CoreFoundation 0x00007fff23c70ff8 +[NSException raise:format:arguments:] + 88 3 Foundation 0x00007fff256e9b51 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 191 4 UserNotifications 0x00007fff2c7dfc7c -[UNTimeIntervalNotificationTrigger _initWithTimeInterval:repeats:] + 277
UNCalendarNotificationTrigger
手機上的日歷用過吧,在新建日程的時候,你可以選擇一個提醒時間,這樣它就會在你設定的提醒時間提醒你,這種情況就很適合用UNCalendarNotificationTrigger去實現(xiàn)。
舉個例子,我們要在每晚7點提醒用戶看公眾號。
let content = UNMutableNotificationContent() content.title = "添加朋友 對著月亮敲代碼" //content.subtitle = "子標題" content.body = "公眾號 gh_6a83a7c19315" content.badge = 1 let dateComponents = DateComponents(hour: 19) // 1 let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true) // 2 let request = UNNotificationRequest(identifier: "Notification", content: content, trigger: trigger) UNUserNotificationCenter.current().add(request) { err in err != nil ? print("添加本地通知錯誤", err!.localizedDescription) : print("添加本地通知成功") }
1 - 創(chuàng)建時間元件,19點即為晚上7點
2 - 創(chuàng)建UNCalendarNotificationTrigger對象,并將dateComponents賦值到dateMatching,repeats為true,重復在每天19點收到通知提醒。
UNLocationNotificationTrigger
這個觸發(fā)器不在此篇文章講述,留給你們自己去實現(xiàn)和測試結(jié)果。
圖標
還記得剛剛設置的屬性badge嗎,我們設置值為1,這意味著在iPhone桌面上的應用圖標在收到通知時,右上角圓點內(nèi)所展示的數(shù)字就是badge的值。
這個屬性值是applicationIconBadgeNumber,它是UIApplication的屬性,設置為0即為隱藏,默認也是0。
UIApplication.shared.applicationIconBadgeNumber = 0
消息推送回調(diào)代理
接收用戶對消息推送的反饋事件,比如說應用在后臺收到了通知,用戶點擊了這條通知進入到了APP里面,我們需要獲取這個事件去做一些處理,比如跳去某個界面,這里例子不講這么復雜,只通過簡單地判斷用戶是通過哪個通知進來的。
接收回調(diào)代理事件前,需要遵循UNUserNotificationCenterDelegate協(xié)議,并設置delegate接收的對象。
xtension AppDelegate: UNUserNotificationCenterDelegate {} UNUserNotificationCenter.current().delegate = self
在Swift語言中,可以通過extension擴展類遵循的協(xié)議,并在extension。
當應用在前臺運行時,收到的是這個-userNotificationCenter:willPresentNotification:withCompletionHandler:代理方法。UNNotification對象存儲了傳遞到應用的一些數(shù)據(jù),通過此對象可以拿到此條通知關(guān)聯(lián)的觸發(fā)器notification.request.trigger,從而判斷其類型。
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { guard let trigger = notification.request.trigger else { return; } if trigger.isKind(of: UNTimeIntervalNotificationTrigger.classForCoder()) { print("Notification did receive, Is class UNTimeIntervalNotificationTrigger") } else if trigger.isKind(of: UNCalendarNotificationTrigger.classForCoder()) { print("Notification did receive, Is class UNCalendarNotificationTrigger") } }
當應用在后臺,或者被殺死的狀態(tài)下,收到的是這個-userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:代理方法。此方法接收UNNotificationResponse類型的參數(shù),它里面包含notification屬性,因此可以參考上面的代碼進行觸發(fā)器的判斷。
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { guard let trigger = response.notification.request.trigger else { return; } if trigger.isKind(of: UNTimeIntervalNotificationTrigger.classForCoder()) { print("Notification did receive, Is class UNTimeIntervalNotificationTrigger") } else if trigger.isKind(of: UNCalendarNotificationTrigger.classForCoder()) { print("Notification did receive, Is class UNCalendarNotificationTrigger") } }
總結(jié)
本地通知有三種類型的觸發(fā)器,分別是UNTimeIntervalNotificationTrigger、UNCalendarNotificationTrigger和UNLocationNotificationTrigger。
UNTimeIntervalNotificationTrigger在設置循環(huán)通知時,所設定的時間隔不能低于60秒,否則會報運行時錯誤。
Demo 源碼下載
我已經(jīng)把 Demo 上傳至 GitHub 上面,項目名字是 SwiftUI-Tutorials,https://github.com/GarveyCalvin/SwiftUI-Tutorials,目錄名為GCLocalUserNotification,有需要的朋友可以去下載運行一下,當然你也可以跟著文章去做一遍,這樣更有利于你掌握此方面的知識。
以上就是本地推送通知UserNotifications在Swift中的實現(xiàn)方式的詳細內(nèi)容,更多關(guān)于Swift推送的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Swift下使用UICollectionView 實現(xiàn)長按拖拽功能
拖拽排序是新聞類的App可以說是必有的交互設計,如今日頭條,網(wǎng)易新聞等。這篇文章主要介紹了Swift下使用UICollectionView 長按拖拽功能,需要的朋友可以參考下2017-03-03Swift免費短信驗證碼實現(xiàn)及動態(tài)倒計時功能
這篇文章主要介紹了Swift免費短信驗證碼實現(xiàn)及動態(tài)倒計時功能的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-02-02Swift利用CoreData如何存儲多種數(shù)據(jù)類的通訊錄
這篇文章主要給大家介紹了關(guān)于Swift利用CoreData如何存儲多種數(shù)據(jù)類的通訊錄的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧。2017-12-12