DispatchQueue.main.sync swift


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:(lat!) lon:(lon!)温度:(温度!)城市:(名字!"之后会继续执行吗?

如果要

在完成后执行某些操作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已经 (a) 异步运行;(b) 在后台线程上运行其完成处理程序,因此viewDidLoad必须显式调度它对模型对象和/或 UI 所做的任何操作到getWeather完成处理程序中的主队列,如上所示。


顺便说一下,如果您使用的是 Swift 4,我建议删除第三方 JSON 解析库并使用JSONDecoderDecodable的模型结构,例如:

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

相关内容

  • 没有找到相关文章

最新更新