概述
iOS有3种nofitication:
- NSNotification: app可以广播到本app里面所有可能的接收者,当app在前台的时候,iOS同样用这类广播来通知app系统的消息,比如键盘显示或者隐藏
- UILocalNotification: 即使app在后台或者完全没有运行,也可以收到,比如:你想在某一个特别的时间唤醒你的app,可以用这类notification
- push notification: 通过一个服务器送给iOS设备
16.1 发送notification
一个notification有3个重要的属性:
- Name:一个字符串,notification的收,发是通过name来做匹配
- Sender:一般是self,只要是收的那一边,可以多做一个判断,比如: 有2个sender都发了相同name的notification,那么可以只接收其中某一个的
- User info dictionary: 可以传一个字典
let notificationName = "NotificationNameGoHere"
override func viewDidLoad() {
super.viewDidLoad()
let notification = NSNotification(name: notificationName, object: self, userInfo: ["Key1" : "Value1", "Key2" : 2])
NSNotificationCenter.defaultCenter().postNotification(notification)
}
16.2 收notification
通过调用addObserver:selector:name:object: 方法, 有4个属性要注意:
- addObserver: 接收notification的对象
- selector: 函数,有一个参数是NSNotification
- name:想要接收的notification的名字
- object: 送notification的对象
如果不想接收了,调用NSNotificationCenter的removeObserver, observer的类必须要继承于NSObject
class Person:NSObject {
var firstName: NSString?
var lastName:NSString?
func handleSendPersonInfoNotification(notification:NSNotification) {
firstName = notification.userInfo![AppDelegate.personInfoKeyFirstName()] as! String
lastName = notification.userInfo![AppDelegate.personInfoKeyLastName()] as! String
}
override init() {
super.init()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "handleSendPersonInfoNotification:", name: AppDelegate.SendPersonInfoNotification, object: UIApplication.sharedApplication().delegate)
}
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
}
16.3 接收键盘的notification
键盘的notification:
- UIKeyboardWillShowNotification: 键盘将要显示,携带user-info
- UIKeyboardDidShowNotification: 键盘已经显示
- UIKeyboardWillHideNotification:键盘将要消失,携带user-info
- UIKeyboardDidHideNotification:键盘已经消失
在user-info里面,有一些需要Key注意: - UIKeyboardAnimationCurveUserInfoKey : 动画的曲线的类型,返回是一个anyobject,要先转为NSValue,然后取得一个NSUInteger
- UIKeyboardAnimationDurationUserInfoKey: 动画持续的时间,返回是一个anyobject,要先转为NSValue,然后取得一个double
- UIKeyboardFrameBeginUserInfoKey: 键盘的frame,如果键盘即将显示,那就是键盘显示之前的frame,如果键盘已经显示,将要隐藏,那么就是键盘显示的frame,返回是一个anyobject,要先转为NSValue,然后取得一个CGRect
- UIKeyboardFrameEndUserInfoKey:动画结束后的键盘frame
16.4 local notification
如果你在做一个闹钟或者一个日历app,需要在你的app没有运行的时候,提醒用户,需要用到。步骤:
- registerUserNotificationSettings: 首先要注册一个notification,iOS会弹出一个框让用户接受或拒绝。
- scheduleLocalNotification: 在用户选择了以后,会调用 func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings),在这个函数里面scheduleLocalNotification
- 然后当schedule的时间到了以后,会调用 func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification)
UIApplication.sharedApplication().scheduleLocalNotification(notification)
let settings = UIUserNotificationSettings(forTypes: .Alert | .Badge, categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
一个UILocalNotification有许多属性:
- fireDate: 一个NSDate类型,告诉iOS什么时候notification被触发
- timeZone: 一个NSTimeZone类型,你可以取得当前的timezone,通过NSCalendar的timeZone函数
- alertBody: 一个NSString类型,表示当notification触发时,显示的字符串
- hasAction: 一个Bool类型,告诉iOS,当notification的时候,你的app是否想要有动作,如果是true,iOS会显示你的alertAction给用户,如果是false,只会显示有一个notification到了。
- alertAction:一个国际化的字符串
- applicationIconBadgeNumber: 如果local notification需要更改你的app icon上的小红点上的值,设置这个值,必须是int。iOS会做加1的动作。你可以取到当前icon上的值, 用UIApplication的applicationIconBadgeNumber属性。
- userInfo: 字典,当notification产生的时候,可以传给app。
hasAction 和 alertAction 属性容许用户去在notification certer打开你的local notificaiton,让iOS开启你的app。
以下实现了app在后台的时候,系统发送notification:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
//First ask the user if we are allowed to perform local notifications
let settings = UIUserNotificationSettings(forTypes: .Alert, categories: nil)
application.registerUserNotificationSettings(settings)
return true
}
func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {
//The user did not allow us to send notifications
if notificationSettings.types == nil {
return
}
let notification = UILocalNotification()
notification.fireDate = NSDate(timeIntervalSinceNow: 8)
notification.timeZone = NSCalendar.currentCalendar().timeZone
notification.alertBody = "A new item is downloaded"
notification.hasAction = true
notification.alertAction = "View"
notification.applicationIconBadgeNumber++
notification.userInfo = [
"Key 1" : "Value 1",
"Key 2" : "Value 2"
]
application.scheduleLocalNotification(notification)
}
16.5 app在前台的时候,发local notification
local notification发生的情况:
- app在前台: local notification发生后,application:didReceiveLocalNotification:方法会被调用
- app在后台:当用户点击notification,app被调用,到前台,然后application:didReceiveLocalNotification:方法会被调用,如果不点击,就不会被调用
- app没开:首先app要先开过一次,notification被注册过,然后app被关掉或者没有active,到了app的notification定义的时间,iOS会弹出提示,如果用户点击,那么app会被唤醒。didFinishLaunchingWithOptions的launchOptions传入UIApplicationLaunchOptionsLocalNotification。
- 设备锁屏: 没有特别的地方,看app在以上上面哪种状况下,就按照上面的状况处理。
tips: 双击home键: shift+commend+h,shift+commend按住不放,h按2次。
16.6 系统的notification
当你的app在前台的时候,想要取得系统的notification。
以下是一些比较重要的系统notification:
- NSCurrentLocaleDidChangeNotification: locale改变,比如:用户把语言从英文变成中文
- NSUserDefaultsDidChangeNotification: 用户改变了app的设置,在setting里面, notification会返回一个NSUserDefaults
func handleSettingsChanged(notification: NSNotification)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "handleSettingsChanged:", name: NSUserDefaultsDidChangeNotification, object: nil)
- UIDeviceBatteryStateDidChangeNotification: 当电池状态改变的时候,比如设备插入电脑,可以读UIDevice的batteryState来获得电量
- UIDeviceProximityStateDidChangeNotification: 当距离sensor改变状态的时候,可以读UIDevice的proximityState,来取得距离sensor的值
- UIDeviceOrientationDidChangeNotification: 旋转
当app在后台的时候,notification会不会发过来的,但是会存起来,当app在前台的时候发过来。如果app竖屏在后台,然后转了4次,又回到竖屏,不会有nitification。
NSNotificationCenter.defaultCenter().addObserver(self, selector: "orientationChanged:", name: UIDeviceOrientationDidChangeNotification, object: nil)
16.7/8/9 push notification
让你的app接受服务器的push notification,步骤:
- 设置provision profile,enable push notification;
- 在app里面,注册,iOS会弹出一个框,让用户确认;
application.registerForRemoteNotifications()
- 收集设备的push notifications identifier,发给服务器
- 实现回调函数
application:didRegisterForRemoteNotificationsWithDe viceToken:
application:didFailToRegisterForRemoteNotifications WithError:
t.b.d