在 swift 中统一 response/error 处理

Unified response/error handling in swift

我想知道如何解决这样的问题:

我有一个允许用户使用用户名和密码登录的应用程序。然后应用程序将凭据发送到 API 服务器并作为响应获取记录的用户数据

在我的模型中,我定义了一个用户 class

class User {

var id: String
var firstName: String?
var lastName: String?
var email: String
var permissions: String?
var birthday: String?
var subscription: String?


init(id: String, firstName: String?, lastName: String?, email: String, permissions: String?, birthday: String?, subscription: String?) {
    self.id = id
    self.firstName = firstName
    self.lastName = lastName
    self.email = email
    self.permissions = permissions
    self.birthday = birthday
    self.subscription = subscription
}

然后在一个名为 ApiConnector 的 class 中,我有这样的东西(使用 AFNetworking):

func loginUser(mainAddress: String, additionalAddr: String, email: String, password: String, callback: (success: Bool, data: User) -> Void){

    let fullAddress = mainAddress + additionalAddr
    var parameters = ["email":email, "password":password]

    manager.POST( fullAddress,
        parameters: parameters,
        success: { (operation: AFHTTPRequestOperation!,responseObject: AnyObject!) in 
            let json = JSON(data: operation.responseData)

            //HERE I HAVE A JSON WITH USER DATA
            callback(success: true, data: ???)
        },
        failure: { (operation: AFHTTPRequestOperation!,error: NSError!) in
            let json = JSON(data: operation.responseData)
               //HERE I HAVE A JSON WITH ERROR
            callback(success: false, data: ???)
    })
}

现在你可以看到我在数据字段中有一个回调 returning 用户。但是当发生错误时会出现问题,我应该 returning 一些错误类型,而不是用户。

我在考虑如何统一响应,以便创建类似

的内容
enum Result<T, E> {
case Ok(T)
case Error(E)
}

在好的情况下 return 我的用户对象。如果出现 Error return 我的 ErrorType 对象 - 但我有点无法理解它。

任何人都可以向我解释如何在我的案例中做一个统一的响应类型吗?

(我在代码中放置了问号而不是类型,因为这就是问题所在,我没有解决方案 ATM)

有多种方法可以做到这一点。其中之一是在您的 Callback 中使用 NSObject :

callback: (success: Bool, data: NSObject?)

然后在你的成功闭包中尝试强制转换:

if let user = data as? User{
// you have the user
}

如果此检查失败,请尝试以相同的方式转换为错误..

我会选择 Optional 并将成功与修饰的 NSError 交换以获得不错的错误消息。例如像这样:

class User {}
class ServerResponseError {
    var error: NSError
    var message: String {
        get {
            switch(error.code) {
                case 500:
                    return "server error"
                default:
                    return "unknown error"
            }
        }
    }
    init(error: NSError) {
        self.error = error
    }
}

func loginUser(callback: (user: User?, error: ServerResponseError?) -> Void){
    // something went wrong on server
    var error: NSError = NSError(domain: "", code: 500, userInfo: nil)
    callback(user: nil, error: ServerResponseError(error:error))
}

loginUser { (user, error) -> Void in
    print(error.message)
}

您还可以修饰将从服务器 return 编辑的错误对象,并以相同的方式传递它(用户为 nil)。但我认为 return 200 和错误对象是不好的做法。