您好我想你剛纔遇到的異步編程的典型陷阱。你要做的是在URLSession返回之前要求任務的返回值。 你可以通過自己製作一個完成處理程序來解決這個問題,就像這個例子,我從Darksky那裏得到一些天氣數據。 請注意,你甚至不需要爲此創建一個類,只是一個函數。
PS注意我使用Alamofire,SwiftyJSON和Gloss,這大大降低了使用REST界面的複雜度。這是Swift 3!
import Alamofire
import SwiftyJSON
import Gloss
typealias DarkSkyWeatherForecast = (_ json : Gloss.JSON?, _ error : Error?) -> Void
func getWeatherForcast(latitude:Double, longitude:Double, completionHandler:@escaping DarkSkyWeatherForecast) -> Void {
let urlString = "https://api.darksky.net/forecast/"+darkSkyKey+"/"+String(latitude)+","+String(longitude)+"?units=si"
Alamofire.request(urlString).responseJSON { (response) in
if let resp = response.result.value {
let json = JSON(resp)
let glossJson = json.dictionaryObject
completionHandler(glossJson, nil)
}else{
completionHandler(nil, response.error)
}
}
}
和呼叫功能是這樣的:
getWeatherForcast(latitude: lat, longitude: lon) { (jsonArg, error) in
if error == nil{
guard let weather = DarkSkyWeather(json: jsonArg!) else {
self.effectView.removeFromSuperview()
return
}
if let ambTemp = weather.currently?.temperature, let windspd = weather.currently?.windSpeed, let windDir = weather.currently?.windBearing{
self.effectView.removeFromSuperview()
self.ambTemperature.text = String(ambTemp)
self.windSpeed.text = String(windspd)
self.windDirection.text = String(windDir)
self.getSpeed()
}
}else{
self.effectView.removeFromSuperview()
let alert = UIAlertController(title: "Error", message: "Could not get weather forecast", preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .default, handler: { (action) in
self.dismiss(animated: true, completion: nil)
})
alert.addAction(okAction)
self.present(alert, animated: true, completion: nil)
}
}
注意,一旦完成處理完畢,實際上要麼返回一些數據或錯誤,我只填寫了文本框。忽略了「effectView」的東西,這是一種特殊的光標等待微調:-)
而且還知道哪些被映射到JSON數據可能是有益的,這些結構:
//common struct for weather data
public struct WeatherDataStruct : Decodable{
let time : Int?
let summary : String?
let icon : String?
let precipIntensity : Double?
let precipProbability : Double?
let precipType : String?
let temperature : Double?
let apparentTemperature : Double?
let dewPoint : Double?
let humidity: Double?
let windSpeed : Double?
let windBearing : Int?
let visibility : Double?
let cloudCover : Double?
let pressure : Double?
let ozone : Double?
public init?(json: JSON){
self.time = "time" <~~ json
self.summary = "summary" <~~ json
self.icon = "icon" <~~ json
self.precipIntensity = "precipIntensity" <~~ json
self.precipProbability = "precipProbability" <~~ json
self.precipType = "precipType" <~~ json
self.temperature = "temperature" <~~ json
self.apparentTemperature = "apparantTemperature" <~~ json
self.dewPoint = "dewPoint" <~~ json
self.humidity = "humidity" <~~ json
self.windSpeed = "windSpeed" <~~ json
self.windBearing = "windBearing" <~~ json
self.visibility = "visibility" <~~ json
self.cloudCover = "cloudCover" <~~ json
self.pressure = "pressure" <~~ json
self.ozone = "ozone" <~~ json
}
}
//hourly weather struct
public struct HourlyStruct : Decodable{
let summary : String?
let icon : String?
let data : [WeatherDataStruct]?
public init?(json: JSON) {
self.summary = "summary" <~~ json
self.icon = "icon" <~~ json
self.data = "data" <~~ json
}
}
//total struct for the whole json answer from darksky weather
public struct DarkSkyWeather : Decodable{
let latitude : Double?
let longitude : Double?
let timezone : String?
let offset : Int?
let currently : WeatherDataStruct?
let hourly : HourlyStruct?
public init?(json: JSON) {
self.latitude = "latitude" <~~ json
self.longitude = "longitude" <~~ json
self.timezone = "timezone" <~~ json
self.offset = "offset" <~~ json
self.currently = "currently" <~~ json
self.hourly = "hourly" <~~ json
}
}
您可以使用授權流程以您的'details'數組作爲您的視圖控制器中的參數獲取回調。現在看看如何在swift中使用協議實現委託。 – Tann