本篇译自: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 是否安装的方法解析 #### 一、引言 在iOS开发过程中,有时候我们需要判断用户设备上是否已经安装了某个特定的应用程序。这种需求常见于应用间跳转或推荐安装等场景。本文将详细介绍如何通过自定义...
因此,我们需要对 SDK 的了解,不了解直接查看使用的 API 所允许的版本,当遇到不直接就进行判断,选择执行的方法,不做任何动作响应,或者一定执行实现,就重写方法,完成高版本的任务。 在屏幕适配中,我们需要...
这个“iOS星级判断显示”是一个简单的演示项目,展示了如何在iOS应用中实现这样的功能,让用户通过点击按钮来改变所显示的星级。 首先,我们要了解iOS开发的基础。iOS应用主要使用Swift编程语言编写,有时也会用到...
在iOS开发中,网络状态的判断是至关重要的,它直接影响到应用的功能实现和用户体验。"iOS 网络状态判断demo"就是一个展示如何在iOS应用中检测网络连接状况的示例项目。在这个项目中,主要涉及到的技术点包括系统提供...
标题“ios-判断访问相机和相册的隐私权限.zip”表明这个压缩包包含了关于如何在iOS应用中检查和处理相机及相册访问权限的代码示例或库。描述中提到的情况是,当用户首次尝试访问这些敏感资源时,如果他们选择不允许...
在iOS应用开发中,定期检测并提示用户更新App版本是保持应用活跃度和用户体验的重要环节。下面我们将深入探讨如何在iOS应用中实现这一功能,并通过一句代码实现版本检测与更新跳转。 首先,我们需要理解iOS的App ...
### Java 判断客户端类型(PC、Android、iOS) 在 Web 开发中,有时我们需要根据用户的访问设备来调整网站的表现形式或功能实现。例如,我们可能希望为 PC 用户提供完整版的网页,而为移动端用户提供轻量级的版本,...
下面是一个完整的判断代码,包括判断移动终端、iOS还是Android、浏览器语言版本等: ``` var browser = { versions: function() { var u = navigator.userAgent, app = navigator.appVersion; return { trident...
"ios-正则判断封装.zip" 提供了一个封装好的解决方案,便于开发者在项目中快速、统一地进行各种正则验证。 该压缩包包含一个名为 "ZJVerifyDemo" 的文件,很可能是一个示例工程或库,用于演示和使用这些封装好的...
本文将深入探讨如何在Swift中判断iOS设备的型号。 首先,我们要了解iOS设备的基本类型。目前,iOS支持的主要设备包括iPhone、iPad、iPod touch以及Apple TV等。iPhone系列又分为多个型号,如iPhone 8、iPhone X、...
除了使用URL Scheme方法,还可以通过使用`UNUserNotificationCenter`(iOS 10及以上版本)来请求其他应用的通知权限,但这种方法通常适用于那些支持发送通知的应用,而且需要用户的交互。 在实际开发中,你可能需要...
源码中会包含判断两个水果是否相邻、是否可以消除的算法,这涉及到数据结构(如二维数组)和算法设计。 4. **Core Animation**:苹果的Core Animation库用于创建平滑的动画效果,使得游戏界面更加生动。在水果连连...
在iOS开发中,判断设备的网络状态是一项基本且重要的任务,因为这直接影响到应用能否正常地获取和发送数据。这篇博客“iOS 判断网络状态”提供了实现这一功能的方法,通过查看其提供的源码文件“Reachability.h”和...
"iOS网络连接状态判断 JPNetwork"是一个简单而实用的库,它帮助开发者轻松地检测iOS设备的网络连接状况。下面将详细阐述这个库的主要功能和实现原理。 首先,JPNetwork库主要由两个文件组成:JPNetwork.h和...
在iOS开发中,有时我们需要对日期进行操作,例如判断两个日期是否属于同一周。这在处理日历事件、数据分析或用户界面更新等场景时非常常见。`NSDate`是Apple的Foundation框架提供的一种基础数据类型,用于表示特定的...
在iOS开发中,判断应用程序运行时的网络环境是IPv4还是IPv6是非常重要的,因为这直接影响到应用的网络连接和通信。随着IPv6的普及,开发者需要确保他们的应用能够兼容这两种网络协议。以下是如何在iOS工程中判断当前...
6. **兼容性处理**:针对iOS 6到iOS 7的变化,可能需要条件判断或适配代码来确保在不同版本的系统上都能正常工作。 在"Teardrop"这个文件中,很可能包含了实现这一效果的源代码、资源文件(如PNG图片或SVG矢量图形...
7. **回调处理**:支付完成后,支付宝会通过URL Scheme回调应用,Demo展示了如何处理这些回调,判断支付状态,并更新应用中的订单状态。 8. **用户授权**:在进行某些操作,如获取用户信息时,可能需要用户授权。...
在开发Unity3D游戏并针对iOS平台进行网络通信时,了解如何判断设备当前使用的网络类型——IPv4或IPv6——是非常关键的。这是因为不同的网络环境可能会影响游戏的网络连接性能和稳定性。以下是一些关于如何在Unity3D...
位置转换 前提:图片是等比例缩放布局显示的 将当前触摸点的位置转换为图片上的位置。 1. 获取触摸点位置 2. 获取图片大小 ...通过转换后的坐标,拿到当前坐标的像素点,然后再根据像素中的颜色信息判断是否透明