【发布时间】:2014-10-24 13:08:06
【问题描述】:
以下 Swift 代码必须运行两次才能在标签中显示 JSON 数据。在第一次运行时,标签只是保持空白。在我看来,这个问题可能与最后运行的代码的 JSON 部分类似,但我不知道为什么。我已经包含了下面的代码。我还是个菜鸟,所以要温柔:D
class ViewController: UIViewController {
@IBOutlet weak var labelDegrees: UILabel!
@IBOutlet weak var labelSpeed: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Set logo in nav bar
navigationItem.titleView = UIImageView(image: UIImage(named: "logo"))
// Global save values
var appDel: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
var context: NSManagedObjectContext = appDel.managedObjectContext!
// JSON Fetching
let urlPath = "http://api.openweathermap.org/data/2.5/weather?lat=55.564120&lon=12.568605"
let url = NSURL(string: urlPath)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url!, completionHandler: {data, response, error -> Void in
if (error != nil) {
println(error)
}
else {
// Delete old entries in CoreData
var request = NSFetchRequest(entityName: "WindData")
request.returnsObjectsAsFaults = false
var results = context.executeFetchRequest(request, error: nil)
for result in results! {
context.deleteObject(result as NSManagedObject)
context.save(nil)
}
// Start fetching JSON
let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
var item = jsonResult["wind"] as NSDictionary
var degrees:Float = item["deg"] as Float
var speed:Float = item["speed"] as Float
// Start saving JSON
var newItem = NSEntityDescription.insertNewObjectForEntityForName("WindData", inManagedObjectContext: context) as NSManagedObject
var speedValue:Float = speed as Float
var degreesValue:Float = degrees as Float
newItem.setValue(speedValue, forKey: "speed")
newItem.setValue(degreesValue, forKey: "degrees")
context.save(nil)
}
})
task.resume()
// Start fetching from CoreData
var request = NSFetchRequest(entityName: "WindData")
request.returnsObjectsAsFaults = false
var results = context.executeFetchRequest(request, error: nil)
if results!.count > 0 {
for result in results as [NSManagedObject] {
let degrees:Float = result.valueForKey("degrees")! as Float
let speed:Float = result.valueForKey("speed")! as Float
if speed > 6.0 {
self.labelDegrees.text = "Go kitesurf: \(speed) m/s"
}
else {
self.labelDegrees.text = "Stay in: \(speed) m/s"
}
}
}
else {
println("No data")
}
}
【问题讨论】:
-
“开始从核心数据获取”之后的代码将在
NSURLSession完成处理程序关闭之前运行之前。这段代码也应该进入闭包。此外,由于该闭包可能不会在主线程上运行,因此不要忘记使用dispatch_async(dispatch_get_main_queue()) { ... }将 UI 更新分派回主线程。 -
谢谢 Rob,这很有道理