2017-10-17 2 views
0
override func viewDidLoad() { 
    super.viewDidLoad() 
    DispatchQueue.global().async(execute: { 
     print("teste") 
      print("main thread") 
      self.getWeather(city: "Minsk") 
     print("Hello") 

    }) 
    print("working") 
} 

func getWeather(city: String) { 

    let cityEscaped = city.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlHostAllowed) 

    let path = "http://samples.openweathermap.org/data/2.5/weather?q=Minsk&appid=..." // appid removed for the sake of privacy 
    let url = URL(string: path) 
    let session = URLSession.shared 

    let task = session.dataTask(with: url!) { (data: Data?, response: URLResponse?, error: Error?) in 
     let json = JSON(data!) 
     let lon = json["coord"]["lon"].double 
     let lat = json["coord"]["lat"].double 
     let temp = json["main"]["temp"].double 
     let name = json["name"].string 
     let desc = json["weather"][0]["description"].string 

     print("Lat: \(lat!) lon:\(lon!) temp: \(temp!) city: \(name!)") 
    } 

    task.resume() 
} 

Was die Drucklinie gebracht zu Beginn dieses getan werden kann ("Lat: (lat) lon :! (Lon) Temp :! (Temp) Stadt :! (Name)") und nach der fortgesetzten Ausführung von Code?DispatchQueue.main.sync swift

+3

übersetzen Ihre Frage ... –

+0

möchten Sie erste Druckergebnis dann herunterladen? –

+0

zu „Hallo“ gebracht, nachdem „lat lon“ bedeuten? –

Antwort

1

Wenn Sie etwas tun wollen nach getWeather getan wird, einen Abschluss-Handler hinzuzufügen. Persönlich würde ich dies vereinfachen, indem eine Struktur zu schaffen, die erfassten Informationen weitergeben zurück:

struct WeatherReport { 
    let latitude: Double 
    let longitude: Double 
    let temperature: Double 
    let name: String 
    let desc: String 
} 

func getWeather(city: String, completion: @escaping (WeatherReport?, Error?) -> Void) { 

    ... 

    let task = session.dataTask(with: url!) { data, _, error in 
     ... 
     guard successful else { 
      completion(nil, error) 
      return 
     } 

     let weatherReport = WeatherReport(...) 
     completion(weatherReport, nil) 
    } 

    task.resume() 
} 

Dann

override func viewDidLoad() { 
    super.viewDidLoad() 

    getWeather(city: "Minsk") { weatherReport, error in 
     guard let weatherReport = weatherReport, error == nil else { 
      print(error?.localizedDescription ?? "Unknown error") 
      return 
     } 

     DispatchQueue.main.async { 
      // do something with `weatherReport` here 
     } 
    } 
} 

Hinweis, dataTask bereits (a) asynchron ausgeführt wird; und (b) läuft seine Fertigstellung Handler auf einem Hintergrund-Thread, so viewDidLoad muss ausdrücklich etwas versenden es tut mit Modellobjekten und/oder der Benutzeroberfläche an der Hauptwarteschlange in der getWeather Abschluss handler wie oben gezeigt.


By the way, wenn Sie Swift mit 4 sind, würde ich vorschlagen, auszuschließen, dass Dritte JSON-Parsing-Bibliothek und verwendet JSONDecoder und eine Modellstruktur, die Decodable, zB:

struct Coordinate: Decodable { 
    let latitude: Double 
    let longitude: Double 

    enum CodingKeys: String, CodingKey { 
     case latitude = "lat" 
     case longitude = "lon" 
    } 
} 

struct WeatherReportDetails: Decodable { 
    let temperature: Double 
    let pressure: Double 
    let humidity: Double 
    let temperatureMin: Double 
    let temperatureMax: Double 

    enum CodingKeys: String, CodingKey { 
     case pressure, humidity 
     case temperature = "temp" 
     case temperatureMin = "temp_min" 
     case temperatureMax = "temp_max" 
    } 
} 

struct WeatherReport: Decodable { 
    let coordinate: Coordinate 
    let details: WeatherReportDetails 
    let name: String 

    enum CodingKeys: String, CodingKey { 
     case name 
     case coordinate = "coord" 
     case details = "main" 
    } 
} 

und dann

func getWeather(city: String, completion: @escaping (WeatherReport?, Error?) -> Void) { 
    let cityEscaped = city.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlHostAllowed)! 
    let urlString = "http://samples.openweathermap.org/data/2.5/weather?q=" + cityEscaped + "&appid=..." // appid removed for privacy’s sake 
    let url = URL(string: urlString)! 

    let task = URLSession.shared.dataTask(with: url) { data, _, error in 
     guard let data = data, error == nil else { 
      completion(nil, error) 
      return 
     } 

     do { 
      let weatherReport = try JSONDecoder().decode(WeatherReport.self, from: data) 
      completion(weatherReport, nil) 
     } catch { 
      completion(nil, error) 
     } 
    } 

    task.resume() 
} 
+0

@HeltyrCafry - By the way, ich weiß nicht, ob Sie verwenden Swift 3 oder Swift 4, aber wenn Swift könnte für Sie wollen die in Rente gehen dritte JSON Bibliothek und neuen Swift 4 der Verwendung 'JSONDecoder' API und der' Decodable' Protokoll. Siehe revidierte Antwort. (Wenn Swift mit 3, fühlen Sie sich frei zu ignorieren. Lol.) – Rob

+0

Dank wird versuchen, –