2017-10-17 1 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() 
} 
이의 시작 부분에 인쇄 라인 ("위도! : (LAT) 경도 :! (론) 온도 :! (온도) 도시 :! (이름)")하게 수행 할 수 있습니다 무엇

코드의 지속적인 실행 후? 당신이 getWeather 완료 후 뭔가를하려는 경우DispatchQueue.main.sync 신속

+3

귀하의 질문을 번역 ... –

+0

당신은 그것을 다운로드 첫 번째 인쇄 결과를 원하는가? –

+0

는 "안녕하세요", "위도 경도"후하게 할을 의미합니까? –

답변

1

, 완료 핸들러를 추가합니다. 개인적으로, 나는 캡처 한 정보를 다시 전달하는 구조를 만들어이 단순화 것 : 그런 다음

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 위에서 나타낸 것처럼 명시 적 모델 객체 및/또는 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을 요청할 수 있습니다 타사 JSON 라이브러리와 스위프트 4의 새로운'JSONDecoder' API와 the' Decodable' 프로토콜을 사용합니다. 개정 된 대답을 참조하십시오. (스위프트 3를 사용하는 경우, 롤. 무시 주시기 바랍니다.) – Rob

+0

감사를 시도 할 것이다 –