本文由CocoaChina译者ALEX吴浩文翻译自Use Your Loaf博客
原文:Checking API Availability With Swift
Swift 2改进了检查API可用性的方法,使其更加容易、安全。
回顾Objective-C的方法
在看Swift之前,让我们简要回顾一下我们之前用Objective-C检查SDK可用性的方法。
检查类和框架的可用性
iOS 9作为一个重要的版本,引进了许多新的框架。但如果你部署版本低于iOS 9,你需要弱连接(weak link)这些新框架,然后在运行时检查其类的可用性。例如:如果我们想在iOS 9中使用新的联系人框架(Contacts framework),而在iOS 8中使用旧的通讯录框架(AddressBook framework):
1
2
3
4
5
6
|
if ([CNContactStore class]) {
CNContactStore *store = [CNContactStore new ];
//...
} else {
// 使用旧框架
} |
检查方法的可用性
用respondsToSelector检查框架内是否含有此方法。例如:iOS 9在Core Location框架中新增了allowsBackgroundLocationUpdates属性:
1
2
3
4
5
|
CLLocationManager *manager = [CLLocationManager new ];
if ([manager respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]) {
// 在iOS 8中不可用
manager.allowsBackgroundLocationUpdates = YES;
} |
陷阱
这些方法既难以维护,又没有看上去那么安全。也许某个API现在是公有的,但在早期的版本中却有可能是私有的。例如:iOS 9中新增了几个文本样式,如UIFontTextStyleCallout。如果只想在iOS 9中使用这种样式,你可以检查其是否存在,因为它在iOS 8中应该是null的:
1
2
3
|
if (UIFontTextStyleCallout) {
textLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleCallout];
} |
不幸的是结果并非如此。原来这个标志在iOS 8中是存在的,只是没有宣布公有。使用一个私有的方法或值有可能出现难以预料的结果,况且这也和我们的想法不同。
Swift 2的方法
Swift 2内置了可用性检查,而且是在编译时进行检查。这意味着当我们使用当前部署版本不可用的API时,Xcode能够通知我们。例如:如果我在部署版本为iOS 8的情况下使用CNContactStore,Xcode将提出以下改进:
1
2
3
4
5
|
if #available(iOS 9.0, *) {
let store = CNContactStore()
} else {
// 旧版本的情况
} |
同样这可以取代我们之前使用的respondsToSelector:
1
2
3
4
|
let manager = CLLocationManager() if #available(iOS 9.0, *) {
manager.allowsBackgroundLocationUpdates = true
} |
可用性检查的使用情形
#available条件适用于一系列平台(iOS, OSX, watchOS) 和版本号。例如:对于只在iOS 9或OS X 10.10上运行的代码:
1
2
3
|
if #available(iOS 9, OSX 10.10, *) {
// 将在iOS 9或OS X 10.10上执行的代码
} |
即使你的App并没有部署在其他平台,最后也需要用*通配符来包括它们。
如果某块代码只在特定的平台版本下执行,你可以用guard声明配合#available来提前return,这样可以增强可读性:
1
2
3
4
5
6
7
8
|
private func somethingNew() { guard #available(iOS 9, *) else { return }
// 在iOS 9中执行的代码
let store = CNContactStore()
let predicate = CNContact.predicateForContactsMatchingName( "Zakroff" )
let keys = [CNContactGivenNameKey, CNContactFamilyNameKey]
...
} |
如果整个方法或类只在特定的平台版本下存在,用@available:
1
2
3
4
5
|
@available(iOS 9.0, *) private func checkContact() { let store = CNContactStore()
// ...
} |
编译时的安全性检查
结束前,让我们再看看那个常量在iOS 9中公有却在iOS 8中私有的问题。如果部署版本为iOS 8,我们却把字体设置为一个只有iOS 9才能用的样式,这将产生一个编译错误:
1
2
|
label.font = UIFont.preferredFontForTextStyle(UIFontTextStyleCallout) > 'UIFontTextStyleCallout' is only available on iOS 9.0 or newer
|
Swift使其便于调试,同时能够根据平台版本赋一个合理的值:
1
2
3
4
5
|
if #available(iOS 9.0, *) {
label.font = UIFont.preferredFontForTextStyle(UIFontTextStyleCallout)
} else {
label.font = UIFont.preferredFontForTextStyle(UIFontTextStyleBody)
} |
阅读推荐:
WWDC 2015 Session 403 Improving Your Existing Apps with Swift
WWDC 2015 Session 411 Swift in Practise
感谢:
http://www.cocoachina.com/swift/20150901/13283.html
相关推荐
在Swift中的魔方API 一个遗传求解算法
This is an example project of SwiftUI and Combine using GitHub API.
两种利用私有api实现打开目标应用的方法
用于访问GitHub API的Swift PM模块
《Swift语言》中文版API
Swallow:简单好用的 web 通信工具-Swallow 封装了 HTTP 和 HTTPS 请求,设计良好的 API 用起来非常顺手。此外,Swallow 还支持链式操作和 JSON 解析,能满足绝大部分通信需求。
一个API描述文档自动生成Swift执行代码的工具
swift python api,很好的开发指南,对于C C++ java 都是很有利的
Laravel开发-bukkit-swift-api Swiftapi PHP API封装在一个Laravel包中,用于远程调用Minecraft Bukkit服务器。
FileKit - 在Swift中简单和表达性的文件管理
这些模块大致分为两类:API过于专业化,无法放入标准库中,但它的通用性足以将其集中在单个通用包中。 正在积极开发的API,可能会在将来将其包含在标准库中。 这两个类别之间有些重叠,并且从第一个类别开始的API...
The Swift Programming Language 中文版 - v2.3
Chronology是一个为Swift构建更好日期和时间的API
Swift的WikipediaKit · API 客户端框架,可用于macOS, iOS, watchOS和tvOS
swift 报文中文手册 第一章 SWIFT 基础知识 第二章 SWIFT MX1XX 客户汇款及支票 第三章 SWIFT MT2XX 银行头寸划拨 第四章 SWIFT MT3XX 外汇买卖和存放款 第五章 SWIFT MT4XX 托收 第六章 SWIFT MT7XX 信用证 第七章 ...
使用私有API将触摸栏按钮添加到控制条
混编|限制 API 可用性关键词:NS_SWIFT_UNAVAILABLE、NS_UNAVAILABLE、available使用 NS_SWIFT_UNAVAI
ObjectiveKit 为一组强大的Objective-C运行时功能。提供了一个Swift友好的API
它支持代码预览(playgrounds),这个革命性的特性可以允许程序员在不编译和运行应用程序的前提下运行 Swift 代码并实时查看结果。 Swift 通过采用现代编程模式来避免大量常见编程错误: * 变量始终在使用前初始化。...
Openstack Swift 原理、架构与API介绍Openstack Swift 原理、架构与API介绍Openstack Swift 原理、架构与API介绍Openstack Swift 原理、架构与API介绍Openstack Swift 原理、架构与API介绍Openstack Swift 原理、...