从iOS8开始,本质上来讲有两种通知:html
本地通知(local notifications):由开发者定义,App触发。触发的时间是被事先安排好的。ios
远程通知(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
Alert or Banner:通知能够用alert或者banner来显示,这取决于用户在设置中得选择。数组
Sound: 当一个通知被送达时,你能够‘告诉’iOS播放一段自定义或者系统默认的声音。服务器
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
类的对象。UIMutableUserNotificationAction
是iOS8
新引入的类,有着许多有用的配置属性:
标示符(identifier): 字符串,标示了一个对于整个App惟一的字符串。很明显,你永远不该该在同一个App中定义两个一样地标示符。经过此标示符,咱们能够决定在用户点击不一样的通知时,调用哪一个动做。
标题(title):用来在展现给用户的动做按钮上。能够是简单地或者本地化的字符串。为了让用户能立刻理解动做的含义,必定要仔细考虑这个标题的值,最好是1到2个字符。
destructive: 布尔值。当设置为true时,通知中相应地按钮的背景色会变成红色。这只会在banner通知中出现。一般,当动做表明着删除、移除或者其余关键的动做是都会被标记为destructive以得到用户的注意。
authenticationRequired: 布尔值。当设置为true时,用户在点击动做以前必须确认本身的身份。当一个动做十分关键时这很是有用,由于为认证的操做有可能会破坏App的数据。
ActivationMode: 决定App在通知动做点击后是应该被启动仍是不被启动。
behavior: iOS9 新特性 能够支持在用户通知中输入文本
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显示时的上下文,有两个值:
Default
: 在屏幕的中央展现一个完整的alert。(未锁屏时)
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,安排一个通知并无什么变化。事实上,全部的基本设置都是如出一辙的。惟一的新东西就是必须给一个通知设置一个类目,这样通知就能知道当用户点击的时候该启动哪些动做了。
咱们会定义一个新的方法来配置和安排一个本地通知。在咱们实现这个方法以前,咱们先看看一个本地通知中得重要属性:
fireDate:一个通知应当被显示的日期和时间。NSDate对象。
alertBody:通知的内容。应当尽可能的简洁明了,这样用户才能立刻理解它。
alertAction:在默认状况下,点击一个banner通知会致使App启动。在以alert形式显示的通知中,会建立一个和这个动做对应 的按钮。在此属性中,你必须指定这个按钮的标题。
。。。等等
如今放咱们定义这个方法配置这个通知。不用说先让咱们建立一个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所支持的通知和动做的类型时,这个方法很是有用。别忘了,用户能够经过用户设置来改变通知类型,因此咱们不能保证,初始的通知类型一直都有效。
当你安排了一个通知以后,不管你的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 激活的方法") }
到这里咱们的基本介绍就完了。