`
啸笑天
  • 浏览: 3465594 次
  • 性别: Icon_minigender_1
  • 来自: China
社区版块
存档分类
最新评论

在Swift中检查API的可用性

 
阅读更多

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

分享到:
评论

相关推荐

    Openstack Swift 原理、架构与API介绍.docx

    Swift 的架构基于标准硬件,不依赖 RAID,而是利用一致性哈希和数据冗余来保证可用性和可扩展性。 **一致性哈希**是Swift寻址策略的关键。这种技术将对象分布到虚拟节点上,以减少在添加或删除物理节点时的数据迁移...

    swift-FileKit-在Swift中简单和表达性的文件管理

    **Swift中的FileKit:简单与表达性的文件管理** 在Swift编程中,文件操作是不可或缺的一部分。FileKit是一个开源库,它为Swift开发者提供了一种更简单、更表达性的方法来处理文件系统操作,使得文件管理变得更为...

    flutter-google-api-availability:检查当前设备上Google Play服务的可用性

    Flutter Google Api可用性插件 Flutter插件,用于检查当前设备上Google Play服务的可用性。 科建立状态开发 主产品特点检查Google Play服务的可用性(仅适用于Android)。用法要使用此插件,请中将google_api_...

    swift CLI - 中文.docx

    Swift提供了多层冗余和分布式存储,确保数据的高可用性和持久性。 在进行实际操作时,用户通常会通过一系列命令来完成工作流程,比如创建一个新容器,然后将本地文件上传到该容器,最后可能还需要检查存储的状态...

    swift2.0新特性

    在之前版本中,开发者需要通过if语句来检测系统API是否可用,而在Swift 2.0中引入了#available关键字,它允许开发者在一个更清晰的语法结构中进行API版本的检查。比如,可以明确地写出一个if条件表达式来检查是否...

    Swift架构概述

    每个资源都被映射到多个虚节点上,每个虚节点又会在集群中分布多个副本,以增强数据冗余性和高可用性。 - **副本 (Replica)**:为了提高数据可靠性,每个虚节点在集群中有多个副本,默认情况下至少有三个副本。 环...

    swift-Reachability.swift使用Swift写的第三方网络检测类

    在Swift项目中集成Reachability.swift非常简单,通常通过CocoaPods、Carthage或手动导入源码来完成。一旦集成,你就可以利用它提供的API来实时监控网络变化,并做出相应的响应,例如在网络断开时显示错误信息,或者...

    swift3.0 指纹、手势解锁

    3. **检查Touch ID可用性**:在尝试使用Touch ID之前,应先检查设备是否支持Touch ID并设置了一个有效的指纹。 ```swift if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error)...

    Swift服务的基本使用.doc

    在OpenStack环境中,Swift可以通过"swift stat"命令检查其服务状态,如示例所示,该命令会显示Account、Containers、Objects的数量以及相关的元数据信息。这些信息有助于监控Swift服务的运行状况。 创建容器是使用...

    swift UICollectionView, UITableView 上拉/下拉刷新 修改

    在编写代码时,应确保使用的API和语言特性在目标版本中可用,避免使用Swift 3或更高版本的新特性,以免在旧版本Xcode或iOS中出错。 4. **第三方库**:在实际开发中,为了简化实现过程,开发者可能会选择使用第三方...

    Implementing Cloud Storage with OpenStack Swift

    - **分布式的存储架构**:Swift采用分布式的架构设计,数据被分布在多个节点上,提高了系统的可用性和性能。 - **数据复制机制**:为了保证数据的可靠性,Swift使用了数据复制机制,通常情况下每个数据副本至少保留...

    OpenStack Swift

    OpenStack Swift是OpenStack项目中负责大规模对象存储的一个组件。对象存储系统是一种存储解决方案,它在功能上...在实际应用中,Swift已被多家企业和组织所采用,用作云存储基础设施的关键组件,并取得了显著的成功。

    swift-仿微信小视频的录制Objective-C版

    10. **错误处理**: 在实现过程中,需要处理可能出现的各种错误,如设备不可用、权限未授予、存储空间不足等,确保程序的健壮性。 通过这个项目,开发者可以学习到Objective-C中的视频录制流程,以及如何将这些技术...

    Packt.Implementing Cloud Storage with Openstack Swift.2014

    该系统设计用来存储、检索和管理大量数据,它被广泛用于云存储服务,尤其是在需要水平扩展以及数据冗余以确保高可用性的环境中。 2. 对象存储系统: 对象存储系统是一种数据存储架构,它将数据作为对象存储在扁平的...

    swift2.0语法改动学习笔记.zip

    这个新特性允许你标记API的可用性,以便在不同版本的iOS、macOS或其他平台间进行兼容性检查。 7. **`where`子句在扩展中使用**: 类型扩展也可以使用`where`子句,限制扩展的条件,使得对已有类型的扩展更为灵活...

    swift-Devices可以检测当前设备的基本系统信息支持iOSOSXtvOSwatchOS

    在Swift编程语言中,开发人员经常需要获取运行应用的设备的相关信息,比如设备型号、操作系统版本等。"swift-Devices" 是一个实用的工具类库,它为开发者提供了简便的方法来检测并获取这些基础的系统信息。这个库...

    DDC.swift:Swift的显示数据通道(DDC)和扩展显示标识数据(EDID)API

    DDC.swift 是一个开源项目,专注于在Swift编程语言中实现Display Data Channel (DDC) 和Extended Display Identification Data (EDID)的相关功能。DDC是一种通信协议,允许显示器和图形适配器之间交换信息,比如...

    swift-SFSafeSymbols一种类型安全的方式访问Apple的SFSystemSymbols

    在Swift中,SFSafeSymbols通过枚举(enum)的形式封装了所有可用的SF System Symbols。每个枚举案件代表一个特定的图标,这使得编译器能够在编译时检查符号的正确性,防止因拼写错误或符号更新而导致的运行时错误。...

    swift-mattress-iOS离线缓存Web内容

    Swift中的离线缓存Web内容是iOS应用开发中一个重要的技术点,特别是在提供无缝用户体验和减少网络依赖性方面。"mattress"项目是一个专门针对这种情况的解决方案,它旨在帮助开发者实现iOS应用中的Web内容离线存储和...

Global site tag (gtag.js) - Google Analytics