前提・実現したいこと
現在位置情報から国土地理院のAPIを使って標高を取得するアプリを作成しています。
標高を取得する操作をControllerとModelに分けて実装しようとしたところうまくいきませんでした。
発生している問題・エラーメッセージ
標高の取得が完了する前にUIの更新をしてしまって、画面に標高の表示がうまく反映されない。
該当のソースコード
Controllerで位置情報を取得したら、ModelのgetElevationで標高を取得しています。
このAPIを使って取得した標高をViewにわたすことができずにいます。
常に0.0mが表示されてしまう状況です。
Controller
1func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 2 self.customView.elevation = customModel.getElevation(locations) 3}
Model
1var elevationString: String = "0.0m" 2private var afterElevation:Double = 0.0 3private var beforeElevation:Double = pow(10, 5) 4 5func getElevation(_ Locations: [CLLocation]) -> String{ 6 7 self.locations = Locations 8 9 guard let coordinate = Locations.first?.coordinate else {return elevationString} 10 11 userLocation = CLLocationCoordinate2DMake(coordinate.latitude, coordinate.longitude) 12 13 // 国土地理院のURL 14 let baseUrl = "https://cyberjapandata2.gsi.go.jp/general/dem/scripts/getelevation.php?" 15 // ロングタップ地点でクエリを設定する 16 if let userLocation = userLocation { 17 let lonUrl = "&lon=" + userLocation.longitude.description 18 let latUrl = "&lat=" + userLocation.latitude.description 19 // アウトプット形式をJSONに設定する 20 let outtypeUrl = "&outtype=JSON" 21 // URLとクエリを連結 22 let listUrl = baseUrl + lonUrl + latUrl + outtypeUrl 23 // URLを生成する 24 guard let url = URL(string: listUrl) else { return elevationString} 25 26 let task = URLSession.shared.dataTask(with: url) { (data, response, error) in 27 if error != nil { 28 print(error!.localizedDescription) 29 } 30 guard let data = data else { return } 31 // JSONを取得する 32 if let json = try? JSONDecoder().decode(ElevationData.self, from: data) { 33 DispatchQueue.main.async { 34 // JSONから標高を取得する 35 self.afterElevation = json.elevation 36 self.measuringElevation() 37 self.elevationString = String(format: "%.2fm", self.gotElevation) 38 self.beforeElevation = self.afterElevation 39 print(#function, self.elevationString) 40 } 41 } else { 42 self.afterElevation = 0.0 43 44 } 45 } 46 task.resume() 47 } 48 return elevationString 49} 50 51func measuringElevation() { 52 if afterElevation > beforeElevation { 53 gotElevation += afterElevation - beforeElevation 54 } 55} 56
ElevationData
1import Foundation 2 3struct ElevationData: Codable{ 4 let elevation: Double 5}
試したこと
非同期通信などを調べてみてものの、解決に至らなかったのでどうかよろしくおねがいします
回答1件
あなたの回答
tips
プレビュー