同时多次调用 Alamofire、Swift 中的 API

kin*_*nza 3 asynchronous ios swift alamofire

我的应用程序中有一个表格视图,如下所示:

在此输入图像描述

我需要的是,当用户点击心脏图像时,请求会发送到服务器以更改该表视图项的状态,并且响应(成功或错误)应该返回。这是点击时调用的代码:

var manager = Alamofire.SessionManager.default
manager = Alamofire.SessionManager(configuration: configuration)
manager.request(######, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: headers).responseJSON(completionHandler: { response in

                switch response.result {
                case .success:
                    print(response)

                    let responseJson = JSON(response.result.value!)

                    // parsing JSON response using swiftyJSON
                    let code = (responseJson["code"]).int
                    let successStatus = responseJson["success"]
                    let message = (responseJson["message"]).rawString()

                    if ((code == 200) && (successStatus == true))
                    {
                        success()
                    }
                    else if (successStatus == false)
                    {
                        let errorObj = CError()
                        if ((code == 401) || (code == 404) || (code == 409))
                        {
                            errorObj.message = message!
                            errorObj.code = code!
                            error(errorObj)
                        }

                        else if ((code == 400) || (code == 500))
                        {
                            let object = response.result.value as? [String:Any]
                            let responseErrors = object!["errors"] as? [String:Any]
                            errorObj.responseErrors = responseErrors
                            errorObj.message = message!
                            errorObj.code = code!
                            error(errorObj)
                        }
                        else
                        {
                            errorObj.message = "Error processing request"
                            errorObj.code = 500
                            error(errorObj)
                        }
                    }

                case .failure (let serverError):
                    let errorObj = CError()
                    if (serverError._code == NSURLErrorTimedOut)
                    {
                        errorObj.message = "Request timed out"
                    }
                    else
                    {
                        errorObj.message = "Error sending request to server"
                    }
                    errorObj.code = 500
                    error(errorObj)
                }
            }
            )
Run Code Online (Sandbox Code Playgroud)

如果我只点击一项,一切都会顺利。但是,当我点击多个项目时,假设我点击了两项,则会调用代码的错误块:

case .failure (let serverError):
                        let errorObj = CError()
                        if (serverError._code == NSURLErrorTimedOut)
                        {
                            errorObj.message = "Request timed out"
                        }
                        else
                        {
                            errorObj.message = "Error sending request to server" //this line gets called
                        }
                        errorObj.code = 500
                        error(errorObj)
                    }
Run Code Online (Sandbox Code Playgroud)

之后,一项的成功响应就会返回。

从目前的情况我了解到的是:

  • 对服务器的一次调用就完成了。
  • 它的回应还没有回来,第二个电话又响了。
  • 此调用会阻止第一个请求并调用其错误块。
  • 然后第二个调用需要时间来处理并且其响应返回(成功块被调用)

根据 Alamofire 的文档,它的调用是在后台处理的。但根据此https://github.com/Alamofire/Alamofire/issues/1922,默认情况下会在主线程上调用响应。我认为这就是同步被阻止的问题。为了在后台处理,我尝试了这种方法:

let queue = DispatchQueue(label: "favAdv", qos: .background, attributes: .concurrent)
manager.request(urlAdventureFavouriteStatus, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: headers).responseJSON(queue: queue) { response in .....
Run Code Online (Sandbox Code Playgroud)

但这对我不起作用。谁能建议我解决这个问题?如果我的理解有任何错误,请纠正它,因为我是 iOS 新手。

我正在使用 Xcode 9.1、Swift 4、Alamofire 4。

kin*_*nza 5

后来我通过添加以下内容解决了这个问题:

let configuration = URLSessionConfiguration.default
configuration.httpMaximumConnectionsPerHost = 10 // change the number according to need
Run Code Online (Sandbox Code Playgroud)

添加此功能将能够同时发送 10 个请求。