您的位置:首页 > 移动开发

iOS-UIApplicationDelegate学习笔记

2016-03-13 15:49 232 查看
UIApplicationDelegate协议定义了很多方法,这些方法将会在你的App的生命周期中发生重要的事件时被一个单例对象UIApplication所调用。

该delegate的一些方法使得我们可以在应用状态发生变化时做一些处理操作。比如说,当应用从前台变到后台执行,就会有对应的方法被调用来响应该状态的变化。在很多情况下,这个delegate将是获得这些变化的通知的唯一方法。

根据官方文档描述,app delagate应该扮演一下的关键角色:

包含应用启动代码;

响应app的关键变化。明确说就是,应该响应一些暂时的异常和执行状态的改变等事件,比如说你的应用从前台切换到了后台。

响应别的应用发来的通知,比如说远程通知(推送通知),低内存警告,下载完成通知等等。

决定是否需要保存应用状态或信息。

响应app自身的事件。

可以存储应用的核心数据对象和内容,而不需要拥有任何view controller对象。

应用的启动

一个应用的生命周期中很重要的一部分就是启动时。因为在启动期间,应用会执行很多特定的代码去初始化你的应用。下面是一些在启动阶段会执行的操作:

查看启动选项参数(launchOptions)中的dictionary对象,判断应用是为何为启动。
application:willFinishLaunchingWithOptions:
application:didFinishLaunchingWithOptions:
方法都提供了一个包含启动信息的字典对象,通过查看该对象可以知道应用启动的原因。

决定时都需要存储应用状态。如果应用先前保存过视图控制器的状态的话,那么只需要在
application:shouldRestoreApplicationState:
方法返回YES的时候再重新存储视图控制器的状态。

注册推送通知服务。为了接受远程推送通知服务,app必须要通过调用
registerForRemoteNotificationTypes:
方法来注册远程通知服务。

打开一个URL请求。如果有URL需要被访问,系统则会调用
application:openURL:options:
方法。首先必须要在app的Info.plist文件中添加CFBundleURLType键来声明URL。

给应用提供一个根窗口(root window)对象。从技术上讲,默认情况下Xcode已经自动实现了window的属性赋值,如果你不需要定制自己的应用窗口的话则不需要做任何别的操作。

application:willFinishLaunchingWithOptions:
application:didFinishLaunchingWithOptions:
方法传递的launchOptions字典参数中包含了很多与app相关的重要启动信息。字典中的信息说明了app启动的原因,从而你有机会更具不同的原因作出启动处理的调整。例如,你的app是因为一个即将到来的远程通知而需要启动,那么你可能就想先配置一些与交互界面相关的数据。

以下就是一些启动原因。

NSString *const UIApplicationLaunchOptionsURLKey;
NSString *const UIApplicationLaunchOptionsSourceApplicationKey;
NSString *const UIApplicationLaunchOptionsRemoteNotificationKey;
NSString *const UIApplicationLaunchOptionsLocalNotificationKey;
NSString *const UIApplicationLaunchOptionsAnnotationKey;
NSString *const UIApplicationLaunchOptionsLocationKey;
NSString *const UIApplicationLaunchOptionsNewsstandDownloadsKey;
NSString *const UIApplicationLaunchOptionsBluetoothCentralsKey;
NSString *const UIApplicationLaunchOptionsBluetoothPeripheralsKey;
NSString *const UIApplicationLaunchOptionsShortcutItemKey;
NSString *const UIApplicationLaunchOptionsUserActivityDictionaryKey;
NSString *const UIApplicationLaunchOptionsUserActivityTypeKey;


状态转换管理

app delegate一个主要的工作就是响应系统通知的应用状态转换事件。对于发生的每个状态转换事件,系统都会调用app delegate中响应的方法。

Not running。应用没启动或已终止。

Inactive。app在前台运行,但是不接收事件。通常情况app都只是在它转换到别的状态之前在这个阶段短暂停留了一会。

Active。app在前台运行,并接收事件。这是一个在前台运行的app的一般状态。一个在激活状态的app不会被其他东西所约束,因为他是前台运行的应用所以它就应该只负责响应用户的操作。

Background。app可以执行代码,但是不可见。当用户退出app,系统就会将app短暂的切换到后台状态,然后再进入暂停状态。一个处于后台状态的app应该尽可能少的执行任务。

Suspended。app在内存中但不执行代码。系统会暂停那些进入后台状态的app,并且不会再调度它们完成任务任务。并且系统可能会移除暂停状态的app,为其他应用腾空间。



下面这些方法就是在状态转换时会调用的。

启动阶段

application:willFinishLaunchingWithOptions:

application:didFinishLaunchingWithOptions:

切换到前台

applicationDidBecomeActive:

切换到后台

applicationDidEnterBackground:

切换到非活动状态

applicationWillResignActive: (活动状态切换到非活动状态)

applicationWillEnterForeground:(后台状态切换到非活动状态)

终止状态

applicationWillTerminate:

下面我们来看一个很简单的小例子。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSLog(@"%@", NSStringFromSelector(_cmd));
return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application {
NSLog(@"%@", NSStringFromSelector(_cmd));
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
NSLog(@"%@", NSStringFromSelector(_cmd));
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
NSLog(@"%@", NSStringFromSelector(_cmd));
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
NSLog(@"%@", NSStringFromSelector(_cmd));
}

- (void)applicationWillTerminate:(UIApplication *)application {
NSLog(@"%@", NSStringFromSelector(_cmd));
}


然后我们就会看到这样一个输出过程。其中刚初始化完时时只有前两句输出的。当我们按了home键关闭返回主界面时,就会输出3,4句的结果。当我们通过双击home上滑把应用删除后,按道理来说就会执行
applicationWillTerminate:
方法。

2016-03-13 14:14:04.926 UIApplicationDelegateDemon[1323:75394] application:didFinishLaunchingWithOptions:
2016-03-13 14:14:04.930 UIApplicationDelegateDemon[1323:75394] applicationDidBecomeActive:
2016-03-13 14:14:09.892 UIApplicationDelegateDemon[1323:75394] applicationWillResignActive:
2016-03-13 14:14:10.482 UIApplicationDelegateDemon[1323:75394] applicationDidEnterBackground:


我们对
didFinishLaunchingWithOptions
稍作修改。这样就是在判断应用启动的理由,并做一些相应的处理的方式。当然我们这里只是简单判断了三种启动方式而已。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSLog(@"%@", NSStringFromSelector(_cmd));

//说明,如果应用是用户直接启动,则launchOptions内无数据。

//如果是通过别的应用启动的,则输出对应启动源应用的 Bundle ID
NSString *bundleId = [launchOptions objectForKey:UIApplicationLaunchOptionsSourceApplicationKey];
if (bundleId) {
NSLog(@"%@", bundleId);
}

//如果是打开一个URL,则输出需要被打开的URL信息
NSURL *url = [launchOptions objectForKey:UIApplicationLaunchOptionsURLKey];
if (url) {
NSLog(@"%@", url);
}

//如果是通过本地通知启动的应用,则输出通知相关信息
UILocalNotification *localNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (localNotification) {
NSLog(@"Title: %@; Body:%@", [localNotification alertTitle],  [localNotification alertBody]);
}

return YES;
}


参考资料

苹果官方文档
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  delegate 应用 文档 app