本篇译自:Matt Gallagher的blog-http://cocoawithlove.com
原文:http://cocoawithlove.com/2010/07/tips-tricks-for-conditional-ios3-ios32.html
这篇日志会告诉你在ios编程中如何判断不同的版本的ios系统。
1,让项目/Target支持不同版本的iOS
要让一个程序可以在多个版本的ios上运行相当简单:
- 在Project Settings中,将BaseSDK设置为最新的版本。
- 再将【iPhone OS Deployment Target】设置为最老的版本。
将上面这个版本信息设置正确非常简单。但是要在新的iOS上使用新的系统功能,而且还不能让程序在老版本的系统中崩溃,这相对难一些。
2,使用新iOS功能,同时支持老版本
如果你想在iOS4中启动一个后台任务,同时要支持老版本,就要像下面这样写:
Objective-C
- #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 40000
- if ([[UIApplication sharedApplication]
- respondsToSelector:@selector(beginBackgroundTaskWithExpirationHandler:)])
- {
- UIBackgroundTaskIdentifier bgTask = [[UIApplication sharedApplication]
- beginBackgroundTaskWithExpirationHandler:^{}];
- // Perform work that should be allowed to continue in background
- [[UIApplication sharedApplication] endBackgroundTask:bgTask];
- }
- #endif
代码分为三个部分:
- #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 40000 这是编译时期的条件判断。如果我们选择的BaseSDK小于4.0,不会导致编译错误。
- UIApplication的beginBackgroundTaskWithExpirationHandler方法在运行时做的check。
- check中间的功能代码。
3,让条件判断更好看一些
上面代码有编译期判断和运行时check。要做两个判断,写法麻烦。我们要把两个check合并到一起:
Objective-C
- IF_IOS4_OR_GREATER(
- UIBackgroundTaskIdentifier bgTask = [[UIApplication sharedApplication]
- beginBackgroundTaskWithExpirationHandler:^{}];
- // Perform work that should be allowed to continue in background
- [[UIApplication sharedApplication] endBackgroundTask:bgTask];
- );
可以像下面这样实现宏:
Objective-C
- #ifndef kCFCoreFoundationVersionNumber_iPhoneOS_4_0
- #define kCFCoreFoundationVersionNumber_iPhoneOS_4_0 550.32
- #endif
- #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 40000
- #define IF_IOS4_OR_GREATER(...) \
- if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iPhoneOS_4_0) \
- { \
- __VA_ARGS__ \
- }
- #else
- #define IF_IOS4_OR_GREATER(...)
- #endif
如果想要检查早于某一个sdk版本,可以像下面这样写:
Objective-C
- #define IF_PRE_IOS4(...) \
- if (kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iPhoneOS_4_0) \
- { \
- __VA_ARGS__ \
- }
关于上面写的宏:
- 这里使用的是kCFCoreFoundationVersionNumber在运行时判断iOS的版本。有很多例子用的是[[UIDevice currentDevice] systemVersion]。后者需要字符串比较,没有double型的比较直接。
- 没有使用do { x } while (0) ;来包装宏。
- 宏使用了变量参数列表,加多少个变量都没有关系,用逗号隔开就行。
再有一点,kCFCoreFoundationVersionNumber并不是所有版本SDK都有定义。有时候我们需要自己定义:
Objective-C
- #ifndef kCFCoreFoundationVersionNumber_iPhoneOS_2_0
- #define kCFCoreFoundationVersionNumber_iPhoneOS_2_0 478.23
- #endif
- #ifndef kCFCoreFoundationVersionNumber_iPhoneOS_2_1
- #define kCFCoreFoundationVersionNumber_iPhoneOS_2_1 478.26
- #endif
- #ifndef kCFCoreFoundationVersionNumber_iPhoneOS_2_2
- #define kCFCoreFoundationVersionNumber_iPhoneOS_2_2 478.29
- #endif
- #ifndef kCFCoreFoundationVersionNumber_iPhoneOS_3_0
- #define kCFCoreFoundationVersionNumber_iPhoneOS_3_0 478.47
- #endif
- #ifndef kCFCoreFoundationVersionNumber_iPhoneOS_3_1
- #define kCFCoreFoundationVersionNumber_iPhoneOS_3_1 478.52
- #endif
- #ifndef kCFCoreFoundationVersionNumber_iPhoneOS_3_2
- #define kCFCoreFoundationVersionNumber_iPhoneOS_3_2 478.61
- #endif
- #ifndef kCFCoreFoundationVersionNumber_iPhoneOS_4_0
- #define kCFCoreFoundationVersionNumber_iPhoneOS_4_0 550.32
- #endif
4,更好的解决方案
比使用宏更好的方式是使用一个简单的函数。
比如下面的代码:
Objective-C
- #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 30200
- if ([[UIDevice currentDevice] respondsToSelector:@selector(userInterfaceIdiom)] &&
- [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
- {
- // iPad specific layout changes
- }
- else
- #endif
- {
- // iPhone layout
- }
可以使用IF_IOS4_OR_GREATER来改写,但更好的方法是下面的代码:
Objective-C
- if (isIPad())
- {
- // iPad specific layout changes
- }
- else
- {
- // iPhone layout
- }
关于isIPad()方法:
Objective-C
- BOOL isIPad()
- {
- IF_3_2_OR_GREATER
- (
- if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
- {
- return YES;
- }
- );
- return NO;
- }
5,结论:
Apple没有让支持老版本的sdk非常简单。因为他们想让每个人一直使用新的系统,或者买新的设备。但这对开发人者来说很不现实,我们不能期待软件的用户一直使用新系统或新设备。
写适用多版本的程序关键点是写尽量少的if判断。你肯定不想为了对应多版本的问题,让自己的程序有很多的分支,因为每一个分支都意味着要进行测试。
如果你发现需要写很多的if判断,还可以为每个os版本写一个子类。用不同实现类实现功能。
- #ifdef __MAC_OS_X_VERSION_MAX_ALLOWED
- // code only compiled when targeting Mac OS X and not iOS
- // note use of 1050 instead of __MAC_10_5
- #if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
- if (CGColorCreateGenericCMYK != NULL) {
- CGColorCreateGenericCMYK(0.1,0.5.0.0,1.0,0.1);} else {
- #endif
- // code to create a color object with earlier technology
- #if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
- }
- #endif
- #endif
- }
相关推荐
ios判断App是否安装: 自已写的A,B两个程序。用该方法可以使A程序判断B程序是否在ios设备中有没有安装。 不能判断任意程序是否安装。
java判断PC端,Andiro,IOS,java判断PC端,Andiro,IOS,java判断PC端,Andiro,IOS,java判断PC端,Andiro,IOS
iOS 网络状态判断demo
iOS上的简单的星级判断demo,通过点击按钮来改变星级。
iOS 判断设备型号总结
判断当前网络是2G,还是Wifi,还是,3G,还是4G
iOS中App版本的检测更新、如果有更新就跳转至App Store上更新
iOS 判断两个日期是否在同一周内
当用户第一次使用相机或者相册功能,访问用户的隐私权限,点击不允许的情况下,返回上一个页面,再次进来提示用户是否允许访问,可以直接将封装的类导入工程,便可调用.
主要对基础的正则判断类型进行封装,可以同时判断多个类型,方便使用,包括手机号、银行卡、身份证、邮箱以及其他基础验证,比如说在注册界面只需调用一次判断就可对账户、密码、验证码进行判断
JavaScript判断客户端是iOS还是Android等移动终端
包含分类IBInspectable、模型、以及字典三种情况下对控件进行正则判断的封装、可以同时判断多个类型,方便使用,包括手机号、银行卡、身份证、邮箱以及...,除了包含有基础的正则判断,开发者也可以进行自定义正则判断
iOS使用UIScrollView实现左右滑动UITableView和UICollectionView
这应该算是 iOS开发中最常用的功能吧,这两个文件很easy的实现了对网络状态的判断 实用 易用
获取打开页面手机是安卓还ios系统
2种iOS判断网络状态的方法。 一种用系统自带statusBar状态判断 一种基于AFNetWorking来对网络状态做出的判断 欢迎大家下载学习分享使用
针对 iOS 网络权限的监控和判断
1,时间戳转换时间;2,时间转换时间戳;3,时间显示(例如:1分钟以内 显示 : 刚刚 // 2)1小时以内 显示 : X分钟前 // 3)当前时间之前或者昨天 显示 : 今天 09:30 昨天 09:30 // 4)当前时间之前或者明天 显示...
Unity3d For IOS 判断当前是 Ipv6还是ipv4 Unity3d For IOS 判断当前是 Ipv6还是ipv4
NULL 博文链接:https://332016912-qq-com.iteye.com/blog/1973711