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

Invalid conversion from throwing function of type '(_, _) throws -> ()' to non-throwing function type '(Bool, Error?) -> Void

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

由于 store.requestAccess 没有抛出函数,所以我不能从那个 clousure 中抛出任何错误。 所以我收到这个错误

Invalid conversion from throwing function of type '(_, _) throws -> ()' to non-throwing function type '(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)")
            }

        }


    }

}

有什么办法可以解决这个问题吗?

提前致谢

您不能从非抛出完成处理程序中抛出。它是异步的!正如你不能 return 来自异步函数的值一样,你也不能在那里抛出。毕竟,要抓住抛出的对象,抛出对象需要及时倒退到调用原始函数的时间。这在形而上学上是不可能的。

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