你真的了解UIApplication吗?
一:首先查看一下关于UIApplication的定义
NS_CLASS_AVAILABLE_IOS(2_0) @interface UIApplication : UIResponder //获得单例对象 + (UIApplication *)sharedApplication NS_EXTENSION_UNAVAILABLE_IOS("Use view controller based solutions where appropriate instead."); //委托 @property(nullable, nonatomic,assign) id<UIApplicationDelegate> delegate; //暂停触摸事件 - (void)beginIgnoringInteractionEvents NS_EXTENSION_UNAVAILABLE_IOS(""); // 告诉接受者继续处理 touch相关的事件 - (void)endIgnoringInteractionEvents NS_EXTENSION_UNAVAILABLE_IOS(""); // 是否忽略交互事件 - (BOOL)isIgnoringInteractionEvents; //阻止屏幕变暗进入休眠状态 ,耗电,慎重默认NO @property(nonatomic,getter=isIdleTimerDisabled) BOOL idleTimerDisabled; // 通过特定的URL中打开资源 - (BOOL)openURL:(NSURL*)url NS_EXTENSION_UNAVAILABLE_IOS(""); // 返回一个bool值, 是否从已经安装的 apps 中跳转 - (BOOL)canOpenURL:(NSURL *)url NS_AVAILABLE_IOS(3_0); // 发送事件给app内适用的响应者 - (void)sendEvent:(UIEvent *)event; // app的主 window 只读 @property(nullable, nonatomic,readonly) UIWindow *keyWindow; // 隐藏的和看得见的所有 window @property(nonatomic,readonly) NSArray<__kindof UIWindow *> *windows; // 发送一个含选择器的动作消息到指定的目标 - (BOOL)sendAction:(SEL)action to:(nullable id)target from:(nullable id)sender forEvent:(nullable UIEvent *)event; // 是否显示网络正在活动,默认是NO @property(nonatomic,getter=isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible; //状态栏样式 @property(readonly, nonatomic) UIStatusBarStyle statusBarStyle; // default is UIStatusBarStyleDefault //状态栏隐藏 @property(readonly, nonatomic,getter=isStatusBarHidden) BOOL statusBarHidden; //屏幕旋转方向 @property(readonly, nonatomic) UIInterfaceOrientation statusBarOrientation; // 在指定的窗口中, 返回默认的视图控制器方向接口 - (UIInterfaceOrientationMask)supportedInterfaceOrientationsForWindow:(nullable UIWindow *)window NS_AVAILABLE_IOS(6_0); // 状态栏动画持续时间 @property(nonatomic,readonly) NSTimeInterval statusBarOrientationAnimationDuration; // 获取状态栏的 rect @property(nonatomic,readonly) CGRect statusBarFrame; // 未读消息数字,0表示隐藏 @property(nonatomic) NSInteger applicationIconBadgeNumber; // 是否接受摇晃的时候, 展现 撤销和恢复 视图 @property(nonatomic) BOOL applicationSupportsShakeToEdit NS_AVAILABLE_IOS(3_0); // app当前的运行的状态 @property(nonatomic,readonly) UIApplicationState applicationState NS_AVAILABLE_IOS(4_0); // app 在后台运行的时间 @property(nonatomic,readonly) NSTimeInterval backgroundTimeRemaining NS_AVAILABLE_IOS(4_0); //标记开始新的长时间运行的后台任务 - (UIBackgroundTaskIdentifier)beginBackgroundTaskWithExpirationHandler:(void(^ __nullable)(void))handler NS_AVAILABLE_IOS(4_0) NS_REQUIRES_SUPER; // 标记新的长时间运行的任务以及指定任务的命名 - (UIBackgroundTaskIdentifier)beginBackgroundTaskWithName:(nullable NSString *)taskName expirationHandler:(void(^ __nullable)(void))handler NS_AVAILABLE_IOS(7_0) NS_REQUIRES_SUPER; // 结束指定的长时间的后台任务 - (void)endBackgroundTask:(UIBackgroundTaskIdentifier)identifier NS_AVAILABLE_IOS(4_0) NS_REQUIRES_SUPER; // 指定最小时间间隔在后台获取操作 - (void)setMinimumBackgroundFetchInterval:(NSTimeInterval)minimumBackgroundFetchInterval NS_AVAILABLE_IOS(7_0); //进入到后台,是否能够进行后台的操作 @property (nonatomic, readonly) UIBackgroundRefreshStatus backgroundRefreshStatus NS_AVAILABLE_IOS(7_0); @property(nonatomic,readonly,getter=isProtectedDataAvailable) BOOL protectedDataAvailable NS_AVAILABLE_IOS(4_0); // 返回用户界面的布局方向。只读 @property(nonatomic,readonly) UIUserInterfaceLayoutDirection userInterfaceLayoutDirection NS_AVAILABLE_IOS(5_0); // 字体偏好 只读 @property(nonatomic,readonly) NSString *preferredContentSizeCategory NS_AVAILABLE_IOS(7_0); @end
UIApplication的核心作用是提供了iOS程序运行期间的控制和协作工作。它的基类是UIResponder;每一个程序在运行期必须有且仅有一个UIApplication(或则其子类)的一个实例;在程序开始运行的时候,UIApplicationMain函数是程序进入点,这个函数做了很多工作,其中一个重要的工作就是创建一个UIApplication的单例实例。在你的代码中你,你可以通过调用[UIApplication sharedApplication]来得到这个单例实例的指针。UIApplication的一个主要工作是处理用户事件,它会维护一个队列,把所有用户事件都放入队列,逐个处理,在处理的时候,它会发送当前事件到一个合适的处理事件的目标控件。此外,UIApplication实例还维护一个在本应用中打开的window列表(UIWindow实例),这样它就可以接触应用中的任何一个UIView对象。UIApplication实例会被赋予一个代理对象,以处理应用程序的生命周期事件(比如程序启动和关闭)、系统事件(比如来电、记事项警告)等等。
知识点1:属性的运用
//通过sharedApplication获取该程序的UIApplication对象 UIApplication *app=[UIApplication sharedApplication]; app.applicationIconBadgeNumber=100;
知识点2:关于openURL的运用
/* NSURL统一资源定位符 格式 > 协议://路径 */ // 创建UIApplication对象 UIApplication *app = [UIApplication sharedApplication]; // 打电话 tel为打电话协议 [app openURL:[NSURL URLWithString:@"tel://10086"]]; // 发短信 sms为发短信协议 [app openURL:[NSURL URLWithString:@"sms://10086"]]; // 打开网址 http为上网协议 [app openURL:[NSURL URLWithString:@"http://www.ithemima.com"]]; // 发送邮件 mailto为发送邮件协议 [app openURL:[NSURL URLWithString:@"mailto://zhangsan@itcast.cn"]];
知识点3:状态栏的管理从iOS7开始,系统提供了2种管理状态栏的方式
a: 通过UIViewController管理(每一个UIViewController都可以拥有自己不同的状态栏)
b: 通过UIApplication管理(一个应用程序的状态栏都由它统一管理)
在iOS7之后,默认情况下,状态栏都是由UIViewController管理的,若想通过UIApplication进行管理,则需要配置plist文件:View controller-based status bar appearance 设置成NO (默认值为YES)
// 示范代码: // 隐藏系统状态栏 [UIApplication sharedApplication].statusBarHidden = YES; // 设置系统状态栏样式 [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent; // 隐藏系统状态栏带动画 [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide]; // 设置系统状态栏样式带动画 [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];
二:UIApplication (UIRemoteNotifications)分类,处理远程通知
@interface UIApplication (UIRemoteNotifications) //在iOS8中,我们使用新的函数来注册通知 - (void)registerForRemoteNotifications NS_AVAILABLE_IOS(8_0); //关闭推送 - (void)unregisterForRemoteNotifications NS_AVAILABLE_IOS(3_0); //获取本地推送授权状态 - (BOOL)isRegisteredForRemoteNotifications NS_AVAILABLE_IOS(8_0); //授权状态的枚举类型 //UIUserNotificationTypeNone 无授权 //UIUserNotificationTypeBadge 更新APP图标角标 //UIUserNotificationTypeSound 播放声音 //UIUserNotificationTypeAlert 屏幕中间弹出一个UIAlertView - (void)registerForRemoteNotificationTypes:(UIRemoteNotificationType)types NS_DEPRECATED_IOS(3_0, 8_0, "Please use registerForRemoteNotifications and registerUserNotificationSettings: instead"); //获取通知中心 是否 允许程序通知消息的值。 - (UIRemoteNotificationType)enabledRemoteNotificationTypes NS_DEPRECATED_IOS(3_0, 8_0, "Please use -[UIApplication isRegisteredForRemoteNotifications], or -[UIApplication currentUserNotificationSettings] to retrieve user-enabled remote notification and user notification settings"); @end
知识点1:授权的方法实例
UIUserNotificationType type = UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound; UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:type categories:nil]; [[UIApplication sharedApplication] registerUserNotificationSettings:setting];
知识点2:远程推送通知实现的条件
所有的苹果设备,在联网状态下,都会和苹果服务器APNs建立一个长连接;远程推送通知就是借助苹果设备与APNs服务器之间的长连接,借助APNs服务器讲消息发送给客户端。远程推送通知实现的条件,必须有真机,只有真机具备UDID,才能生成deviceToken设备令牌(deviceToken的生成算法只有Apple掌握,为了确保算法发生变化后仍然能够正常接收服务器端发送的通知,每次应用程序启动都重新获得deviceToken);需要开发推送Cer证书;
知识点3:远程推送通知步骤:
1:iOS8以后,使用远程通知,需要请求用户授权 2:注册远程通知成功后会调用以下方法,获取deviceToken设备令牌: -(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken; 3:把deviceToken设备令牌发送给服务器,时刻保持deviceToken是最新的 4:监听远程推送通知: -(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo;
知识点4:判断是否打开推送 IOS7跟IOS8也是有区别
if ([[UIDevice currentDevice].systemVersion floatValue]>=8.0f) { UIUserNotificationSettings *setting = [[UIApplication sharedApplication] currentUserNotificationSettings]; if (UIUserNotificationTypeNone == setting.types) { NSLog(@"推送关闭 8.0"); } else { NSLog(@"推送打开 8.0"); } } else { UIRemoteNotificationType type = [[UIApplication sharedApplication] enabledRemoteNotificationTypes]; if(UIRemoteNotificationTypeNone == type){ NSLog(@"推送关闭"); } else { NSLog(@"推送打开"); } }
知识点5:IOS7跟IOS8关于注册通知是有差异
@interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. //首次打开应用,跳转登录界面 //登录成功,跳转主界面 [self LoadMainView]; //注册远程通知 if ([[UIDevice currentDevice].systemVersion floatValue] < 8.0) { UIRemoteNotificationType type = UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound; [application registerForRemoteNotificationTypes:type]; } else { UIUserNotificationType type = UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound; UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:type categories:nil]; [application registerUserNotificationSettings:setting]; } return YES; } #pragma mark 注册远程通知代理方法,返回deviceToken #ifdef __IPHONE_8_0 - (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings { //iOS8之后注册远程通知需要实现代理方法: [application registerForRemoteNotifications]; } - (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler { //handle the actions if ([identifier isEqualToString:@"declineAction"]){ } else if ([identifier isEqualToString:@"answerAction"]){ } } #endif - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { NSString* newToken = [[[NSString stringWithFormat:@"%@",deviceToken] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]] stringByReplacingOccurrencesOfString:@" " withString:@""]; NSLog(@"nsdata:%@\n 字符串token: %@",deviceToken, newToken);// 获取device token //将token发送给服务器 } - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { NSLog(@"RegistFail %@",error); } - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { //接收通知内容 }
三:UIApplication (UILocalNotifications)分类 处理本地通知
@interface UIApplication (UILocalNotifications) //立刻推送,忽略本地通知对象的fireDate设置进行本地推送通知 - (void)presentLocalNotificationNow:(UILocalNotification *)notification NS_AVAILABLE_IOS(4_0); //延时推送,根据本地通知对象的fireDate设置进行本地推送通知 - (void)scheduleLocalNotification:(UILocalNotification *)notification NS_AVAILABLE_IOS(4_0); //取消指定的本地推送通知 - (void)cancelLocalNotification:(UILocalNotification *)notification NS_AVAILABLE_IOS(4_0); //取消全部本地推送通知 - (void)cancelAllLocalNotifications NS_AVAILABLE_IOS(4_0); //获取本地推送数组 @property(nullable,nonatomic,copy) NSArray<UILocalNotification *> *scheduledLocalNotifications NS_AVAILABLE_IOS(4_0); @end
知识点1:推送通知分为
本地推送通知:
不需要联网,在APP代码中推送的通知,确定知道未来某个时间点应该提醒用户什么【开发人员在APP内部通过代码发生 = 本地推送通知】
远程推送通知:
需要联网,是由服务器推送的通知,不确定未来某个时间点应该提醒用户什么【服务器可以确定通知时间和内容 = 远程推送通知】
知识点2:本地推送通知步骤
1:在iOS8以后使用本地推送通知,需要得到用户的许可 2:创建UILocalNotification本地通知对象,并设置必要属性 3:开始本地推送通知: 第一种方法,延时推送,根据本地通知对象的fireDate设置进行本地推送通知 [[UIApplication shareApplication] scheduleLocalNotification:notification]; 第二种方法,立刻推送,忽略本地通知对象的fireDate设置进行本地推送通知 [[UIApplication shareApplication] presentLocalNotificationNow:notification]; 4:监听用户点击通知: APP处于前台,此时不会弹框通知用户,但会调用对应的代理方法 : -(void)application:(UIApplication *)application didReceiveLocalNotification; APP处于后台,屏幕上方会弹出横幅,用户点击横幅后,会进入前台,调用上面的代理方法。 APP已关闭,屏幕上方会弹出横幅,用户点击横幅后,会启动APP,调用以下方法: -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions; /* 通过参数launchOptions获取本地推送通知内容 */ UILocalNotification *local = launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]; 5:调用UIApplication的对象方法,取消本地推送通知: /* 取消指定的本地推送通知 */ -(void)cancelLocalNotification:(UILocalNotification *)notification; /* 取消全部本地推送通知 */ -(void)cancelAllLocalNotification;
知识点3:实例代码
1. 注册通知代码以及UIAlertView显示通知方法代码
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //因为是storyboard启动,这里就没有其他启动代码了 //iOS8.0以后,如果需要使用推送通知,需要得到用户许可 if (application.currentUserNotificationSettings.types == UIUserNotificationTypeNone) { //注册通知,有横幅通知、应用数字通知、应用声音通知 UIUserNotificationSettings * setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil]; [application registerUserNotificationSettings:setting]; } else { //当APP关闭后接收到通知,在启动中获取本地推送通知对象 UILocalNotification *notification = launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]; [self showLocalNotification:notification]; } return YES; } /* 弹框UIAlertView显示本地通知的信息 */ - (void)showLocalNotification:(UILocalNotification *)notification { /* 显示本地通知 */ NSDictionary *userInfo = notification.userInfo; NSString *title = @"本地通知"; NSString *msg = userInfo[@"msg"]; UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:msg delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil]; [alert show]; //移除本地通知 [[UIApplication sharedApplication] cancelLocalNotification:notification]; }
2. 创建本地通知代码
/* 创建一个本地通知 */ - (UILocalNotification *)makeLocalNotification{ //创建本地推送通知对象 UILocalNotification *notification = [[UILocalNotification alloc] init]; //设置调用时间 notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:10.0];//通知触发的时间,10s以后 notification.repeatInterval = NSCalendarUnitMinute;//每隔多久重复发一次本地通知 //设置通知属性 notification.alertBody = @"最近添加了诸多有趣的特性,是否立即体验?";//通知主体 notification.applicationIconBadgeNumber = 1;//应用程序图标右上角显示的消息数 notification.alertAction = @"打开应用"; //待机界面的滑动动作提示 notification.alertLaunchImage = @"Default";//通过点击通知打开应用时的启动图片,这里使用程序启动图片 notification.soundName = UILocalNotificationDefaultSoundName;//收到通知时播放的声音,默认消息声音 //设置用户信息 notification.userInfo = @{ @"id":@1, @"user":@"Kenshin Cui", @"msg":@"我来了一发本地通知"};//绑定到通知上的其他附加信息 return notification; }
如果需要每天的中午12点准时本地推送怎么办呢?就像这么办,修改fireDate和repeatInterval属性
NSDateFormatter *formatter1 = [[NSDateFormatter alloc]init]; [formatter setDateFormat:@"yyyy-MM-dd HH-mm-sss"]; NSDate *resDate = [formatter dateFromString:@"2016-04-09 12-00-00"]; notification.fireDate = resDate;//设定为明天中午12点触发通知 //记得设置当前时区,没有设置的话,fireDate将不考虑时区,这样的通知会不准确 notification.timeZone = [NSTimeZone defaultTimeZone]; notification.repeatInterval = NSCalendarUnitDay;//每隔一天触发一次
3:监听用户点击
/* 注册本地通知完成会调用,即用户点击确定授权后调用 */ - (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings { //在这里我们尝试发送本地推送通知 if (notificationSettings.types != UIUserNotificationTypeNone) { UILocalNotification *notification = [self makeLocalNotification]; //延迟调用通知 [application scheduleLocalNotification:notification]; //立刻发送通知 //[application presentLocalNotificationNow:notification]; } } /* 应用还在运行,无论前台还是后台,都会调用该方法处理通知 */ - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { if( notification ) { [self showLocalNotification:notification]; } } /* 应用进入前台,去除应用边角数字显示 */ - (void)applicationWillEnterForeground:(UIApplication *)application { //去除应用边角数字 [application setApplicationIconBadgeNumber:0]; }
四:UIApplication (UIUserNotificationSettings)分类 ios8远程通知注册
@class UIUserNotificationSettings; @interface UIApplication (UIUserNotificationSettings) // IOS8注册远程通知 - (void)registerUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings NS_AVAILABLE_IOS(8_0); // IOS8获得当前的通知设置 - (nullable UIUserNotificationSettings *)currentUserNotificationSettings NS_AVAILABLE_IOS(8_0); @end
五:UIApplication (UIRemoteControlEvents)分类 远程事件开关
@interface UIApplication (UIRemoteControlEvents) //允许传递远程控制事件 - (void)beginReceivingRemoteControlEvents NS_AVAILABLE_IOS(4_0); //关闭远程控制 - (void)endReceivingRemoteControlEvents NS_AVAILABLE_IOS(4_0); @end
结合远程事件的运用;接收到一个远程控制事件。比如耳机控制。允许传递远程控制事件,必须调用UIApplication的beginReceivingRemoteControlEvents方法;关闭远程控制,调用endReceivingRemoteControlEvents。
六:UIApplication (UIStateRestoration)分类 控制状态恢复
@protocol UIStateRestoring; @interface UIApplication (UIStateRestoration) // 异步恢复状态 - (void)extendStateRestoration NS_AVAILABLE_IOS(6_0); // 结束异步恢复状态 - (void)completeStateRestoration NS_AVAILABLE_IOS(6_0); // 阻止应用程序使用最近的快找图像,在接下来的循环中 - (void)ignoreSnapshotOnNextApplicationLaunch NS_AVAILABLE_IOS(7_0); // 注册自定义对象的使用状态恢复系统 + (void)registerObjectForStateRestoration:(id<UIStateRestoring>)object restorationIdentifier:(NSString *)restorationIdentifier NS_AVAILABLE_IOS(7_0); @end
七:UIApplicationDelegate协议
//主要方法有: //应用程序的生命周期 //应用程序启动完成的时候调用 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSLog(@"%s",__func__); return YES; } //当我们应用程序即将失去焦点的时候调用 - (void)applicationWillResignActive:(UIApplication *)application { NSLog(@"%s",__func__); } //当我们应用程序完全进入后台的时候调用 - (void)applicationDidEnterBackground:(UIApplication *)application{ NSLog(@"%s",__func__); } //当我们应用程序即将进入前台的时候调用 - (void)applicationWillEnterForeground:(UIApplication *)application { NSLog(@"%s",__func__); } //当我们应用程序完全获取焦点的时候调用 只有当一个应用程序完全获取到焦点,才能与用户交互. - (void)applicationDidBecomeActive:(UIApplication *)application { NSLog(@"%s",__func__); } //当我们应用程序即将关闭的时候调用 - (void)applicationWillTerminate:(UIApplication *)application { NSLog(@"%s",__func__); }
最近有个妹子弄的一个关于扩大眼界跟内含的订阅号,每天都会更新一些深度内容,在这里如果你感兴趣也可以关注一下(嘿对美女跟知识感兴趣),当然可以关注后输入:github 会有我的微信号,如果有问题你也可以在那找到我;当然不感兴趣无视此信息;