こんにちは、私はあなただけで非同期プログラミングの典型的な落とし穴に遭遇したと思います。あなたは、URLSessionから戻ってくる前に、タスクの戻り値を求めています。 この例のような補完ハンドラを自分で作成することで、Darkskyの天気データを取得できます。 これについてはクラスを作成する必要はありません。関数だけです。
PSノート私はAlamofire、SwiftyJSON、Glossを使用しており、RESTインターフェイスを使用して複雑さを大幅に軽減しています。これはスイフト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)
}
}
注完了ハンドラが終了し、実際にいくつかのデータまたはエラーが返されたら、私はテキストフィールドを埋めます。
//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
}
}
あなたは委任プロセスを使用することができます
:「effectView」ものを無視し、それが参考になっかもしれませんJSONデータにマッピングされているこれらの構造体を知ることも
そして:-)特別なカーソル待ちスピナーのためでありますあなたのviewcontrollerのパラメータとしてあなたの '詳細'配列でコールバックを取得します。今すぐプロトコルで代理人を迅速に実装する方法を見てみましょう。 – Tann