对于一些需要在程序启动或者在前后台切换的时刻进行的操作, 理解UIApplicationDelegate会在什么时候触发以及触发的顺序很重要.
1. 正常启动app或者杀死进程后点击推送消息启动app
1. application:willFinishLaunchingWithOptions
2. application:application:didFinishLaunchingWithOptions
3. applicationDidBecomeActive
4. application:didRegisterForRemoteNotificationsWithDeviceToken
注:程序正常启动是不会调用applicationWillEnterForeground的, 这点很重要.
2. 双击Home键进入多任务界面/拖下通知中心/拖上控制中心(iOS7新增)/删除PHAsset时系统弹出的确认删除alert(iOS8新增)
applicationWillResignActive
3. 从多任务界面复原/拖上通知中心/拖下控制中心/dismiss掉删除PHAsset的alert
applicationDidBecomeActive
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:.
参考: