从关闭中抛出错误的正确方法?

时间:2019-05-03 05:37:40

标签: ios swift

此刻,我实际上正在尝试快速地进行一些代码逻辑训练,我想知道从init中抛出错误的正确方法是什么?

因此,流程是Controller在初始化Model要求我的sql管理器创建帐户时要求创建帐户,并且此方法从闭包中返回结果。

但是感觉有些不对劲,我应该只使用包含我的两个Int的sql管理器的返回值吗?和错误? ?

init(_ username: String, _ password: String) throws {
        self.id = 0
        self.username = username
        self.password = password

        var toThrow: Error? = nil
        // Register in database
        userManager.create(self) { (id: Int?, err: Error?) in
            Thread.sleep(forTimeInterval: 10)
            if let error = err {

                // Register in database goes wrong
                debugPrint("Handle error from user creation...")
                toThrow = error
            } else {

                // There is no id and no error ?
                guard let _ = id else { return }
                self.id = id!
            }
        }

        if let error = toThrow {
            throw error
        }
    }

2 个答案:

答案 0 :(得分:0)

如果您使用的是Swift 5,则可以研究使用Result并像这样定义闭包

(id: Int) -> Result<Int, Error>

并将代码更改为

userManager.create(self) { (id: Int?) -> Result<Int, Error> in
        Thread.sleep(forTimeInterval: 10)
        if let error = err {

            // Register in database goes wrong
            debugPrint("Handle error from user creation...")
            return .failure(error)
        } else {

            // There is no id and no error ?
            guard let _ = id else { return }
            return .success(id)
        }
    }

如果您对Db类有自己的错误枚举,例如

enum DbError {
    case create
    case update
    //...
}

然后您可以在闭包声明中使用该类型

(id: Int?) -> Result<Int, DbError> 

并为此操作返回特定错误

 return .failure(.create)

请注意,我尚未对此进行编译,因此请考虑一个示例

答案 1 :(得分:0)

这是人们想要看的解决方案:

@IBAction func didPressRegister() {
        guard let username = usernameField.text else { return }
        guard let password = passwordField.text else { return }

        let user = UserModel(username, password)
        userManager.create(user) { result in
            switch(result) {
            case .failure(let error):
                // TODO: UIAlert
                debugPrint(error)
            case .success(let int):
                // TODO: Generate user token and redirect main
                debugPrint(int)
            }
        }
    }
// TODO
    public func create(_ user: UserModel, _ complete: @escaping (Result<Int, Error>) -> ()) {

        debugPrint("Requested to create the user... \(user)")
        complete(.failure(toThrow.ACCOUNT_ERROR))
    }