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迅速
如果你想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()
}
@HeltyrCafry - 顺便说一句,我不知道,如果你使用的斯威夫特3或4雨燕,但如果斯威夫特你可能要退休第三方JSON库,并使用雨燕4的新'JSONDecoder' API和的'Decodable'协议。见修订后的答案。 (如果使用斯威夫特3,随意忽略。大声笑。) – Rob
感谢会尝试 –
翻译您的问题... –
你想先打印结果,然后下载呢? –
为“Hello”之后的“纬度经度”带来的是什么意思? –