iOS 10:本地消息推送及實現(xiàn)

文章結(jié)構(gòu):

<a id="1"></a>前言

這階段在學(xué)習(xí)有關(guān) iOS 10 消息推送的內(nèi)容,通過查閱資料并親身實踐,對消息推送有了一定的理解。因此寫這篇文章,希望對剛接觸 iOS 消息推送的開發(fā)者有幫助。

Apple 應(yīng)用的消息推送分為本地消息推送(Local Notification)和遠(yuǎn)程消息推送(Remote Notification)。當(dāng)有新的消息時,可以通過本地或遠(yuǎn)程推送告知用戶,即使 App 并未運行。

  • 本地消息推送不需要聯(lián)網(wǎng),由系統(tǒng)統(tǒng)一管理 App 推送的消息,App 只需與系統(tǒng)交互即可。本地消息推送適用于 iOS、tvOS 和 watchOS。
  • 遠(yuǎn)程消息推送需要連接網(wǎng)絡(luò),通過 App 或者后臺服務(wù)器與 Apple Push Notification(APN) 通信,再由 APN 將消息推送到終端上。遠(yuǎn)程消息推送除了支持 iOS、tvOS 和 watchOS,還支持 macOS。

本文將大體介紹消息推送的相關(guān)內(nèi)容,并實現(xiàn)基本的本地消息推送。想直接看如何實現(xiàn)本地消息推送,請看“本地消息推送實現(xiàn)”部分。

<a id="2"></a>iOS 消息推送的基礎(chǔ)知識

<a id="21"></a>推送方式

盡管消息推送方式分為本地和遠(yuǎn)程,但是他們展現(xiàn)給用戶的方式是一樣的,因為它們默認(rèn)使用的是系統(tǒng)提供的外觀。主要的推送方式有:

  • 通知、橫幅
  • 應(yīng)用圖標(biāo)標(biāo)記
  • 帶有聲音的通知、橫幅或標(biāo)記

<a id="22"></a>管理消息推送

App must be configured at launch time to support local and remote notification.

首先,我們需要在 applicationDidFinishLaunching: 之前聲明支持消息推送的方式。如果想在 App 運行后某個時間再進行聲明的話,在此之前要避免推送消息。因為在聲明支持消息推送之前,發(fā)送任何消息都是無效的。

當(dāng)配置了消息推送的方式后,需要請求授權(quán):requestAuthorizationWithOptions:completionHandler:,第一次調(diào)用該方法時,系統(tǒng)會提示用戶 App 需要推送消息,等待用戶確認(rèn)。系統(tǒng)自動保存用戶的授權(quán)結(jié)果,當(dāng)以后調(diào)用該方法時,就不會在出現(xiàn)提示了。

獲得推送消息權(quán)限后,就需要考慮以下幾個問題:

一、設(shè)定 Category。當(dāng) App 推送的消息很多,需要進行分類時,就需要設(shè)定 Category。

let generalCategory = UNNotificationCategory(identifier: "GENERAL",actions: [],intentIdentifiers: [],options: .customDismissAction)
 // Register the category.
let center = UNUserNotificationCenter.current()
center.setNotificationCategories([generalCategory])

設(shè)定消息的 Category 后,就可以添加自定義的行為(action),這樣用戶就可以在不打開 App 的情況下,對消息進行簡單的操作。如果不為消息分配 Category,那么消息就會以默認(rèn)的形式推送,不帶有任何附加的行為。

二、為 Category 添加自定義的行為。每個 Category 最多可以包含四個自定義的行為。

let generalCategory = UNNotificationCategory(identifier: "GENERAL",actions: [],intentIdentifiers: [],options: .customDismissAction)
 
// Create the custom actions for the TIMER_EXPIRED category.
let snoozeAction = UNNotificationAction(identifier: "SNOOZE_ACTION",title: "Snooze", options: UNNotificationActionOptions(rawValue: 0))
let stopAction = UNNotificationAction(identifier: "STOP_ACTION",title: "Stop",options: .foreground)
 
let expiredCategory = UNNotificationCategory(identifier: "TIMER_EXPIRED", actions: [snoozeAction, stopAction],intentIdentifiers: [], options: UNNotificationCategoryOptions(rawValue: 0))
 
// Register the notification categories.
let center = UNUserNotificationCenter.current()
center.setNotificationCategories([generalCategory, expiredCategory])

三、配置通知聲音。本地和遠(yuǎn)程推送都可以自定義聲音。自定義聲音的音頻編碼形式可以是以下幾種:

  • Linear PCM
  • MA(IMA/ADPCM)
  • uLaw
  • aLaw

而音頻文件應(yīng)該為 .aiff.wav.caf 文件。音頻時長必須小于 30s,否則系統(tǒng)會使用默認(rèn)的聲音。Mac 里自帶了 afconvert 音頻格式轉(zhuǎn)換工具。如在終端中輸入如下代碼,可以將 16-bit linear PCM 編碼的 Submarine.aiff 文件轉(zhuǎn)化為 IMA4 編碼的 .caf 文件:

afconvert /System/Library/Sounds/Submarine.aiff ~/Desktop/sub.caf -d ima4 -f caff -v

四、管理推送設(shè)置。由于用戶可以在設(shè)置里自由的打開或關(guān)閉 App 推送功能,在程序中,需要判斷推送功能是否可用:getNotificationSettingsWithCompletionHandler:。

五、管理推送消息。我們可以給用戶推送消息,也可以管理已經(jīng)推送或?qū)⒁扑偷南?。?dāng)一條消息已經(jīng)不具備時效性,那么我們就應(yīng)該把它從通知欄中消除。使用:removeDeliveredNotificationsWithIdentifiers:removePendingNotificationsWithIdentifiers:。

<a id="3"></a>本地消息推送實現(xiàn)

下面的代碼是實現(xiàn)了一個負(fù)責(zé)推送消息的對象,它包含了請求推送創(chuàng)建推送消息的方法。

import UIKit
import UserNotifications

internal class LocalNotificationManager: NSObject {
    static let shared = LocalNotificationManager()
    private let notificationCenter = UNUserNotificationCenter.current()
    private override init(){
        super.init()        
    }
    //用于請求推送權(quán)限
    internal func requestAuthorization(){
        notificationCenter.requestAuthorization(options: [.alert, .sound]){ (granted, error) in
            if(granted&&error == nil){
                
            }else{
                
            }
        }
    }
    //用于創(chuàng)建推送消息(創(chuàng)建的消息將在調(diào)用函數(shù)后十秒發(fā)出)
    internal func createNewNotification(){     
        let content = UNMutableNotificationContent()
        content.title = NSString.localizedUserNotificationString(forKey: "Alarm", arguments: nil)
        content.body = NSString.localizedUserNotificationString(forKey: "WakeUp", arguments: nil)
        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 10, repeats: false)
        let request = UNNotificationRequest(identifier: "MyNotification", content: content, trigger: trigger)
        
        notificationCenter.add(request){(error) in
            if let _ = error {
                assertionFailure()
            }
        }
    }
}

有了上面管理消息推送的對象,實現(xiàn)簡單的本地消息推送只需要以下兩步:

一、在 AppDelegate.swift 里的 application:willFinishLaunchingWithOptions: 調(diào)用 requestAuthorization 請求授權(quán):

func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
        LocalNotificationManager.shared.requestAuthorization()  
        return true
}

二、在要推送消息的地方調(diào)用:

LocalNotificationManager.shared.createNewNotification()

這樣就能收到推送的消息。
當(dāng) App 在后臺運行時,消息會以橫幅的形式出現(xiàn)。
當(dāng) App 在前臺運行時,消息會直接傳遞給 App,默認(rèn)狀態(tài)下不出現(xiàn)橫幅。想在前臺運行時也出現(xiàn)橫幅,可以實現(xiàn) UNUserNotificationCenterDelegate 代理方法,在 completionHandler 里添加需要的推送形式:

func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler(UNNotificationPresentationOptions.alert)
}

歡迎訪問我的Github:LinShiwei (Lin Shiwei) · GitHub

有任何疑問的話,歡迎在下方評論區(qū)討論。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容