Swift包装iOS AddressBook框架。
地址簿框架中包含的枚举非常糟糕。它们没有正确声明。地址簿框架不是使用CF_ENUM和CF_OPTIONS,而是更喜欢创建匿名枚举,然后是typedef-ed类型。
这意味着您有ABRecordType
别名到UInt32
,并且有三个孤儿声明(kABPersonType
,kABGroupType
,kABSourceType
)作为Int
导入到Swift中。
同样,kABPersonKindProperty
属性包含一个不是用CFNumberRef包装的ABPersonKind。它包含kABPersonKindPerson
或kABPersonKindOrganization
(两者都是静态CFNumberRef)。
不要注意幕后的人。
实现细节位于此处,例如
ABExternalChangeCallback
,它可以使用基于块的机制注册(和注销)外部更改的通知。`ABAddressBookRegisterExternalChangeCallback`函数需要一个函数指针来调用外部更改发生时的通知。Swift导入这种必需的类型为无用的CFunctionPointer;因为这个原因,在这里使用了一定量的Objective-C。这些“多值类型”是表示 ABMultiValueRef
中值的结构体。正如你可能猜测的那样,MultiDate
是 NSDate
的包装器,而 MultiString
是 String
的包装器。这些类型的存在是为了方便在用于添加到多值对象的对象的适当 CFTypeRef
值之间进行转换,同时也为了提高类型安全性。
AddressBookType
列出了地址簿对象的职责和要求,以及其他类似的对象如 GroupType
、PersonType
和 SourceType
。
创建这些协议是为了你可以在应用程序中使用它们而不是具体类型。为什么?地址簿框架是一个黑盒,且不易测试。现在,你可以使用 *Type
协议来在测试中提供有效的虚构数据。
你可以在你的类中(通过 依赖注入)传递符合 AddressBookType
的值(而不仅仅是使用内部的 ABAddressBookRef
)。
之前
struct PersonViewModel {
private let addressBook: ABAddressBookRef
init() {
// Create addressBook here
}
}
之后
struct PersonViewModel<AB: AddressBookType> {
private let addressBook: AB
init(addressBook: AB) {
// Assign addressBook here
}
}
Gulliver 设计用于 Swift 1.2。与未来版本的兼容性不能保证。
“Gulliver” 是小说《世界各地的几个偏远国家游记。四部。由Lemuel Gulliver,最初是一名外科医生,后来成为一名船舶船长》(普遍被称为 格列佛游记),这是乔纳森·斯威夫特(在Taylor之前很久就著名的斯威夫特)所写的一部讽刺小说中的主要人物的名字。