你真的了解UIApplication吗?

时间:2023-12-17 10:29:20

一:首先查看一下关于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=;

知识点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:远程推送通知步骤:

:iOS8以后,使用远程通知,需要请求用户授权
:注册远程通知成功后会调用以下方法,获取deviceToken设备令牌:
-(void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken;
:把deviceToken设备令牌发送给服务器,时刻保持deviceToken是最新的
:监听远程推送通知:
-(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:本地推送通知步骤

:在iOS8以后使用本地推送通知,需要得到用户的许可
:创建UILocalNotification本地通知对象,并设置必要属性
:开始本地推送通知:
第一种方法,延时推送,根据本地通知对象的fireDate设置进行本地推送通知
[[UIApplication shareApplication] scheduleLocalNotification:notification]; 第二种方法,立刻推送,忽略本地通知对象的fireDate设置进行本地推送通知
[[UIApplication shareApplication] presentLocalNotificationNow:notification]; :监听用户点击通知:
APP处于前台,此时不会弹框通知用户,但会调用对应的代理方法 :
-(void)application:(UIApplication *)application didReceiveLocalNotification; APP处于后台,屏幕上方会弹出横幅,用户点击横幅后,会进入前台,调用上面的代理方法。 APP已关闭,屏幕上方会弹出横幅,用户点击横幅后,会启动APP,调用以下方法:
-(BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
/* 通过参数launchOptions获取本地推送通知内容 */
UILocalNotification *local = launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]; :调用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 = ;//应用程序图标右上角显示的消息数
notification.alertAction = @"打开应用"; //待机界面的滑动动作提示
notification.alertLaunchImage = @"Default";//通过点击通知打开应用时的启动图片,这里使用程序启动图片
notification.soundName = UILocalNotificationDefaultSoundName;//收到通知时播放的声音,默认消息声音
//设置用户信息
notification.userInfo = @{ @"id":@,
@"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:];
}

四: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协议

你真的了解UIApplication吗?

//主要方法有:
//应用程序的生命周期
//应用程序启动完成的时候调用
- (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 会有我的微信号,如果有问题你也可以在那找到我;当然不感兴趣无视此信息;

你真的了解UIApplication吗?