如何使用Alamofire发出同步请求?

Fra*_*ero 12 synchronous ios swift alamofire

我正在尝试使用同步请求Alamofire.我查看了Stackoverflow并发现了这个问题:使异步alamofire请求同步.

我看到接受的答案用于completion使Alamofire请求同步但我无法使其工作.这是我的简化代码:

func loadData(completion: (Bool)) -> (Int, [String], [String], [String]){

    Alamofire.request(url!, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: nil).responseJSON { response in

        switch(response.result) {
        case .success(_):
            if let JSON = response.result.value as! [[String : AnyObject]]!{
                 //Here I retrieve the data
            }

            completion(true)
            break

        case .failure(_):
            print("Error")
            completion(false)
            break  
        }
   }

   return (numberRows, nameArray, ageArray, birthdayArray)
}
Run Code Online (Sandbox Code Playgroud)

使用此代码,我在尝试制作时遇到错误completion(bool value).我得到的错误如下:

无法调用非函数类型'Bool'的值

我尝试使用很多示例使用完成来同步获取值(因为我需要先检索数据才能在表上显示它,同时获取该表的行数)但没有成功.

如何使用该完成来获得同步响应?

提前致谢!

Ali*_*Gol 2

更新:

\n

您可以使用信号量来冻结调用线程,直到任务返回值:参考

\n
\nfunc performSynchronously(request: URLRequest) -> (data: Data?, response: URLResponse?, error: Error?) {\n        let semaphore = DispatchSemaphore(value: 0)\n\n        var data: Data?\n        var response: URLResponse?\n        var error: Error?\n\n        let task = self.dataTask(with: request) {\n            data = $0\n            response = $1\n            error = $2\n            semaphore.signal()\n        }\n\n        task.resume()\n        semaphore.wait()\n\n        return (data, response, error)\n    }\n\n
Run Code Online (Sandbox Code Playgroud)\n

现在,让\xe2\x80\x99s 说我们想要在 SwiftUI 视图中渲染由上述 WWDCItemsLoader 加载的项目。关于如何做到这一点的初步想法可能是做这样的事情:参考

\n
\nfunc performSynchronously(request: URLRequest) -> (data: Data?, response: URLResponse?, error: Error?) {\n        let semaphore = DispatchSemaphore(value: 0)\n\n        var data: Data?\n        var response: URLResponse?\n        var error: Error?\n\n        let task = self.dataTask(with: request) {\n            data = $0\n            response = $1\n            error = $2\n            semaphore.signal()\n        }\n\n        task.resume()\n        semaphore.wait()\n\n        return (data, response, error)\n    }\n\n
Run Code Online (Sandbox Code Playgroud)\n

旧答案:(Swift 2.0)

\n

当您使用完成处理程序时,不要使用返回。

\n
func loadData(completion: @escaping (_ number: Int, _ strArr1: [String], _ strArr2: [String], _ strArr3: [String]) -> ()){\n\n  Alamofire.request(url!, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: nil).responseJSON { response in\n    \n    switch(response.result) {\n    case .success(_):\n        if let JSON = response.result.value as! [[String : AnyObject]]!{\n            //Here I retrieve the data\n        }\n        completion(number: numberRows, strArr1 : nameArray, strArr2 : ageArray, strArr3: birthdayArray)\n        break\n        \n    case .failure(_):\n        print("Error")\n        completion(number: numberRows, strArr1 : nameArray, strArr2 : ageArray, strArr3: birthdayArray)\n        break\n    }\n  }\n}\n\nloadData (completion: { (number, strArr1, strArr2, strArr3) in\n    // do it\n    // for exapmple\n    self.number = number\n    self.strArr1 = strArr1\n    // and so on\n    \n})\n
Run Code Online (Sandbox Code Playgroud)\n

或者,如果您想在闭包中返回任何值,则必须使用完成处理程序来返回任何值或类似的东西,例如,如果您想返回布尔值:

\n
func loadData(completion:(number: numberRows, strArr1 : nameArray, strArr2 : ageArray, strArr3: birthdayArray) -> (Bool))\n
Run Code Online (Sandbox Code Playgroud)\n

并在loadData

\n
loadData( completion: { ( number, strArr1, strArr2, strArr3 ) -> (Bool) in\n       # code \n       return False\n})\n
Run Code Online (Sandbox Code Playgroud)\n

或者有些人有其他想法。

\n

我使用 swift 3。但如果您想要另一个版本的 swift,请注意外部参数名称和内部参数名称,例如:@escaping (_ number: Int, _ strArr1: [String], _ strArr2: [String], _ strArr3: [String]) -> ())

\n

如果你想设置外部参数名称,只需删除_并设置参数名称即可。

\n

  • 这仍然是异步的...因此 {response in } 块...这基本上是回调 (2认同)