iOS版本兼容以及部分iOS 11适配
来源:互联网 发布:利用网络犯罪 编辑:程序博客网 时间:2024/06/05 02:59
Tips Xcode 配置理解
1.Base SDK
指的是当前编译用的SDK版本。简单来说就是表示当前使用的Xcode所支持的最高的SDK的版本,比如现在是用iOS 11来编译程序,那么最高的SDK也就是11
2.Deployment Target
指的是编译出的程序将在哪个系统版本上运行,它控制着运行应用需要的最低操作系统版本。简单来说是当前的设置的Target所支持的最低的iOS的版本,比如现在设置的8.0,那么最低运行适配版本就是8.0,再低可能就炸了
版本兼容面对的问题
1.若你想要体验最新的iOS 11的功能,又要兼容iOS 8.0版本,Base SDK设置为最新的iOS 11(默认即可)。Deployment Target设置为iOS 8.0。当然,你用到的iOS 11 的API,要确保它们不会在iOS 8.0上不会crash。
2.团队开发,如果你比较猎奇,你已经升级了最新的Xcode9,那么你就能编译最新的SDK,支持iOS 11,但是你的同事比较保守,没有升级,还是停留在Xcode 8,那么最高支持也就是iOS 10.3,当你提交了代码,如果不做好不同版本之间的条件编译,会导致用旧版本Xcode同事报错无法编译
解决思路一:静态检查编译SDK阶段
静态检查,即在编译时段就检查当前SDK编译与构建应用是否能使用某个API或已经不支持某个API
1.__IPHONE_OS_VERSION_MIN_REQUIRED
值等于Deployment Target,检查支持的最小系统版本。
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000 //minimum deployment target is 8.0, so it’s safe to use iOS 8-only code 当前SDK最小支持的设备系统,即8.0,所以在iOS 8.0设备上是安全的#else //you can use iOS8 APIs, but the code will need to be backwards //compatible or it will crash when run on an iOS 7 device 你仍然可以使用iOS 8的API,但是在iOS 7的设备上可能会crash.#endif
2.__IPHONE_OS_VERSION_MAX_ALLOWED
值等于Base SDK,即用于检查SDK版本的
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0 //you can use iOS 11 APIs here because the SDK supports them //but the code may still crash if run on an iOS 8 device 可以使用最新的iOS 11的API,开始支持的新功能。但是仍然可能会在iOS 8的设备上crash。#else //this code can’t use iOS 10 APIs as the SDK version doesn’t support them 不能使用iOS 11的API,只能使用iOS 11之前的。#endif
通过系统预设的宏定义进行条件编译
1.每次发布新版本SDK的时候,都会伴随新的API供大家使用,因此为了做兼容,低版本还是用低版本方法,而新版本可以用高版本API来进行兼容
2.宏只在编译阶段生效,只是纯粹的文本替换,被宏包起来的代码,在编译阶段已经决定是否运行了,如果已经运行到系统上,那么宏就已经没什么卵用,已经在编译阶段判定好使用哪段代码了
3.那么问题来了,不同版本的Xcode要进行宏定义的条件编译不同适配的代码,才能保证SDK的兼容问题
#ifndef __IPHONE_11_0#define __IPHONE_11_0 110000#endif#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0#else#endif
这样只是保证了不同SDK之间的兼容问题,保证编译的时候不存在问题,那么跑进系统之后如何保证高版本API在低系统运行时也能兼容,那么就需要运行时检查系统版本
解决思路二:运行时检查系统版本
这里从StackOverFlow上搜集了一些判断当前系统版本的几个方法
1.Xcode 9新方法 if (@available(iOS 11, *)) {}
如果要看available语法的介绍可以自行百度,一大把
2.NSFoundationVersionNumber
iphone版本感觉10之前都可以用,貌似10之后有点问题了,稍微知道下就好了,反正我不用
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) { // here you go with iOS 7}
3.UIDevice
if ([[ [UIDevice currentDevice] systemVersion] floatValue] >= 11.0) {}
该方法对于整数,float计算出来就不会有问题,那么当如果你的系统是11.2.1和11.2.2这个时候就会出现精度问题,毕竟float存在的精度问题随时会出现,这种简单的判断适用于整数大版本,小版本就无法精确判断了
4.NSOperatingSystemVersion
NSOperatingSystemVersion version = [[NSProcessInfo processInfo] operatingSystemVersion]; NSLog(@"major--->%ld,minjor--->%ld,patch--->%ld",version.majorVersion,version.minorVersion,version.patchVersion); NSOperatingSystemVersion v = (NSOperatingSystemVersion){9,0,0}; // 判断操作系统是否大于等于v版本 BOOL isRight = [[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:v]; if (isRight) { NSLog(@"当前版本大于指定版本"); } else { NSLog(@"当前版本小于指定版本"); }// 2017-09-27 15:43:01.540690+0800 测试Icon[28898:915470] major--->11,minjor--->0,patch--->0// 2017-09-27 15:43:01.540811+0800 测试Icon[28898:915470] 当前版本大于指定版本
这种方法是iOS 8之后才有的,目前为止的话可以用了,毕竟已经最低支持iOS 8了,不用担心7了
5.字符串比较
/* * System Versioning Preprocessor Macros */ #define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)#define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)/* * Usage */ if (SYSTEM_VERSION_LESS_THAN(@"4.0")) { ...}if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"3.1.1")) { ...}
我用的就是这种方式
但是需要注意的是,如果你系统版本是11.0,你指定的版本是11.0.0,这种情况下,你要知道11.0.0是比11.0版本大的,也就是说你用SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"11.0.0")
返回的是NO
针对上面的方法举个例子
#ifndef __IPHONE_8_0#define __IPHONE_8_0 80000#endif // 编译时判断:检查SDK版本 兼容Xcode版本#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0 // 运行时判断:检查当前系统版本 if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) { UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Warning" message:@"Compatibility" preferredStyle:UIAlertControllerStyleAlert]; [alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { NSLog(@"Cancel"); }]]; [self presentViewController:alertController animated:YES completion:nil]; } else { // 用旧的代替 UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Warning" message:@"Compatibility" delegate:nil cancelButtonTitle:@"Cancel" otherButtonTitles:nil]; [alertView show]; }#else // ...#endif}
针对上面提到的知识点总结,这里老外有一个简单的回答
总结来说:编译时检查SDK版本(兼容Xcode),运行时检查系统版本(兼容系统)
iOS 11适配
适配详情可以参考如下链接
iOS 11适配详解
下面都是我个人的感觉和做法
iPhone X 变化最大的是头部 & 底部
非iPhone X :
StatusBar 高20px,NavigationBar 高44px,底部TabBar高49px
iPhone X:
StatusBar 高44px,NavigationBar 高44px,底部TabBar高83p
来来来,一句话搞定适配,把下面的代码放着这个下面 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
#ifndef __IPHONE_11_0#define __IPHONE_11_0 110000#endif#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0// if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"11.0")) { if (@available(iOS 11.0, *)) { UIScrollView.appearance.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; UITableView.appearance.estimatedRowHeight = 0; UITableView.appearance.estimatedSectionFooterHeight = 0; UITableView.appearance.estimatedSectionHeaderHeight = 0; } else { // Fallback on earlier versions }// }#endif
个人的一些知识点记录,如果对于上面提到的有任何问题,各位大神请留言指点,谢谢了~~~
参考链接
How to check iOS version?
版本兼容
解决iOS项目的版本兼容问题-结合宏、Category和Runtime
- iOS版本兼容以及部分iOS 11适配
- [iOS开发]Xcode8兼容iOS7以及低版本Xcode调试高版本iOS系统
- [iOS开发]Xcode8.3兼容iOS10.3.1以及低版本Xcode调试高版本iOS系统
- IOS 版本方法兼容解决办法
- 【iOS开发】iOS7 兼容及部分细节
- 【iOS开发】iOS7 兼容及部分细节
- 怎样才能做到iOS应用程序与iOS版本兼容
- iOS XIB以及Storyboard的部分使用方法
- iOS开发之版本兼容一,使用#ifdef语法
- ios类初始化以及版本适配
- iOS状态栏颜色以及版本判断
- iOS部分
- IOS 9 同时兼容http以及https请求
- 各个时间段对应使用的Xcode版本以及iOS版本。
- iOS检查版本更新,以及获取不到版本信息问题
- iOS 版本
- iOS 6.0旋转兼容
- iOS兼容amr音频格式
- Hbase与Hadoop版本对应
- Unity实时接收麦克风音频将音频可视化类卡拉OK效果展示
- SVN默认访问地址去掉svn路径内容
- 委托与泛型
- StringUtils的一些常用用法
- iOS版本兼容以及部分iOS 11适配
- codechef September Challenge 2017解题报告
- Python(3)
- BIM软件
- 用qgis把遥感图像tiff文件切割出来还是tiff文件
- 回顾大一·C语言编程2.3(5)
- android 7.0 拍照 适配
- CListCtrl控件导出Excel格式文件
- 3.1、操作系统(作业、进程、线程、内存管理、垃圾回收)