这是我参与更文挑战的第10天,活动详情查看: 更文挑战
KeychainAccess 是 Keychain 的简单 Swift 包装器,适用于 iOS 和 OS X。在 Swift 中,它可以让我们在使用 Keychain API 时非常的容易和方便。
下面是我在阅读 KeychainAccess 源码时学习到的技巧。
OptionSet 上的 and 和 or
在 Swift 中使用位掩码时,会用到 OptionSet
,即选项集合(option sets)。在以前使用 OptionSet
的过程中,我只考虑到了将几个选项拼在一起做为一个新的选项使用。在 KeychainAccess 的 AuthenticationPolicy
中,还添加了 and
和 or
两个选项,用来表示所有的条件都必须满足,还是只满足其中一个即可。
public struct AuthenticationPolicy: OptionSet {
public static let or = AuthenticationPolicy(rawValue: 1 << 14)
public static let and = AuthenticationPolicy(rawValue: 1 << 15)
#if swift(>=2.3)
public let rawValue: UInt
public init(rawValue: UInt) {
self.rawValue = rawValue
}
#else
public let rawValue: Int
public init(rawValue: Int) {
self.rawValue = rawValue
}
#endif
}
复制代码
在使用的时候,就可以通过添加 and
或 or
表示更丰富的可能。比如,作者提供的测试用例中的代码:
let policy: AuthenticationPolicy = [.touchIDAny, .or, .devicePasscode]
let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
复制代码
只保留的关键代码。
subscript 下标脚本
KeychainAccess 中有很多处使用到了 subscript
, 即下标脚本。因为不经常使用,所以时常会忘记。subscript
可以快速的访问对象、集合或序列,不需要再调用实例的特定的赋值和访问方法。
比如 KeychainAccess 代码中的 Attributes
,它内部封装了一个 [String: Any]
类型的字典,用户既可以使用属性来访问、设置对应的字典,可以有效的避免传入错误的 key 导致的错误。在定义的属性不够使用时,也可以支持通过自定义的字符串进行访问或设置。
关键代码:
public struct Attributes {
fileprivate let attributes: [String: Any]
public var path: String? {
return attributes[AttributePath] as? String
}
init(attributes: [String: Any]) {
self.attributes = attributes
}
public subscript(key: String) -> Any? {
get {
return attributes[key]
}
}
}
复制代码
Tests
一个安全可靠的框架,离不开完备的测试用例。同样,KeychainAccess 提供了丰富的测试用例。在一个测试方法里,作者可以通过 do{}
将一个测试分成更小的单元,这样可以使代码更加的清晰。
func testGenericPassword() {
do {
// Add Keychain items
}
do {
// Update Keychain items
}
do {
// Remove Keychain items
}
}
复制代码