在Swift中检查API的可用性

http://www.cocoachina.com/swift/20150901/13283.html

本文由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

时间: 2024-11-04 21:19:49

在Swift中检查API的可用性的相关文章

在swift中检查PAI的可用性

回顾Objective-C的方法 在看Swift之前,让我们简要回顾一下我们之前用Objective-C检查SDK可用性的方法. 检查类和框架的可用性 iOS 9作为一个重要的版本,引进了许多新的框架.但如果你部署版本低于iOS 9,你需要弱连接(weak link)这些新框架,然后在运行时检查其类的可用性.例如:如果我们想在iOS 9中使用新的联系人框架(Contacts framework),而在iOS 8中使用旧的通讯录框架(AddressBook framework): 1 2 3 4

[Swift]检查API可用性

Swift内置支持检查API可用性,这可确保您不会意外使用在给定部署目标上不可用的API. 编译器使用SDK中的可用性信息来验证代码中使用的所有API是否在项目指定的部署目标上可用.如果您尝试使用不可用的API,Swift会在编译时报告错误. 您可以在or 语句中使用可用性条件来有条件地执行代码块,具体取决于您要使用的API是否在运行时可用.当编译器验证该代码块中的API可用时,编译器将使用可用性条件中的信息.ifguard 1 if #available(iOS 10, macOS 10.12

在Swift中使用遗留的C API

Swift的类型系统的设计目的在于简化我们的生活,为此它强制用户遵守严格的代码规范来达到这一点.毫无疑问这是一件大好事,它鼓励程序员们编写 更好更正确的代码.然而,当Swift与历史遗留的代码库.特别是C语言库进行交互时,问题出现了.我们需要面对的现实是许多C语言库滥用类型,以至于它 们对Swift的编译器并不友好.苹果的Swift团队的确花了不少功夫来支持C的一些基础特性,比如C字符串.但当在Swift中使用历史遗留的C语言 库时,我们还是会面临一些问题.下面我们就来解决这些问题. 在开始之前

swift中文文档- 类型转换

未翻译完 待续(英语烂,求斧正) Type Casting 类型转换 Type casting is a way to check the type of an instance, and/or to treat that instance as if it is a different superclass or subclass from somewhere else in its own class hierarchy. 类型转换是检测实例所属类型的一种方法,和/或 去对待实例好像它是一个

如何模块化swift中的状态?

本文和大家分享的主要是模块化swift中状态相关内容,一起来看看吧,希望对大家学习swift有所帮助. 在构建应用或设计系统的时候,最困难的事情之一就是如何建模并处理状态.当应用的某些部分处于我们意料之外的状态时,管理状态的代码也是一个非常常见的 bug 来源. 这周,让我们看一看能更容易处理并响应状态改变的编码技术 - 让代码更加强壮,不容易出错.在本文中,我不会讨论具体的框架或者更大的应用程序架构范围的更改(比如 RxSwift.ReSwift 或者使用 ELM 风格的架构,我会在之后讨论它

Swift与Objective-C API的交互

互用性是让 Swift 和 Objective-C 相接合的一种特性,使你能够在一种语言编写的文件中使用另一种语言.当你准备开始把 Swift 融入到你的开发流程中时,你应该懂得如何利用互用性来重新定义并提高你写 Cocoa 应用的方案. 互用性很重要的一点就是允许你在写 Swift 代码时使用 Objective-C 的 API 接口.当你导入一个 Objective-C 框架后,你可以使用原生的 Swift 语法实例化它的 Class 并且与之交互. 初始化 为了使用 Swift 实例化 O

如何在Swift中创建自定义控件

更新通知:这篇引导教程由Mikael Konutgan使用iOS 8和Swift语言重新制作,在Xcode6和7上测试通过.原始教程是由Colin Eberhardt团队制作的. 用户界面控件是许多应用的重要组成部分.使用这些控件,可以让用户查看应用的内容或与他们的应用进行交互.苹果提供了一个控件集,像UITextField, UIButton 和 UISwitch.灵活使用这些工具箱中已经存在的控件,可以让你创建各种各样的用户界面. 但是,有的时候你可能需要做一些与众不同的事情:库中的控件已经

在Swift中应用Grand Central Dispatch(上)

本文翻译自raywenderlich,原文:Grand Central Dispatch Tutorial for Swift: Part 1/2尽管Grand Central Dispatch(GCD)已经存在一段时间了,但并非每个人都知道怎么使用它.这是情有可原的,因为并发很棘手,而且GCD本身基于C的API在Swift世界中很刺眼. 在这两篇教程中,你会学到GCD的来龙去脉.第一部分解释了GCD可以做什么和几个基本功能.第二部分,你会学到一些GCD所提供的进阶功能. 起步 libdispa

Swift 中枚举

Swift 中枚举高级用法及实践 字数11017 阅读479 评论0 喜欢20 title: "Swift 中枚举高级用法及实践"date: 2015-11-20tags: [APPVENTURE]categories: [Swift 进阶]permalink: advanced-practical-enum-examples 原文链接=http://appventure.me/2015/10/17/advanced-practical-enum-examples/作者=Benedik