[swift]Alamofire 中的错误处理

发布时间: 2017/3/5 0:27:36
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

我在 AngularJS 控制器有 HTTP 代码︰

$http.post('/api/users/authenticate', {email: $scope.email, password: $scope.password})
    .success(function (data, status, headers, config) {
        authService.login($scope.email);
        $state.go('home');
    })
    .error(function (data, status, headers, config) {
        $scope.errorMessages = data;
        $scope.password = "";
    });

在成功的情况下,服务器将响应用户一个 JSON 表示。在错误情况下服务器将响应与一个简单的字符串如 User not found ,可以通过访问 data 参数。

我有问题弄清楚如何去做类似的 Alamofire。这里是现在所拥有的︰

@IBAction func LoginPressed(sender: AnyObject) {
    let params: Dictionary<String,AnyObject> = ["email": emailField.text, "password": passwordField.text]

    Alamofire.request(.POST, "http://localhost:3000/api/users/authenticate", parameters: params)
        .responseJSON {(request, response, data, error) in
            if error == nil {
                dispatch_async(dispatch_get_main_queue(), {
                    let welcome = self.storyboard?.instantiateViewControllerWithIdentifier("login") as UINavigationController;

                    self.presentViewController(welcome, animated: true, completion: nil);
                })
            }
            else{
                dispatch_async(dispatch_get_main_queue(), {
                    // I want to set the error label to the simple message which I know the server will return
                    self.errorLabel.text = "something went wrong"
                });
            }
    }
}

我有没有想法,如果我非错误情况下正确处理要么,并且希望在那输入以及。

解决方法 1:

你是在正确的轨道,但你要运行到与您的当前实现的一些关键问题。有一些低级别的 Alamofire 事情,去的旅行了,我要你帮着。这里是您将会更有效的代码示例替代版本。

@IBAction func loginPressed(sender: AnyObject) {
    let params: [String: AnyObject] = ["email": emailField.text, "password": passwordField.text]

    let request = Alamofire.request(.POST, "http://localhost:3000/api/users/authenticate", parameters: params)
    request.validate()
    request.response { [weak self] request, response, data, error in
        if let strongSelf = self {
            let data = data as? NSData

            if data == nil {
                println("Why didn't I get any data back?")
                strongSelf.errorLabel.text = "something went wrong"
                return
            } else if let error = error {
                let resultText = NSString(data: data!, encoding: NSUTF8StringEncoding)
                println(resultText)
                strongSelf.errorLabel.text = "something went wrong"
                return
            }

            var serializationError: NSError?

            if let json: AnyObject = NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments, error: &serializationError) {
                println("JSON: \(json)")
                let welcome = self.storyboard?.instantiateViewControllerWithIdentifier("login") as UINavigationController
                self.presentViewController(welcome, animated: true, completion: nil)
            } else {
                println("Failed to serialize json: \(serializationError)")
            }
        }
    }
}

验证

首先, validate 上请求的函数将验证以下︰

  • HTTPStatusCode-必须要 200...299
  • Content-Type-在响应中的此标头必须匹配 Accept 原始请求中的标头

你可以在 Alamofire 在自述文件中找到有关验证的详细信息。

Weakify/Strongify

请确保向弱自我和强烈的自我你封闭,以确保你不会创建一个保留周期。

对主队列调度

你回主队列的调度电话不是必要的。Alamofire 保证你完成处理程序在 responseresponseJSON 已经上主队列调用序列化程序。你其实可以提供您自己的调度队列运行序列化程序如果你希望,但您的解决方案或我既不目前这样做进行调度到主队列调用完全没有必要。

响应的序列化程序

在您特定的情况下,你其实不想使用 responseJSON 的序列化程序。如果你做,你不会最终得到任何数据回来,如果你不通过验证。原因是从 JSON 序列化的响应是什么将作为返回 AnyObject 。如果序列化失败, AnyObject 将为零,你不能读出数据。

相反,使用 response 的序列化程序并尝试解析用手动数据 NSJSONSerialization 。如果失败,那么你可以依靠良好的 ole NSString(data:encoding:) 方法将数据打印出来。

希望这有助于阐明一些相当复杂的方法来得到绊倒了。

赞助商