【问题标题】:Alamofire best way to recall api on failureAlamofire 在失败时召回 api 的最佳方法
【发布时间】:2017-09-21 09:50:52
【问题描述】:

我需要在收到特定错误时调用 api,例如错误代码 -1005。

我想在 Alamofire 文件中处理这个问题,以便它可以与项目中的所有 api 一起使用。

我在 dataTaskWithHTTPMethod 的 ObjC 的 AFNetworking 中使用以下代码处理此问题:-

if (failure)
        {
            if (error.code == -1005)
            {
                [self POST:URLString parameters:parameters progress:nil success:success failure:failure];
            }           
}

谁能帮我在 Alamofire 中做到这一点?

【问题讨论】:

  • 显示你尝试过的代码
  • 我无法定义 Alamofire 从哪里调用给定请求的成功或失败块
  • 是的,你可以做到
  • 参考这个link

标签: ios swift afnetworking alamofire


【解决方案1】:
 //MARK: Your method

   func hitYourService(){
            showActivityIndicator(decision: true, inViewConroller: self, animated: true)
            let deviceToken = HelpingClass.userDefaultForKey(key: "deviceToken")
            let paramDict = ["email":txtFEmail.text ?? "" ,"password":txtFPassword.text ?? "" ,"device_token":deviceToken]

            NetworkManager.instance().hitPostServiceJsonForm(paramDict, myReqURL: ServiceMethods.serviceBaseURL+ServiceMethods.login, unReachable: {
                // Here you can handle the case if there is no internet connection
            }) { (response) in
                showActivityIndicator(decision: false, inViewConroller: self, animated: true)
                if response != nil{
                    if  response?["error_code"] as! Int == 0{
                        //Handle your response

                    }else{
                        //Show error
                        showHudWithMessage(message: response?["error_msg"] as! String, inViewConroller: self, animated: true, hideAfter: 2)
                    }
                }else{
                    //You can hit back your service
                   self.hitYourService()
                }

            }
        }


//MARK: Alamofire method to hit service, written in NetworkManager class        


        func hitPostServiceJsonForm(_ params:Dictionary<String,Any>, myReqURL:String, unReachable:(() -> Void),handler:@escaping ((Dictionary<String,Any>?) -> Void)) {
            if networkReachable() == false {
                unReachable()
            }
            var request = URLRequest(url: URL(string: myReqURL)!)
            request.httpMethod = "POST"
            request.setValue("application/json", forHTTPHeaderField: "Content-Type")
            print_debug(object: "ReqParameter: \(String(describing: params))") // http url response

            //JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)

            request.httpBody = try! JSONSerialization.data(withJSONObject: params, options: [])



            Alamofire.request(request).responseJSON { response in
                // SwiftLoader.hide()
                print_debug(object: "Request: \(String(describing: response.request))")   // original url request
                print_debug(object: "Response: \(String(describing: response.response))") // http url response
                print_debug(object: "Result: \(response.result)")                         // response serialization result

                print_debug(object: "Result.value \(String(describing: response.result.value))")
                switch response.result {
                case .success:
                    if let jsonDict = response.result.value as? Dictionary<String,Any> {
                        print_debug(object: "Json Response: \(jsonDict)") // serialized json response
                        handler(jsonDict)
                    }
                    else{
                        handler(nil)
                    }
                    if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
                        print("Server Response: \(utf8Text)") // original server data as UTF8 string
                    }
                    break
                case .failure(let error):
                    handler(nil)
                    print_debug(object: error)
                    break
                }
            }
        }

【讨论】:

  • 我想在 alamofire 的课堂上这样做,这样它就可以与所有 api 调用一起工作
  • 你可以把这个方法 -> hitPostServiceJsonForm 放在你的网络类中
  • 在我的项目中看到我在很多地方调用了 api,使用你的解决方案我需要更改我的网络类中的所有 api 调用。我想要的是在 Alamore 类中添加错误处理代码,以便它无处不在
  • 您可以简单地返回 nil 以防服务失败并在您的方法中检查它。如果找到 nil 则返回服务
  • 我知道你在说什么,但我的问题是我需要在调用 API 的任何地方编写此处理。我想要一种可以再次处理和调用 api 的集中方式。
【解决方案2】:

让我们通过一个例子来理解。

我猜你已经创建了一个类来管理那里的所有 web 服务相关的东西。 (如果还没有,那么最好为最佳实践创建一个)。

好的,现在创建两个 typealias 来管理响应。

这里是:-

在这里,我再次假设您想要整个 dictionary 用于成功响应,error 用于失败响应。

typealias successCompletion = (([String:Any]) -> ())
typealias failureCompletion = ((Error) -> ())

现在这里是一个 WSManager 类,用于处理那里的所有 API 相关内容。

    class AlamofireManager {

   static func sampleFunctionOfWebService(successCompletion:successCompletion , failureCompletion:failureCompletion) {

        if success {
            successCompletion(["Key":"success"])
        } else {
            failureCompletion(-1005 as! Error)
        }
    }
}

您需要在函数中传递两个类型别名才能获取 CallBack 在所需的课程中。

这里仅出于理解目的,我们将传递静态 字典 :-> ["Key":"success"] 和静态 -1005 作为错误。

现在如何在我们想要的类中使用这个函数?

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    func wsCalling() {

        AlamofireManager.sampleFunctionOfWebService(successCompletion: { (dict) in

            print(dict)

        }) { (error) in

            if error.code == -1005 {
                self.wsCalling() // recall API Again
            } else {
                // your other logic
            }

        }
    }

}

我在这里没有提到 URLSeeionTask 和 All ,这是件好事 管理 URLSeeionTask。如果你有一个 URLSeeionTask 的实例 以前的 API 然后先取消它,然后再尝试重新调用它。

快乐编码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-30
    • 2014-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-15
    • 2013-05-12
    相关资源
    最近更新 更多