对于一些需要在程序启动或者在前后台切换的时刻进行的操作, 理解UIApplicationDelegate会在什么时候触发以及触发的顺序很重要.
1. 正常启动app或者杀死进程后点击推送消息启动app
1. application:willFinishLaunchingWithOptions
2. application:application:didFinishLaunchingWithOptions
3. applicationDidBecomeActive
4. application:didRegisterForRemoteNotificationsWithDeviceToken
注:程序正常启动是不会调用applicationWillEnterForeground的, 这点很重要.
2. 双击Home键进入多任务界面/拖下通知中心/拖上控制中心(iOS7新增)/删除PHAsset时系统弹出的确认删除alert(iOS8新增)/弹出Touch ID alert
applicationWillResignActive
3. 从多任务界面复原/拖上通知中心/拖下控制中心/dismiss掉删除PHAsset的alert/dismiss Touch ID alert
applicationDidBecomeActive
如果你在applicationDidBecomeActive中调用evaluatePolicy:localizedReason:reply弹出Touch ID验证alert的话, 如果用户点击了Cancel, 那么就进入了死循环: cancel掉Touch ID的alert会触发applicationDidBecomeActive, 程序在applicationDidBecomeActive中弹出Touch ID, 用户点击Cancel...... 所以考虑把Touch ID验证放在applicationWillEnterForeground中. 但问题来了, 如果另外一个app使用openURL方式跳到本app(见第8条), 本app做一下处理后再跳回到跳到本程序的那个app. 这个场景下, 是不能弹出Touch ID的, 但是上面提到Touch ID是在applicationWillEnterForeground中调用的, 那时还尚未调用application:openURL:sourceApplication:annotation:, 程序不知道自己是正常启动还是被其他app使用openURL打开的, 怎么办? 解决方法有两个:
首先, 在application:openURL:sourceApplication:annotation:中设置标志位是必须的.
1. 如果本app做的处理不耗时的话, 例如只是保存个图片什么的, 耗时一般不会超过1秒, 可以考虑在applicationWillEnterForeground中等待一小段时间后判断是不是openURL启动的, 再弹出Touch ID.
2. 把Touch ID放到applicationDidBecomeActive, 设置标志位, 比如起名_ignoreNextApplicationDidBecomeActive. 在reply回调中, 判断用户是否点击了Cancel, 如果是的话, 将该标志位赋为YES. 下次进入applicationDidBecomeActive判断该标志位如果为YES, 将该标志位设为NO; 如果为NO, 则弹出Touch ID.
4. 按Home键使app进入后台/按电源键关闭屏幕
1. applicationWillResignActive
2. applicationDidEnterBackground
5. app从后台恢复到前台(点击app图标或者从多任务中调出)/按电源键或Home键唤醒屏幕并让程序进入前台
1. applicationWillEnterForeground
2. applicationDidBecomeActive
6. 点击通知中心里的远程推送, 使app进入前台
1. applicationWillEnterForeground
2. application:didReceiveRemoteNotification
3. applicationDidBecomeActive
注
:
当程序处于后台时,点击推送消息进入前台会执行
application:didReceiveRemoteNotification
,但直接点击推送消息启动
App
是不会执行该
didReceiveRemoteNotification
的,在
didFinishLaunchingWithOptions
的
options
里面已经有数据表明当前是直接启动还是点击推送消息启动,localNotification与remote类似,略。
7. 删除app
applicationWillTerminate
8. 其他app通过使用openURL方式跳到本程序
1. applicationWillEnterForeground
2. application:openURL:sourceApplication:annotation:
3. applicationDidBecomeActive
如果需要判断本次进入前台是否是openURL造成的, 不能在applicationWillEnterForeground中判断, 因为此时application:openURL:sourceApplication:annotation:还没有被调用. 可以在application:openURL:sourceApplication:annotation:中设置一个标志位, 然后在applicationDidBecomeActive中判断. 我写这篇文章除了第二点中的删除PHAsset外就是因为这个问题了.
9. 电话接入
app在前台如果有电话打入,applicationWillResignActive会被调用, 如果用户接听了电话, applicationDidEnterBackground会被调用, 如果用户拒接, applicationDidBecomeActive会被调用.
你有5秒时间来执行applicationDidEnterBackground并在5秒内返回, 否则程序会被系统杀掉, 如果需要更长时间, 可以使用beginBackgroundTaskWithExpirationHandler:.
参考:
http://www.cnblogs.com/gugupluto/p/3442191.html(必须承认, 部分内容都是从这里抄的)
龙西村原创, 转载请注明出处.