PromiseKit has this initializer for Promise
:
/// Initialize a new promise that can be resolved with the provided `Resolver`.
public init(resolver body: (PromiseKit.Resolver<T>) throws -> Void)
Sometimes I need my function to return a Promise
but the return value of that function depends on other throwing functions. Is it valid to call try
directly without a do/catch
block since the resolver
closure throws? Or must I wrap each throwing function in do
and in the catch
call seal.reject(error)
?
I would prefer to directly use try
because it is much cleaner to return the end result without the do/catch
.
This issue seems relevant, but I'd like some confirmation on these approaches since it isn't called out in the docs: https://github.com/mxcl/PromiseKit/issues/799.
Is this valid?
private func getCNContacts() -> Promise<[CNContact]> {
return Promise { seal in
let fullNameKeyDescriptor = CNContactFormatter.descriptorForRequiredKeys(for: .fullName)
guard let keysToFetch = [fullNameKeyDescriptor, CNContactPhoneNumbersKey] as? [CNKeyDescriptor] else {
throw CKPersistenceError.failedToFetch("Could not cast as [CNKeyDescriptor]")
}
var results: [CNContact] = []
let fetchRequest = CNContactFetchRequest(keysToFetch: keysToFetch)
try contactStore.enumerateContacts(with: fetchRequest) { contact, _ in
results.append(contact)
}
seal.fulfill(results)
}
}
Or must I use do/catch
like this:
private func getCNContacts() -> Promise<[CNContact]> {
return Promise { seal in
let fullNameKeyDescriptor = CNContactFormatter.descriptorForRequiredKeys(for: .fullName)
guard let keysToFetch = [fullNameKeyDescriptor, CNContactPhoneNumbersKey] as? [CNKeyDescriptor] else {
seal.reject(CKPersistenceError.failedToFetch("Could not cast as [CNKeyDescriptor]"))
return
}
do {
var results: [CNContact] = []
let fetchRequest = CNContactFetchRequest(keysToFetch: keysToFetch)
try contactStore.enumerateContacts(with: fetchRequest) { contact, _ in
results.append(contact)
}
seal.fulfill(results)
} catch {
seal.reject(error)
}
}
}
There's also this possibility, but I think it might have threading implications:
private func getCNContacts() -> Promise<[CNContact]> {
let fullNameKeyDescriptor = CNContactFormatter.descriptorForRequiredKeys(for: .fullName)
guard let keysToFetch = [fullNameKeyDescriptor, CNContactPhoneNumbersKey] as? [CNKeyDescriptor] else {
let error = CKPersistenceError.failedToFetch("Could not cast as [CNKeyDescriptor]")
return Promise(error: error)
}
do {
var results: [CNContact] = []
let fetchRequest = CNContactFetchRequest(keysToFetch: keysToFetch)
try contactStore.enumerateContacts(with: fetchRequest) { contact, _ in
results.append(contact)
}
return Promise.value(results)
} catch {
return Promise(error: error)
}
}