iOS之UIApplicatio、AppDelegate
UIApplication,代表的是整个应用做的事,因此每个程序只能有一个,系统使用的是单例模式,就是[UIApplication sharedApplication]来得到一个实例。
这个单例实例是在系统启动时由main函数里面的UIApplicationMain方法生成,就是每个程序里都有的AppDelegate,它实现了UIApplicationDelegate的Protocol,也就是AppDelegate的一个实例。每次通过[UIApplication sharedApplication]调用的就是它。
创建应用程序之后之后,默认有AppDelegate.h文件与AppDelegate.m文件。
AppDelegate为整个应用的一个代理,提供程序启动、退出等类似监控的接口。
AppDelegate.m
//1.应用程序启动后,执行的代理方法
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
在这个方法中设置程序启动的根控制器,设置程序是否锁屏,进行网络判断等一进入程序就要做的事情
//2.应用程序将要由活动状态切换到非活动状态时执行的方法,如按下home按钮,返回主屏幕,或全屏之间切换程序等。
- (void)applicationWillResignActive:(UIApplication *)application;
//3.在应用程序已被激活后,要执行的委托调用,刚好与 applicationDidEnterBackground 方法相对应。
- (void)applicationDidBecomeActive:(UIApplication *)application;
//4.应用程序进入后台程序时,要执行的方法。所以要设置后台继续运行,在这个函数里面设置
当用户从台前状态转入后台时,调用此方法。使用此方法来释放资源共享,保存用户数据,无效计时器,并储存足够的应用程序状态信息的情况下被终止后,将应用 程序恢复到目前的状态。如果您的应用程序支持后台运行,这种方法被调用,否则调用applicationWillTerminate:用户退出。
- (void)applicationDidEnterBackground:(UIApplication *)application;
//5.应用程序进入前台执行的方法,与applicationWillResignActive 方法相对应。
当应用在后台状态,将要进行动前台运行状态时,会调用此方法。
如果应用不在后台状态,而是直接启动,则不会回调此方法。
- (void)applicationWillEnterForeground:(UIApplication *)application;
//6.应用程序将要完全退出的时候调用,通常用来保存数据和一些退出前的清理工作,这个需要设置UIApplicationExitsOnSuspend的键值
说明:iPhone设备只有有限的内存,如果为应用程序分配了太多内存操作系统会终止应用程序的运行,在终止前会执行这个方法,通常可以在这里进行内存清理工作防止程序被终止 在这个方法中做一些数据存储的操作
- (void)applicationWillTerminate:(UIApplication *)application;
//7.当系统时间发生改变的时候执行
- (void)applicationSignificantTimeChange:(UIApplication*)application;
//8.程序收到系统内存警告的时候调用
iPhone设备只有有限的内存,如果为应用程序分配了太多内存操作系统会终止应用程序的运行,在终止前会执行这个方法,通常可以在这里进行内存清理工作防止程序被终止。
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application;
//9.当通过URL执行某些操作的时候调用 这个方法已经不在支持,可能会在以后的某个版本中去掉,用下面的方法代替
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url;
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation NS_DEPRECATED_IOS(4_2, 9_0, "Please use application:openURL:options:") __TVOS_PROHIBITED
//当用户通过其它应用启动本应用的时候,会回调这方法,URL参数是其它应用调用openURL:方法时传过来的
//10、说明:当StatusBar框将要变化时执行
- (void)application:(UIApplication)application willChangeStatusBarFrame:(CGRect)newStatusBarFrame
{
NSLog(@"StatusBar框将要变化");
}
//11、说明:当StatusBar框方向将要变化时执行
- (void)application:(UIApplication*)application willChangeStatusBarOrientation:
(UIInterfaceOrientation)newStatusBarOrientation duration:(NSTimeInterval)duration
{
}
//12、说明:当StatusBar框方向变化完成后执行
- (void)application:(UIApplication*)application didChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientation
{
}
//13、说明:当StatusBar框变化完成后执行
- (void)application:(UIApplication*)application didChangeSetStatusBarFrame:(CGRect)oldStatusBarFrame
{
}
//协议方法 Handling Remote Notifications (处理远程消息)
// 当一个运行着的应用程序收到一个远程的通知 发送到这个方法
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo;
//客户端注册远程通知的时候,会回掉下面两个方法,如果成功,回掉第一个,客户端把deviceToken取出来发给服务端,Push消息的时候要用 如果失败,回调第二个,可以从error参数中看一下失败的原因
//当一个应用程序成功的注册一个推送服务(APS) 发送到代理方法
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken;
//当APS无法成功的完成向程序进程推送时 发送到代理方法
-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
注:注册远程通知使用如下方法:
UIRemoteNotificationType t=UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeSound; [[UIApplication sharedApplication] registerForRemoteNotificationTypes:t];
//Handling Local Notification (处理本地消息)
当应用在前台运行中,收到远程通知时,会回调这个方法。
当应用在后台状态时,点击push消息启动应用,也会回调这个方法。
– (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification NS_AVAILABLE_IOS(4_0);
当应用收到本地通知时会调这个方法,同上面一个方法类似。
如果在前台运行状态直接调用,如果在后台状态,点击通知启动时,也会回调这个方法
本地通知可见另一篇文章:http://bluevt.org/?p=70
Responding to Content Protections Changes(响应受保护内容的改变)-applicationProtectedDataWillBecomeUnavailable:
说明:通知委托,受保护的文件当前变为不可用的
-applicationProtectedDataWillBecomeAvailable:
说明:通知委托 受保护的文件当前变为可用
全局变量
AppDelegate可以在整个应用程序中调用,在其他页面中可以使用代码段获取AppDelegate的全局变量:AppDelegate *appDelegate=[[UIApplication sharedApplication] delegate]; 因此可以在AppDelegate.h中定义需要全局使用的变量
iPhone中的应用程序很容易受到打扰,比如一个来电可能导致应用程序失去焦点,如果这个时候接听了电话,那么应用程序会转到后台运行。
还有很多其它类似的事件会导致iPhone应用程序失去焦点,在应用程序失去焦点前会调用委托类的applicationWillResignActive()方法,
而应用程序再次获取到焦点的时候会调用applicationDidBecomeActive()方法。
比如在运行应用程序的时候锁屏会调用委托类的applicationWillResignActive()方法,而当屏幕被解锁的时候,又会调用applicationDidBecomeActive()方法。
另外一个非常重要的方法就是applicationDidReceiveMemoryWarning(),因为iPhone设备只有有限的内存,如果为应用程序分配了太多内存操作系统会终止应用程序的运行,但在终止之前操作系统会通过先调用委托类的applicationDidReceiveMemoryWarning()方法警告应用程序,在UIApplication接收到这个事件后它会传递给委托类的applicationDidReceiveMemoryWarning()方法,委托类在这个方法内可以进行释放内存的操作以防止操作系统强制终止应用程序的运行。
下面是这个类的一些功能:
1.设置icon上的数字图标
//设置主界面icon上的数字图标,在2.0中引进, 缺省为0
[UIApplication sharedApplication].applicationIconBadgeNumber = 4;
2.设置摇动手势的时候,是否支持redo,undo操作
//摇动手势,是否支持redo undo操作。
//3.0以后引进,缺省YES
[UIApplication sharedApplication].applicationSupportsShakeToEdit =YES;
3.判断程序运行状态
4.阻止屏幕变暗进入休眠状态
//阻止屏幕变暗,慎重使用,缺省为no 2.0
[UIApplicationsharedApplication].idleTimerDisabled =YES;
慎重使用本功能,因为非常耗电。
5.显示联网状态
//显示联网标记 2.0
[UIApplication sharedApplication].networkActivityIndicatorVisible =YES;
6.在map上显示一个地址
7.发送电子邮件
8.打电话到一个号码
// Call Google 411
[[UIApplication sharedApplication]openURL:[NSURLURLWithString:@"tel://8004664411"]];
9.发送短信
// Text to Google SMS
[[UIApplication sharedApplication]openURL:[NSURLURLWithString:@"sms://466453"]];
10.检查能否打开某个URL,并且打开URL;这个功能可以配合应用的自定义URL功能,来检测是否安装了某个应用。比如检测是否安装了淘宝的应用,可以用下面的代码:
//11.防止程序锁屏
UIApplication
AppDelegate:负责为另外一个对象处理特定事件的类,比如我们load完一个页面的时候,代理就帮助UIApplication完成
didFinishLaunchingWithOptions动作,相应地在这个方法里面执行对应地action;
代理是给一个对象提供机会对另一个对象中的变化作出反映或者影响另一个对象的行为,通常包括3种动词:should、will、did
UIApplication委托AppDelegate,则AppDelegate必须得实现UIApplicationDelegate协议,这个协议我们可以当成是java中的一个接口,
协议中定义了一系列方法,我们必须在子类中将其实现,然后底层UIApplication会自动去调用我们已经定义好的方法,这有点类似java中Ioc方向控制机制
当然,iphone中运用委托设计模式的地方很多,比如这个UIActionSheetDelegate、UIAlertViewDelegate协议,比如我们要在自己的某个界面中展示
这个操作表(UIActionSheet),则我们的视图控制器必须要实现这个UIActionSheetDelegate协议,重写其中的某些方法,也就是说,谁被委托了,
谁就要实现协议中定义的方法,确保正常的调用