第一篇文章,請溫和。我在Swift 3,Xcode 8.1中玩弄了JSON數據。我特別從http://forecast.weather.gov/MapClick.php?lat=38.9782&lon=-76.4933&FcstType=json獲取我的數據。我的代碼如下:無法從Swift 3的dataTask中獲取JSON數據
private func getWeatherData(url:URL) -> (currentObservation:Dictionary<String, AnyObject>, currentData:Dictionary<String, AnyObject>) {
var currentObservation:Dictionary = [:] as Dictionary<String, AnyObject>
var currentData:Dictionary = [:] as Dictionary<String, AnyObject>
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil {
print ("Error retrieving URLSession")
}
else
{
if let content = data
{
do
{
let JSONData = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
if let observation = JSONData["currentobservation"] as? Dictionary<String, AnyObject> {
currentObservation = observation
print("currentObservation inside of task: \(currentObservation)\n\n")
}
if let data = JSONData["data"] as? Dictionary<String, AnyObject> {
currentData = data
print("currentData inside of task: \(currentData)")
}
}
catch
{
print("Error in trying JSONSerialization")
}
}
}
}
task.resume()
print("currentObservation outside of task: \(currentObservation) \n\n")
print("currentData outside of task: \(currentData)")
return (currentObservation , currentData)
}
我得到的輸出是:
currentObservation outside of task: [:]
currentData outside of task: [:]
currentObservation: [:]
currentData: [:]
currentObservation inside of task: ["state": MD, "name": Annapolis, United States Naval Academy, "longitude": -76.49, "elev": 3, "Relh": 79, "WindChill": NA, "Weather": Fair, "Altimeter": 1028.7, "latitude": 38.99, "Temp": 46, "SLP": 30.37, "id": KNAK, "timezone": EST, "Weatherimage": nsct.png, "Windd": 0, "Winds": 0, "Visibility": 10.00, "Gust": 0, "Dewp": 40, "Date": 7 Nov 20:54 pm EST]
currentData inside of task: ["hazard": <__NSArrayM 0x60800005a520>(
Frost Advisory, Hazardous Weather Outlook), "weather": <__NSArrayM 0x60800005a490>(
Clear then Areas Frost, Areas Frost then Sunny,
Partly Cloudy then Slight Chance Showers, etc.(edited for brevity)]
我得到一個JSON數據的反應,但我似乎無法保持數據的保持。
我很困惑的幾件事情。首先,爲什麼URLSession.shared.dataTask之外的打印語句在打印語句之前打印?
此外,「currentObservation」和「currentData」的打印語句在函數外調用,並且它們打印在URLSession.shared.dataTask中的打印語句之前。這是爲什麼?
最後,最重要的是,爲什麼JSON數據沒有超出URLSession.shared.dataTask塊呢?
任何洞察將有所幫助。謝謝。
編輯: 這是我現在的代碼基於維諾德的迴應。當我打印它們時,currentObservation和currentData仍然是空的。
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var currentObservation:Dictionary = [:] as Dictionary<String, AnyObject>
var currentData:Dictionary = [:] as Dictionary<String, AnyObject>
let serverURL = URL(string:"http://forecast.weather.gov/MapClick.php?lat=38.9782&lon=-76.4933&FcstType=json")
getWeatherData(serverURL: serverURL!, completion: { serverResponse in
if let observation = serverResponse["currentobservation"] as? Dictionary<String, AnyObject> {
currentObservation = observation
print("currentObservation inside of task: \(currentObservation)\n\n")
}
if let data = serverResponse["data"] as? Dictionary<String, AnyObject> {
currentData = data
print("currentData inside of task: \(currentData)\n\n")
}
})
print("currentObservation outside of task: \(currentObservation)\n\n")
print("currentData outside of task: \(currentData)")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
private func getWeatherData(serverURL:URL, completion:@escaping (AnyObject) ->()){
let task = URLSession.shared.dataTask(with: serverURL) { (data, response, error) in
if error != nil {
print ("Error retrieving URLSession")
}
else
{
if let content = data
{
do
{
let JSONData = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
completion(JSONData)
}
catch
{
print("Error in trying JSONSerialization")
}
}
}
}
task.resume()
}
}
是的,我知道我不應該在所有的視圖控制器違反了MVC的可以這樣做,但我只是玩弄的努力得到它添加的複雜工作之前數據模型和控制器以及UI。謝謝。
'dataTask'以異步方式工作。您不能從包含異步任務的方法返回任何內容。 – vadian
我想這是有道理的。如果在函數調用完成時已完成採樣,那麼如何返回任何內容。謝謝。 – Yrb
Vinod的答案提供了一種使用回調閉包異步返回數據的解決方案。此外,在這裏有幾百個相關的主題。 – vadian