我正在创建一个联系人类来异步获取用户的电话号码。
我创建了三个函数,利用了新的Combine框架的Future功能。
func checkContactsAccess() -> Future<Bool, Never> {
Future { resolve in
let authorizationStatus = CNContactStore.authorizationStatus(for: .contacts)
switch authorizationStatus {
case .authorized:
return resolve(.success(true))
default:
return resolve(.success(false))
}
}
}
func requestAccess() -> Future<Bool, Error> {
Future { resolve in
CNContactStore().requestAccess(for: .contacts) { (access, error) in
guard error == nil else {
return resolve(.failure(error!))
}
return resolve(.success(access))
}
}
}
func fetchContacts() -> Future<[String], Error> {
Future { resolve in
let contactStore = CNContactStore()
let keysToFetch = [
CNContactFormatter.descriptorForRequiredKeys(for: .fullName),
CNContactPhoneNumbersKey,
CNContactEmailAddressesKey,
CNContactThumbnailImageDataKey] as [Any]
var allContainers: [CNContainer] = []
do {
allContainers = try contactStore.containers(matching: nil)
} catch {
return resolve(.failure(error))
}
var results: [CNContact] = []
for container in allContainers {
let fetchPredicate = CNContact.predicateForContactsInContainer(withIdentifier: container.identifier)
do {
let containerResults = try contactStore.unifiedContacts(matching: fetchPredicate, keysToFetch: keysToFetch as! [CNKeyDescriptor])
results.append(contentsOf: containerResults)
} catch {
return resolve(.failure(error))
}
}
var phoneNumbers: [String] = []
for contact in results {
for phoneNumber in contact.phoneNumbers {
phoneNumbers.append(phoneNumber.value.stringValue.replacingOccurrences(of: " ", with: ""))
}
}
return resolve(.success(phoneNumbers))
}
}
现在,我该如何将这三个 Future 合并为一个 Future 呢?
1)检查权限是否可用 2)如果为真,则异步获取联系人 3)如果为假,则先异步请求访问权限,然后再异步获取联系人
欢迎分享你更好的处理方法。
func getPhoneNumbers() -> Future<[String], Error> {
...
}
resolve
。不要返回调用它的“结果”。删除所有的return
。 - mattauthorizationStatus(for:)
并不是异步的,因此将其转换为 Future 没有意义。 - matt