如何使用函数中的JSON数据更新Swift 3中的标签?
出于某种原因,每当我试图使用如何使用函数中的JSON数据更新Swift 3中的标签?,swift,xcode,Swift,Xcode,出于某种原因,每当我试图使用DispatchQueuecode块内部的self.infoLabel.text=String(temp!)用当前温度更新标签时,我会收到以下致命错误消息: unexpectedly found nil while unwrapping an Optional value. 如果有人能帮我找出下面的代码不起作用的原因,我将不胜感激。谢谢 func getCurrentTemp(city: String){ let weatherRequestURL = U
DispatchQueue
code块内部的self.infoLabel.text=String(temp!)
用当前温度更新标签时,我会收到以下致命错误消息:
unexpectedly found nil while unwrapping an Optional value.
如果有人能帮我找出下面的代码不起作用的原因,我将不胜感激。谢谢
func getCurrentTemp(city: String){
let weatherRequestURL = URL(string: "\(openWeatherMapBaseURL)?APPID=\(openWeatherMapAPIKey)&q=\(city)")!
// The data task retrieves the data.
URLSession.shared.dataTask(with: weatherRequestURL) { (data, response, error) in
if let error = error {
// Case 1: Error
print("Error:\n\(error)")
}
else {
//print("Raw data:\n\(data!)\n")
//let dataString = String(data: data!, encoding: String.Encoding.utf8)
//print("Human-readable data:\n\(dataString!)")
do {
// Try to convert that data into a Swift dictionary
let weather = try JSONSerialization.jsonObject(with: data!, options:.allowFragments) as! [String:AnyObject]
if let main = weather["main"] as? [String: Any] {
let temp = main["temp"] as? Double
print("temp\(temp!)")
DispatchQueue.main.sync(execute: {
self.infoLabel.text = String(temp!)
})
//return temp as? String
//let temp_max = main["temp_max"] as? Double
//print("temp\(temp_max!)")
//let temp_min = main["temp_min"] as? Double
//print("temp\(temp_min!)")
}
}
catch let jsonError as NSError {
// An error occurred while trying to convert the data into a Swift dictionary.
print("JSON error description: \(jsonError.description)")
}
}
}
.resume()
}
这里有两种可能性:1)temp为零(不应该是,因为您已经在上面的打印语句中强制将其展开)2)或infoLabel为零,如果您断开了插座连接,则会发生这种情况 它容易检查;在分配上方设置断点,并在调试控制台中键入:
po self.infoLabel
看看是不是零。为了更好地测量,您还需要检查温度
您还可以添加一个print语句来检查self.infoLabel或assert。好的,所以我找到了解决这个问题的临时解决方案(见下文)。我没有将代码放在我创建的函数中,而是将其放在viewDidLoad()函数中。无论出于何种原因,
self.infoLabel?
在我创建的函数中的任何地方都是零
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
print("Sucessful launched weather page.")
let weatherRequestURL = URL(string: "\(openWeatherMapBaseURL)?APPID=\(openWeatherMapAPIKey)&q=\(city)")!
// The data task retrieves the data.
URLSession.shared.dataTask(with: weatherRequestURL) { (data, response, error) in
if let error = error {
// Case 1: Error
print("Error:\n\(error)")
}
else {
//print("Raw data:\n\(data!)\n")
//let dataString = String(data: data!, encoding: String.Encoding.utf8)
//print("Human-readable data:\n\(dataString!)")
do {
// Try to convert that data into a Swift dictionary
let weather = try JSONSerialization.jsonObject(with: data!, options:.allowFragments) as! [String:AnyObject]
if let main = weather["main"] as? [String: Any] {
let temp = main["temp"] as? Double
print("temp\(temp!)")
var tempInFarenheit = ((9/5)*((temp!)-273) + 32).rounded()
DispatchQueue.main.sync(execute: {
self.infoLabel.text = "\(tempInFarenheit) + °"
})
}
}
catch let jsonError as NSError {
// An error occurred while trying to convert the data into a Swift dictionary.
print("JSON error description: \(jsonError.description)")
}
}
}
.resume()
}
虽然这不是最有效的方法,但希望它能帮助其他有同样问题的人。如果我能找到一种更有效的方法,我一定会编辑这篇文章并将其包括在内。非常感谢您抽出时间回复。我尝试了这个,并重拨了插座,它仍然给我相同的错误信息。我注意到,当上述函数中的任何地方(在原始代码中)不起作用时,当我尝试在viewDidLoad()中更改infoLabel的文本时,它成功地起作用。对于问题可能是什么,真的很困惑:-/调用是异步的。标签返回时是否存在?就这一点而言,自我存在吗?另外,要验证是否是标签导致了崩溃,请使用可选链接,而不是隐式展开:self.infoLabel?.text。您还可以打印出self以查看它是否有值。如果异步调用完成时调用的视图控制器不再存在,您可能需要对self进行弱引用或无主引用并退出。只需测试它,在函数内部,使用
print(self.InfoLabel?.text)
将打印nil,而在viewDidLoad()中使用print(self.InfoLabel?.text)
,返回它的正确值。函数self的内部也有它的期望值。