iOS 本地通知那些事

從iOS8開始,本質上來講有兩種通知:html

  1. 本地通知(local notifications):由開發者定義,App觸發。觸發的時間是被事先安排好的。ios

  2. 遠程通知(remote notifications):這種狀況下,通知能夠被分紅兩個類別:(a)推送通知(The push notifications),被服務器初始化,而後經過APNS,最終到達用戶設備。(b)靜默通知(The silent notifications),其實也是推送通知,可是他們並無被展現給用戶,而是當即被App處理以發起某項任務,最後當一切都完成時,一個本地通知 被顯示以提示用戶。git

除了以上的2種之外,iOS8引入了地點通知(location notifications)。它其實也是本地通知(local notifications),可是他們只會在用戶一個特定的地理或者iBeacon區域時,纔會被觸發。雖然咱們看不到什麼細節,地點通知 (location notifications)實現起來也很容易。github

從iOS8開始,通知被加入了新的特性。簡單地說,從如今開始,當一個通知被展現時,開發者能夠指定用戶可觸發的具體的動做(actions),並且甚至不用啓動App也能夠處理這個通知。swift

關於本地通知

  1. Alert or Banner:通知能夠用alert或者banner來顯示,這取決於用戶在設置中得選擇。數組

  2. Sound: 當一個通知被送達時,你能夠‘告訴’iOS播放一段自定義或者系統默認的聲音。服務器

  3. Badge: 當通知到達時,一個badge數字會在App的圖標上顯示。當一個通知到達時,badge數字必增長1,當通知被處理後badge數字減1。當badge數字不爲0或者爲0,iOS會顯示或者隱藏badge。app

能夠被安排的本地通知的數量並非無限的,最多有64個本地通知能夠被安排和展現。若是多餘這個數字,全部超過這個數字的通知都會被廢棄。儘管如此,不管通知是以什麼樣的形式被安排的,最先的那個會被最早展現。ide

規定通知類型

咱們來建立一個叫setupNotificationSettings()方法。post

func setupNotificationSettings() {
    //規定通知類型
    var notificationTypes:UIUserNotificationType = [.Alert,.Sound,.Badge]
 
}

UIUserNotificationType如今是一個結構體類型。它包含了通知的全部可能的類型。

建立通知動做

一個動做就是一個UIMutableUserNotificationAction類的對象。UIMutableUserNotificationActioniOS8新引入的類,有着許多有用的配置屬性:

  1. 標示符(identifier): 字符串,標示了一個對於整個App惟一的字符串。很明顯,你永遠不該該在同一個App中定義兩個一樣地標示符。經過此標示符,咱們能夠決定在用戶點擊不一樣的通知時,調用哪一個動做。

  2. 標題(title):用來在展現給用戶的動做按鈕上。能夠是簡單地或者本地化的字符串。爲了讓用戶能立刻理解動做的含義,必定要仔細考慮這個標題的值,最好是1到2個字符。

  3. destructive: 布爾值。當設置爲true時,通知中相應地按鈕的背景色會變成紅色。這隻會在banner通知中出現。一般,當動做表明着刪除、移除或者其餘關鍵的動做是都會被標記爲destructive以得到用戶的注意。

  4. authenticationRequired: 布爾值。當設置爲true時,用戶在點擊動做以前必須確認本身的身份。當一個動做十分關鍵時這很是有用,由於爲認證的操做有可能會破壞App的數據。

  5. ActivationMode: 決定App在通知動做點擊後是應該被啓動仍是不被啓動。

  6. behavior: iOS9 新特性 能夠支持在用戶通知中輸入文本

  7. parameters: iOS9 新特性

接下來咱們來建立幾種不一樣的動做:

//1 點擊後消失,不會作任何事情
        var justInformAction = UIMutableUserNotificationAction()
        justInformAction.identifier = "justInform" 
        justInformAction.title = "OK"
        justInformAction.destructive = false
        justInformAction.authenticationRequired = false
        justInformAction.activationMode = .Background

         //2 啓動應用
        var secAction = UIMutableUserNotificationAction()
        secAction.identifier = "secAction"
        secAction.title = "OK"
        secAction.activationMode = .Foreground
        secAction.destructive = false
        secAction.authenticationRequired = false

咱們把上邊的兩個方法放在setupNotificationSettings中。

當一個通知的全部動做被配置好了以後,他們能夠被包進一個類目(categories)裏。若是你的通知支持動做,那麼你就必須建立一個類目 (categories)。一般狀況下一個類目(category)配對一個通知,假設一個App中得全部通知都支持動做,那麼這個App也會有和通知一 樣多的類目(categories)。

類目(category)就是一個 UIMutableUserNotificationCategory類的對象,這也是iOS8新引入的類。這個類只有一個屬性和一個方法。標示符屬性用 來表示一個惟一的類目(category),方法用來將多個動做包含進來。

咱們來讓咱們來了解一下這個方法 (setActions):

public func setActions(actions: [UIUserNotificationAction]?, forContext context: UIUserNotificationActionContext)

第一個參數指明瞭須要包含進來的動做。是一個包含全部動做的數組,他們在數組中的順序也表明着他們將會在一個通知中調用的前後順序。

第二個參數很是重要。context形參是一個枚舉類型,描述了通知alert顯示時的上下文,有兩個值:

  1. Default : 在屏幕的中央展現一個完整的alert。(未鎖屏時)

  2. Minimal : 展現一個banner alert。

在默認上下文(default context)中,類目最多接受4個動做,會以預先定義好的順序依次在屏幕中央顯示。在minimal上下文中,最多能夠在banner alert中設置2個動做。注意在第二個狀況中,你必須選擇一個較爲重要的動做以顯示到banner通知裏。接下來咱們會將這兩種狀況都用代碼實現。

var category = UIMutableUserNotificationCategory()
        category.identifier = "category1"
        category.setActions([justInformAction], forContext: .Default)
        category.setActions([secAction], forContext: .Minimal)

而後…這樣就行啦,爲一個通知相關的動做建立一個類目就這樣完成了。

註冊通知設置

經過上面的3個部分,咱們已經將本地通知的全部新功能已經實現了。如今咱們須要將這些設定註冊到用戶設置中。爲了完成這個目標,咱們將會用到 UIUserNotificationSettings類(iOS8新引入),而後在下面的init方法中,咱們會指定通知類型和類目 (category)。

convenience init(forTypes types: UIUserNotificationType, categories: Set<UIUserNotificationCategory>?)

第一個參數是咱們爲通知設置的類型,第二個方法是一個集合(NSSet),在這個集合中必須包含一個App全部通知支持的類目。在本例中,咱們只有一個類目,可是咱們仍是須要使用集合來傳遞它。

let newNotificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: [category])
        //最後,讓咱們將它註冊一下吧!
        UIApplication.sharedApplication().registerUserNotificationSettings(newNotificationSettings)

第一次啓動App時上述代碼就會執行,它會在用戶設置中建立一條咱們的App記錄。

最後,在我展示一個完整的setupNotificationSettings(),還有一點須要注意。這個方法會在viewDidLoad方法中 被調用,這意味着每當App被啓動的時候它都會執行一次。很顯然一遍又一遍的設置一樣地值是在作無用功,這樣若是咱們將上面的方法用一個guard判斷執行一下的話就行了。

let notificationSettings = UIApplication.sharedApplication().currentUserNotificationSettings()
        guard notificationSettings?.types != .None else{
            return
        }

首先,咱們經過UIApplication的類方法currentUserNotificationSettings()來獲取通知的類型。經過這 個方法返回的UIUserNotificationSettings類的對象,咱們能夠檢查它的types枚舉屬性。請記住這個屬性爲枚舉類型。若是它的 值爲None,那麼通知類型就尚未被註冊,而後咱們就運行上面的方法來註冊通知類型,不然什麼也不作。

完整代碼:

func setupNotificationSetings(){
        
        let notificationSettings = UIApplication.sharedApplication().currentUserNotificationSettings()
        guard notificationSettings?.types != .None else{
            return
        }
        
        
        //規定通知類型
        let notificationTypes:UIUserNotificationType = [.Alert,.Sound,.Badge]
        //建立通知動做
        
        //1 點擊後消失,不會作任何事情
        let justInformAction = UIMutableUserNotificationAction()
        justInformAction.identifier = "justInform" //標識符
        justInformAction.title = "OK"
        justInformAction.destructive = false
        justInformAction.authenticationRequired = false
        justInformAction.activationMode = .Background
        
        //2 啓動應用
        let secAction = UIMutableUserNotificationAction()
        secAction.identifier = "secAction"
        secAction.title = "OK"
        secAction.activationMode = .Foreground
        secAction.destructive = false
        secAction.authenticationRequired = false
        
        let category = UIMutableUserNotificationCategory()
        category.identifier = "category1"
        category.setActions([justInformAction,secAction], forContext: .Default)
       
        
        let newNotificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: [category])
        
        UIApplication.sharedApplication().registerUserNotificationSettings(newNotificationSettings)
    }

安排本地通知

若是你在iOS以前的版本中使用過本地通知的話,你必定知道安排一個通知是很簡單地事情。在iOS8,安排一個通知並無什麼變化。事實上,全部的基本設置都是如出一轍的。惟一的新東西就是必須給一個通知設置一個類目,這樣通知就能知道當用戶點擊的時候該啓動哪些動做了。

咱們會定義一個新的方法來配置和安排一個本地通知。在咱們實現這個方法以前,咱們先看看一個本地通知中得重要屬性:

  1. fireDate:一個通知應當被顯示的日期和時間。NSDate對象。

  2. alertBody:通知的內容。應當儘可能的簡潔明瞭,這樣用戶才能立刻理解它。

  3. alertAction:在默認狀況下,點擊一個banner通知會致使App啓動。在以alert形式顯示的通知中,會建立一個和這個動做對應 的按鈕。在此屬性中,你必須指定這個按鈕的標題。

  4. 。。。等等

如今放咱們定義這個方法配置這個通知。不用說先讓咱們建立一個UILocalNotification對象

func scheduleLocalNotification(){
        let localNotification = UILocalNotification()
        localNotification.fireDate = NSDate()
        localNotification.alertBody = "Hellor World"
        localNotification.alertAction = "View"
        //咱們必須指定用戶點擊通知後對應的類目動做。回憶一下,咱們前面已經定義了一個類目和類目標示符,咱們在這裏就能使用到這個標示符了
        localNotification.category = "category1"
        //最後,咱們須要使用UIApplication的scheduleLocalNotification(_:) 方法來真正的安排一個通知,否則這個通知永遠都不會「通知」到你啦。
        UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
    }

處理通知動做

如今關於通知,咱們只差最後一個部分了,那就是處理用戶點擊通知相關按鈕時候的各類動做。和往常同樣,這裏有幾個主要的委託方法咱們須要實現。

介紹幾個代理方法,經過他們你能夠方便的開發你的App。

func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {
        
    }

第一個代理方法是關於通知設置的。這個代理方法在程序啓動時被調用(不論是正常啓動仍是經過一個本地通知),包含了全部App通知的設置選項。

經過上述的方法,你能夠獲得全部UIUserNotificationSettings支持的類型。當你須要檢查你的App所支持的通知和動做的類型時,這個方法很是有用。別忘了,用戶能夠經過用戶設置來改變通知類型,因此咱們不能保證,初始的通知類型一直都有效。

  1. 當你安排了一個通知以後,不管你的App是否在運行,這個通知都將被推送。一般狀況下,開發者設置通知如何在App沒有運行或者被掛起的時候被推 送,全部的代碼實現也聚焦在這兩個方面。可是,咱們也應該處理當App在運行時通知如何被處理。感謝蘋果,iOS SDK讓這變得很是簡單,有一個代理方法正能夠處理這種狀況:

func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) {
        
    }

固然在某些狀況下在App運行時你並不須要處理通知。可是在另一個狀況下,上面的代理方法是處理通知動做的地方。

如今讓咱們來看看當用戶點擊了一個通知動做按鈕後將會調用的代理方法。更具咱們給動做設置的標示符(identifier),咱們決定那個動做被調用,而後App就會執行對應的代碼了。

咱們將根據identifier的值給每一種狀況發送一個 NSNotification,在ViewController類中,咱們監視這些NSNotification,而後咱們處理他們。

讓咱們重新的代理方法開始:

func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forLocalNotification notification: UILocalNotification, completionHandler: () -> Void) {
        if identifier == "secAction"{
         NSNotificationCenter.defaultCenter().postNotificationName("secaction", object: nil)
        }
        
        completionHandler()
    }

在上述幾種狀況中咱們根據動做的的標示符,發送不一樣名稱的NSNotification對象。注意到,咱們在方法的結束調用了 completionHandler()方法,根據規定咱們必須調用它,這樣系統才能知道咱們已經處理完了通知動做。在處理本地通知時,這個代理方法很是 重要,在這裏你經過用戶的點擊執行相應地代碼。

接下來,讓咱們打開ViewController.swift文件。首先,讓咱們監視咱們以前發送的NSNotification。在viewDidLoad中加入下面的代碼:

NSNotificationCenter.defaultCenter().addObserver(self, selector: "secAction", name: "secaction", object: nil)

secAction是咱們本身要實現的方法。

func secAction(){
        print("我是 notification 激活的方法")
    }

到這裏咱們的基本介紹就完了。

如何在 iOS 8 中使用 Swift 實現本地通知(上)

如何在 iOS 8 中使用 Swift 實現本地通知(下)

參考

作好了本地推送不是否是也要考慮一下遠程的推送。

推送筆記

相關文章
相關標籤/搜索