因关闭而抛出错误

时间:2019-07-13 18:18:32

标签: swift closures throw

我的应用中有这段代码:

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."])
            }
        }
    })
}

我想抛出所有在关闭函数时引发的错误。

编译器显示错误:

  

从类型为((_,_)的throwing函数->()到无效类型为'(Bool,Error?)-> Void'的无效转换

有人可以用正确的语法帮助我吗?

1 个答案:

答案 0 :(得分:0)

您不能从@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)
}