Swift:解析 JSON 字典值
Swift: Parsing JSON Dictionary Values
我正在尝试解析 JSON 数据。我能做的是将 JSON 数据保存为 NSData 文件。然后我可以将其读取为 NSDictionary 并为相应的文本字段设置一些值。我不能做的是将 JSON 中的这些值直接放到相应的文本字段中。数据来源是 Open Weather Map。这对我来说并不重要。我只需要数据来练习 JSON 解析。无论如何,以下是我的。
@IBOutlet weak var coordField1: UITextField!
@IBOutlet weak var countryField1: UITextField!
@IBOutlet weak var ideeField1: UITextField!
@IBOutlet weak var nameField1: UITextField!
@IBOutlet weak var cntField1: UITextField!
@IBOutlet weak var codField1: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
enum JSONError: String, ErrorType {
case NoData = "ERROR: no data"
case ConversionFailed = "ERROR: conversion from JSON failed"
}
let urlPath = "http://api.openweathermap.org/data/2.5/forecast/city?id=524901&APPID=fb1b5dcb756e9a52c49ee6377a02d879"
guard let endpoint = NSURL(string: urlPath) else { print("Error creating endpoint");return }
let request = NSMutableURLRequest(URL:endpoint)
NSURLSession.sharedSession().dataTaskWithRequest(request) { (data,response,error) -> Void in
do {
guard let dat = data else { throw JSONError.NoData }
guard let jsonDict = try NSJSONSerialization.JSONObjectWithData(dat,options:[]) as? NSDictionary else { throw JSONError.ConversionFailed }
//print(json)
if let items1 = jsonDict["city"] as? NSDictionary {
if let a = items1["coord"] {
if let lat = a["lat"] as? NSNumber {
print("\(lat.stringValue)") // It prints "55.75222"
self.coordField1.text = "lat: " + lat.stringValue as String + " "
}
if let lon = a["lon"] as? NSNumber {
print("\(lon.stringValue)") // √
self.coordField1.text = self.coordField1.text! + "lon: " + lon.stringValue as String
}
}
}
let jdata:NSData = NSKeyedArchiver.archivedDataWithRootObject(jsonDict)
jdata.writeToFile(self.filePath1(), atomically:true) // saving JSON as an NSData file
} catch let error as JSONError {
print(error.rawValue)
} catch {
print(error)
}
}.resume()
}
}
Xcode 迫使我将 self 放在每个文本字段之前。我可以想象为什么。无论如何,结果,我的文本字段是空的。应用程序不会崩溃。我做错了什么?
谢谢。
@J.Wang 指出了正确的事情。问题是 UI 没有在主线程上更新。正如文档所述,completionHandler
将在委托队列上执行,因此我们必须将其与主队列一起分派。顺便说一句,我还收到警告,该应用程序正在尝试修改后台线程上的自动布局...
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.coordField1.text = "lat: " + lat.stringValue as String + " "
})
我正在尝试解析 JSON 数据。我能做的是将 JSON 数据保存为 NSData 文件。然后我可以将其读取为 NSDictionary 并为相应的文本字段设置一些值。我不能做的是将 JSON 中的这些值直接放到相应的文本字段中。数据来源是 Open Weather Map。这对我来说并不重要。我只需要数据来练习 JSON 解析。无论如何,以下是我的。
@IBOutlet weak var coordField1: UITextField!
@IBOutlet weak var countryField1: UITextField!
@IBOutlet weak var ideeField1: UITextField!
@IBOutlet weak var nameField1: UITextField!
@IBOutlet weak var cntField1: UITextField!
@IBOutlet weak var codField1: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
enum JSONError: String, ErrorType {
case NoData = "ERROR: no data"
case ConversionFailed = "ERROR: conversion from JSON failed"
}
let urlPath = "http://api.openweathermap.org/data/2.5/forecast/city?id=524901&APPID=fb1b5dcb756e9a52c49ee6377a02d879"
guard let endpoint = NSURL(string: urlPath) else { print("Error creating endpoint");return }
let request = NSMutableURLRequest(URL:endpoint)
NSURLSession.sharedSession().dataTaskWithRequest(request) { (data,response,error) -> Void in
do {
guard let dat = data else { throw JSONError.NoData }
guard let jsonDict = try NSJSONSerialization.JSONObjectWithData(dat,options:[]) as? NSDictionary else { throw JSONError.ConversionFailed }
//print(json)
if let items1 = jsonDict["city"] as? NSDictionary {
if let a = items1["coord"] {
if let lat = a["lat"] as? NSNumber {
print("\(lat.stringValue)") // It prints "55.75222"
self.coordField1.text = "lat: " + lat.stringValue as String + " "
}
if let lon = a["lon"] as? NSNumber {
print("\(lon.stringValue)") // √
self.coordField1.text = self.coordField1.text! + "lon: " + lon.stringValue as String
}
}
}
let jdata:NSData = NSKeyedArchiver.archivedDataWithRootObject(jsonDict)
jdata.writeToFile(self.filePath1(), atomically:true) // saving JSON as an NSData file
} catch let error as JSONError {
print(error.rawValue)
} catch {
print(error)
}
}.resume()
}
}
Xcode 迫使我将 self 放在每个文本字段之前。我可以想象为什么。无论如何,结果,我的文本字段是空的。应用程序不会崩溃。我做错了什么?
谢谢。
@J.Wang 指出了正确的事情。问题是 UI 没有在主线程上更新。正如文档所述,completionHandler
将在委托队列上执行,因此我们必须将其与主队列一起分派。顺便说一句,我还收到警告,该应用程序正在尝试修改后台线程上的自动布局...
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.coordField1.text = "lat: " + lat.stringValue as String + " "
})