DispatchQueue.main.sync迅速

DispatchQueue.main.sync迅速

问题描述:

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() 
} 

什么可以在今年年初做才能带来的打印线( “纬度:(LAT)LON:!(经度)温度:!(TEMP)城市:!(名称)”)与上面的代码继续执行后?DispatchQueue.main.sync迅速

+3

翻译您的问题... –

+0

你想先打印结果,然后下载呢? –

+0

为“Hello”之后的“纬度经度”带来的是什么意思? –

如果你想getWeather完成后做一些事情,添加完成处理。就个人而言,我会通过创建一个结构,传回捕获的信息简化这个:

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() 
} 

然后

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 
     } 
    } 
} 

注意,dataTask已经(一)以异步方式运行;和(b)运行在后台线程其完成处理程序,因此具有viewDidLoad明确地调度任何它确实与模型对象和/或在getWeather完成处理程序的UI到主队列中,如上所示。


顺便说一句,如果你使用斯威夫特4,我建议消除第三方JSON解析库,并使用JSONDecoder和模型结构,是Decodable,如:

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" 
    } 
} 

然后

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 - 顺便说一句,我不知道,如果你使用的斯威夫特3或4雨燕,但如果斯威夫特你可能要退休第三方JSON库,并使用雨燕4的新'JSONDecoder' API和的'Decodable'协议。见修订后的答案。 (如果使用斯威夫特3,随意忽略。大声笑。) – Rob

+0

感谢会尝试 –