首页 > 解决方案 > 从 '(_, _) throws -> ()' 类型的抛出函数到非抛出函数类型 '(Bool, Error?) -> Void 的无效转换

问题描述

我有一个非常简单的类来获取联系人。现在我需要用 throws 创建这个函数。

因为store.requestAccess不是抛出函数,所以我不能从那个clousure中抛出任何错误。所以我收到了这个错误

从 '(_, _) throws -> ()' 类型的抛出函数到非抛出函数类型 '(Bool, Error?) -> Void' 的无效转换

class ContactFetcher {

    enum ContactError:Error {
        case permissionError
        case fetchError
    }

    func fetchContacts(completion:@escaping(([CNContact]) -> ())) throws  {
        let keys = [CNContactPhoneNumbersKey]  as [CNKeyDescriptor]
        let fetchRequest = CNContactFetchRequest(keysToFetch: keys)
        let store = CNContactStore()
        var results:[CNContact] = []
        store.requestAccess(for: .contacts) { (grant, error) in
            if grant{
                do  {
                    try store.enumerateContacts(with: fetchRequest, usingBlock: { (contact, stop) -> Void in
                        results.append(contact)
                    })
                } catch {
                 //   throw ContactError.fetchError
                }

                completion(results)

            } else {
                throw ContactError.permissionError
                print("Error  \(error)")
            }

        }


    }

}

有没有什么办法解决这一问题 ?

提前致谢

标签: swiftthrowthrows

解决方案


您不能从非抛出完成处理程序中抛出。它是异步的!正如您不能从异步函数中返回值一样,您也不能在那里抛出。毕竟,要捕获 throw,throw 需要及时返回到调用原始函数的时间。这在形而上学上是不可能的。

相反,您必须提供另一个完成处理程序,以便您可以从非抛出完成处理程序中使用 Error 参数调用它。这正是发明 Result 类型的原因,它允许您通过异步情况传播错误。


推荐阅读