通常,有必要为网络实现一个类。这是一个将获取URL并提供数据的类。所有这些都是为了不对额外的逻辑控制器进行评分。我遇到了这样一个问题,当你第一次创建一个View时,数据不会出现。这是网络类:
private static var dataTask: NSURLSessionDataTask?
private static var dataJSON: NSData?
private static var sessionConfig: NSURLSessionConfiguration = {
var configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
configuration.allowsCellularAccess = false
configuration.HTTPMaximumConnectionsPerHost = 2
configuration.HTTPAdditionalHeaders = ["Accept": "application/json"]
configuration.timeoutIntervalForRequest = 30.0
configuration.timeoutIntervalForResource = 60.0
return configuration
}()
static func getListObjectsBy(url: String?) -> NSData? {
let session = NSURLSession(configuration: sessionConfig)
log.debug("DataTask start")
dataTask = session.dataTaskWithURL(NSURL(string: url!)!) { (data, response, error) in
log.debug("if error = error")
if let error = error {
print(error.localizedDescription)
} else if let httpResponse = response as? NSHTTPURLResponse {
log.debug("if httpResponse")
if httpResponse.statusCode == 200 {
dataJSON = data
} else {
print("Bad request")
}
}
}
dataTask?.resume()
log.debug("DataTask Resume")
return dataJSON
}
我的主控制器中的方法viewDidLoad:
let response = Network.getListObjectsBy("http://lb.rmc.su/api-dev/v2/wc/5")
print(String(response))
我的日志说我,数据返回零。注意,我在控制器与SWRevealViewController之间切换。重新加载主视图控制器时,将返回数据。我做了什么?
答案 0 :(得分:1)
您似乎误解了这是一个异步调用。
static func getListObjectsBy(url: String?) -> NSData? {
let session = NSURLSession(configuration: sessionConfig)
log.debug("DataTask start")
dataTask = session.dataTaskWithURL(NSURL(string: url!)!) { (data, response, error) in
// Everything in this block is happening on a separate thread.
log.debug("if error = error")
if let error = error {
print(error.localizedDescription)
} else if let httpResponse = response as? NSHTTPURLResponse {
log.debug("if httpResponse")
if httpResponse.statusCode == 200 {
// this won't happen until the data comes back from the remote call.
dataJSON = data
} else {
print("Bad request")
}
}
}
// This code here does not wait for the response from the remote.
// The call to the remote is sent then this code
// is immediately executed WITHOUT WAITING
dataTask?.resume()
log.debug("DataTask Resume")
// dataJSON will be nil until the remote answers.
return dataJSON
}
执行此操作时:
let response = Network.getListObjectsBy("http://lb.rmc.su/api-dev/v2/wc/5")
print(String(response))
遥控器还没有回答,所以你会得到零。
您的下一个问题可能是"我该怎么办?"。在不知道你正在做的其他事情的情况下,答案是不清楚的。
线程
多个执行线程就像两个程序同时运行。想想2个人同时处理两个不同的任务。为了使界面保持响应,iOS使用一个执行线程来更新屏幕。如果一个进程必须运行需要很长时间,我们就不希望屏幕等到完成为止。假设您必须从某个远程系统获取数据,并且该远程系统速度很慢,您的设备将会冻结,直到响应回来。为避免这种情况,调用远程系统等活动在另一个线程中完成。请求被发送到操作系统本身,并且操作系统被告知在操作完成时回调。
这就是这里发生的事情 设置发送到操作系统的请求。
dataTask = session.dataTaskWithURL(NSURL(string: url!)!)
告诉操作系统开始工作。
dataTask?.resume()
这个块是AKA关闭的回调。当远程调用完成后,iOS将运行此代码。
dataTask = session.dataTaskWithURL(NSURL(string: url!)!) {
// Closure starts here
// Gets called when the remote has sent a response.
(data, response, error) in
// Everything in this block is happening on a separate thread.
log.debug("if error = error")
etc
}
这意味着您必须等到响应返回后再打印输出。您可以在函数中使用闭包来执行此操作。
public typealias CompletionHandler = (data: NSData?, error: NSError?) -> Void
static func getListObjectsBy(url: String?, completion: CompletionHandler) {
let session = NSURLSession(configuration: sessionConfig)
log.debug("DataTask start")
dataTask = session.dataTaskWithURL(NSURL(string: url!)!) {
(data, response, error) in
// Everything in this block is happening on a separate thread.
log.debug("if error = error")
if let error = error {
print(error.localizedDescription)
} else if let httpResponse = response as? NSHTTPURLResponse {
log.debug("if httpResponse")
if httpResponse.statusCode == 200 {
// this won't happen until the data comes back from the remote call.
} else {
print("Bad request")
}
}
// Call your closure
completion(data, error)
}
// This code here does not wait for the response from the remote.
// The call to the remote is sent then this code
// is immediately executed WITHOUT WAITING
dataTask?.resume()
log.debug("DataTask Resume")
}
在您的通话代码中,您可以这样做:
Network.getListObjectsBy("http://lb.rmc.su/api-dev/v2/wc/5") {
(data, error) in
if let data == data {
print(data)
}
}