从闭包中抛出错误

Throwing errors from closure

我的应用程序中有这段代码:

func saveContact2(contact: String) throws {
    let contactStore = CNContactStore()
    contactStore.requestAccess(for: .contacts, completionHandler: {(granted, error) in
        if granted && error == nil {
            //...
        } else {
            if !granted {
                throw contactErrors.contactAccessNotGranted(["Error","Access to Contacts is not granted."])
            }
        }
    })
}

我想将闭包中引发的所有错误抛给调用函数。

编译器显示错误:

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

谁能用正确的语法帮助我?

您不能从异步调用的 @escaping 闭包中抛出错误。这是有道理的,因为您的应用程序已继续执行并且没有地方可以捕获错误。

因此,改为自己采用完成处理程序模式:

func saveContact2(_ contact: String, completion: @escaping: (Result<Bool, Error>) -> Void) {
    let contactStore = CNContactStore()
    contactStore.requestAccess(for: .contacts) { (granted, error) in
        guard granted else {
            completion(.failure(error!)
            return
        }

        //...
        completion(.success(true))
    }
}

然后你会这样称呼它:

saveContact2(contactName) { result in 
    switch result {
    case .failure:
        // handler error here

    case .success:
        // handle confirmation of success here
    }
}

如果您使用的是没有 Result 类型的旧编译器,基本上是:

enum Result<Success, Failure> where Failure: Error {
    case success(Success)
    case failure(Failure)
}