swift - 在采用转义闭包的函数中抛出错误

标签 swift escaping closures try-catch throw

我正在尝试编写一个在 Firebase 中注册新用户的自定义函数。我在一个名为 DatabaseManager 的类中导入了 Firebase。在那里,我管理所有数据库交互。在这个类中,我想要一个用于添加用户的自定义函数,它会抛出所有 Firebase 错误。这样我就可以在 ViewController 类中使用该函数,我可以在其中捕获错误并显示警报。 但是我似乎无法使该功能正常工作,而且我不确定自己做错了什么。

这是我的功能:

enum createAccountError : Error{
        case emailInUse, weakPassword, networkError, unknownError
    }

    //Mark: create a user profile
    ///create account with email, password, username, phoneNumber, birthDate, name
    func createAccount(_ userModel: UserModel, _ password: String?, completion: @escaping (_ inner: ()throws -> Bool)->())  {
        Auth.auth().createUser(withEmail: userModel.email!, password: password!, completion: {(user, error) in
            if let error = error {
                if let errCode = AuthErrorCode(rawValue: error._code) {
                    switch errCode {
                    case .emailAlreadyInUse:
                        completion({throw createAccountError.emailInUse})
                    case .weakPassword:
                        completion({throw createAccountError.weakPassword})
                    case .networkError:
                        completion({throw createAccountError.networkError})
                    default:
                        completion({throw createAccountError.unknownError})
                    }
                }
                return
            } else {
                completion({return true})
            }
        })
    }

下面是我尝试使用它的方式:

DatabaseManager.system.createAccount(user, password) { (( inner: ()throws -> Bool)->()) in
            do{
                let result = try inner()
            } catch .emailInUse{
                //show alert
            }
            }

最佳答案

我已经为演示创建了测试函数,一切正常

// error type
enum TestError: Error { case notFound, empty }
// define typealias for eiser usage of complex function type
typealias ThrowableCallback = () throws -> Bool

func createAccount(_ shouldThrow: Bool, completion: @escaping (_ inner: ThrowableCallback) -> Void) {
  // call completion callback asynchronously
  DispatchQueue.main.async {
    if shouldThrow {
      // throw error
      completion({ throw TestError.notFound })
    }
    // return value
    completion({ return true })
  }
}

用法:

createAccount(true) { (inner: ThrowableCallback) -> Void in
        do {
          let success = try inner()
          print(success)
        } catch {
          print(error)
        }
      }

UPD:我不建议使用这种技术来处理异步函数中的错误。对成功和失败使用单独的回调或 Promises 以优雅地处理异步代码(查看 this 了解更多信息)

UPD 2:实际解决方案

typealias ThrowableCallback = () throws -> User 
func createAccount(_ userModel: UserModel,
                   _ password: String,
                   completion: @escaping (_ inner: ThrowableCallback) -> Void) {
  Auth.auth().createUser(withEmail: userModel.email!, password: password!, completion: {(user, error) in 
    if let error = error { completion({ throw error }) } 
    else { completions({ return user! }) } 
  }) 
}

// usage
createAccount(userModel, somePassword) { (inner: ThrowableCallback) -> Void in
        do {
          let createdUser = try inner()
        } catch {
          ler errCode = (error as NSError)._code
          switch errCode {
             case .emailAlreadyInUse:
               showAlert("Email is already in use")
             case .weakPassword:
               showAlert("please enter stronger password ")
             case .networkError:
               showAlert("it seams that there is no internet connection")
             default:
               showAlert("Error creating user. Please try again later")
             }
        }
      }

关于swift - 在采用转义闭包的函数中抛出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48038318/

相关文章:

swift - 如何在 Vapor 3.0 中获取客户端 IP 地址?

ios - 如何为 View Controller 的背景设置动画以在多种颜色之间淡入淡出?

java - 为什么在路径中我应该使用双反斜杠但在 glob 模式中 - 四倍?

java - 使用 JdbcTemplate 时转义单引号

javascript - 即使外部函数返回后,闭包如何访问外部函数的变量?

ios - 如何替换 UITextView 中的特定字符

swift - 字符串插值和字符串连接之间的区别

oracle - ADF SQL 查询在日期周围使用单引号

rust - 如何在对象安全方法中通过动态分派(dispatch)传递闭包?

Swift - 在关闭时强烈捕获 self 后期待泄漏