【问题标题】:Alamofire can't get response closure to executeAlamofire 无法执行响应关闭
【发布时间】:2016-05-14 15:53:32
【问题描述】:

Mac OS X 10.11.3 El-Capitan、XCode 7.2.1、Alamofire 3.5.1(来自 Carthage)

试图获得我能想到的最基本的 Alamofire 示例。虽然我是一位经验丰富的开发人员,但我是 XCode 的新手,所以我确信我只是缺少一些基本的东西。我设置了一个新项目,通过 Carthage 添加了 Alamofire,在 main.swift 中添加了一个简单的 get 请求。代码构建并运行,但我的响应闭包中没有任何内容被调用。我添加了 sleep 以尝试并确保等待足够长的时间以使关闭被调用。我打开了 Little Snitch,看到我的项目正在调用 httpbin.org。我尝试了各种 response* 方法。但是关闭永远不会运行,我错过了什么?

main.swift

import Alamofire

print("Start")
var x : String = "main"

Alamofire.request(.GET, "https://httpbin.org/get")
  .responseString {resp in
    print("in response handler")
    print("response \(resp)")
    x = "response"
}

sleep(90)
print("End \(x)")

控制台输出

Start
End main

XCode

xcode screenshot

【问题讨论】:

  • 所以你所有的代码都在viewDidLoad 或者你是如何调用请求的?
  • 它是XCode中的一个命令行应用项目。我刚刚从 XCode 中点击 Run,它会运行我在 main.swift 中的所有内容。至少这是看起来正在发生的事情。控制台输出显示开始和结束打印语句。如果我为不在闭包和调试中的东西设置断点,调试器会在该断点处停止。闭包内的断点永远不会被触发。
  • 这可能是你的问题,请参阅this answer

标签: xcode swift alamofire


【解决方案1】:

不知道为什么,但是在另一个线程上运行完成块对我的命令行工具不起作用;在等待回调之前它仍然完成。我在 http://mgrebenets.github.io/swift/2015/10/08/async-swift-scripting

此方法使用 RunLoop 保持程序运行,直到回调触发。

摘要代码

var keepAlive = true

Alamofire.request("http://httpbin.org/get", parameters: ["foo": "bar"])
            .response(
    responseSerializer: DataRequest.jsonResponseSerializer()) { response in

        print(response.result.value ?? "")                
        keepAlive = false
    }

let runLoop = RunLoop.current
while keepAlive && runLoop.run(mode: RunLoopMode.defaultRunLoopMode, before: Date(timeIntervalSinceNow: 0.1)) {
    // Run, run, run
}

【讨论】:

    【解决方案2】:

    working example的Github repo

    【讨论】:

      【解决方案3】:

      我认为 Alamofire 默认调用主队列中的响应处理程序,因此如果您在主队列/线程中发出请求、睡眠和打印,则在应用程序终止之前不会从主队列执行 responseString。不知道 .responseString,但使用 .response 可以指定队列:

      public func response<T: ResponseSerializerType>(
              queue queue: dispatch_queue_t? = nil,
              responseSerializer: T,
              completionHandler: Response<T.SerializedObject, T.ErrorObject> -> Void)
              -> Self
      

      【讨论】:

      • 哦,所以我的 main.swift 和处理程序设置为在同一个队列上运行,而我的 main.swift 有效地阻塞了队列,所以没有其他东西可以运行。好的,这是有道理的。所以我需要告诉 Alamofire 将我的响应处理程序放在不同的队列中,然后我猜?如果有人有 Alamofire 代码的示例,我将不胜感激
      • .response( queue: dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), responseSerializer: Request.stringResponseSerializer(encoding: NSUTF8StringEncoding)) { response in // Print here }
      • 搞定了。非常感谢@tapani 为我指明了正确的方向。为了完整起见,本文中的代码是如何在后台(非主)线程stackoverflow.com/a/29883233/204396 上获取响应处理程序的示例
      猜你喜欢
      • 2021-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-20
      • 2016-04-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多