如何使此UIKit网络调用获取图像-而不是重复
如何使此UIKit网络调用获取图像-而不是重复
许多Cocoa和CocoaTouch方法在Objective-C中使用块实现完成回调,在Swift中使用闭包实现。然而,在Playground中尝试时,完成回调从未被调用。例如:
// Playground - 名词:人们可以玩耍的地方
import Cocoa
import XCPlayground
let url = NSURL(string: "http://stackoverflow.com")
let request = NSURLRequest(URL: url)
NSURLConnection.sendAsynchronousRequest(request, queue:NSOperationQueue.currentQueue() {
response, maybeData, error in
// 这个块从未被调用?
if let data = maybeData {
let contents = NSString(data:data, encoding:NSUTF8StringEncoding)
println(contents)
} else {
println(error.localizedDescription)
}
}
我可以在Playground时间轴中看到控制台输出,但是我的完成块中的println
从未被调用...
问题的原因是XCode 7.1中的XCPSetExecutionShouldContinueIndefinitely()已被弃用。现在正确的做法是首先将当前页面的indefinite execution属性设置为true,然后在执行完成时指示execution的结束。
解决方法是导入XCPlayground,将XCPlaygroundPage.currentPage.needsIndefiniteExecution属性设置为true,然后使用NSURLSession.sharedSession().dataTaskWithURL()方法进行网络调用,并在执行完成后调用XCPlaygroundPage.currentPage.finishExecution()结束execution。
以下是一个示例代码:
import Foundation
import XCPlayground
// 设置indefinite execution为true
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
// 发起网络请求
NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: "http://stackoverflow.com")!) {
result in
print("Got result: \(result)")
// 执行完成,结束execution
XCPlaygroundPage.currentPage.finishExecution()
}.resume()
通过以上方法,可以解决这个问题,并成功进行网络调用并获取到图片。
问题的出现原因是:在使用Playground进行网络调用时,需要设置XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
来等待异步操作完成,否则Playground会在主线程结束后立即终止,导致异步操作没有机会执行完毕。
解决方法是:在进行网络调用前,添加XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
来设置Playground的运行模式为等待异步操作完成。这样,在主线程结束后,Playground会继续运行主循环以等待异步操作完成。另外,可以通过设置timeout的值来配置Playground的超时时间。
以下是使用Swift 3和Swift 2进行网络调用的示例代码:
Swift 3的示例代码:
import UIKit
import PlaygroundSupport
let url = URL(string: "http://stackoverflow.com")!
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else {
print(error ?? "Unknown error")
return
}
let contents = String(data: data, encoding: .utf8)
print(contents!)
}.resume()
PlaygroundPage.current.needsIndefiniteExecution = true
Swift 2的示例代码:
import UIKit
import XCPlayground
let url = NSURL(string: "http://stackoverflow.com")
let request = NSURLRequest(URL: url!)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.currentQueue()) { response, maybeData, error in
if let data = maybeData {
let contents = NSString(data:data, encoding:NSUTF8StringEncoding)
println(contents)
} else {
println(error.localizedDescription)
}
}
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
需要注意的是,从DP4开始,XCPlayground
框架也可以在iOS Playgrounds中使用。
更新的方法是使用XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
来等待异步操作完成。
更新的方法是:添加import PlaygroundSupport
并使用PlaygroundPage.current.needsIndefiniteExecution = true
来设置Playground的运行模式为等待异步操作完成。