2017-04-19 55 views
2

我想要使用Google地圖API獲取兩個地點之間的駕駛/步行距離。我更新我的應用程序斯威夫特3,Objective-C和我現在就卡在這個代碼塊轉換成斯威夫特3.使用谷歌地圖API在Swift 3中尋找駕車/步行距離2

NSString *dist; 
NSString *strUrl = [NSString stringWithFormat:@"http://maps.googleapis.com/maps/api/directions/json?origin=%f,%f&destination=%f,%f&sensor=false&mode=%@", closestLocation.coordinate.latitude, closestLocation.coordinate.longitude, _currentUserLocation.coordinate.latitude, _currentUserLocation.coordinate.longitude, @"DRIVING"]; 
NSURL *url = [NSURL URLWithString:[strUrl stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLQueryAllowedCharacterSet]]; 
NSData *jsonData = [NSData dataWithContentsOfURL:url]; 
if(jsonData != nil) 
{ 
    NSError *error = nil; 
    id result = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error]; 
    NSMutableArray *arrDistance=[result objectForKey:@"routes"]; 
    if ([arrDistance count]==0) { 
     NSLog(@"N.A."); 
    } 
    else{ 
     NSMutableArray *arrLeg=[[arrDistance objectAtIndex:0]objectForKey:@"legs"]; 
     NSMutableDictionary *dictleg=[arrLeg objectAtIndex:0]; 

     dist = [NSString stringWithFormat:@"%@",[[dictleg objectForKey:@"distance"] objectForKey:@"text"]]; 
    } 
} 
else{ 
    NSLog(@"N.A."); 
} 

我使用的工具,如Swiftify嘗試,但不斷收到錯誤隨處可見。我現在所擁有的是:

var dist: String = "" 
var strUrl: String = "http://maps.googleapis.com/maps/api/directions/json?origin=\(closestLocation!.coordinate.latitude),\(closestLocation!.coordinate.longitude)&destination=\(currentUserLocation!.coordinate.latitude),\(currentUserLocation!.coordinate.longitude)&sensor=false&mode=\("DRIVING")" 
var url = URL(string: strUrl) 
var jsonData = Data(contentsOf: url!) 
    if (jsonData != nil) { 
     var error: Error? = nil 
     var result: Any? = try? JSONSerialization.jsonObject(with: jsonData, options: JSONSerialization.ReadingOptions.Element.mutableContainers) 
     var arrDistance: [Any]? = (result?["routes"] as? [Any]) 
     if arrDistance?.count == 0 { 
      print("N.A.") 
     } 
     else { 
      var arrLeg: [Any]? = ((arrDistance?[0] as? [Any])?["legs"] as? [Any]) 
      var dictleg: [AnyHashable: Any]? = (arrLeg?[0] as? [AnyHashable: Any]) 

      dist = "\(dictleg?["distance"]["text"])" 
     } 
    } 
    else { 
     print("N.A.") 
    } 

我的錯誤,現在有以下幾種:

的數據(contentsOf:URL)它告訴我「呼叫可以拋出,但沒有標明「試「和錯誤沒有被處理

而且它不會像我如何使用[任何]我arrDistance變量。

如果有人知道如何實現斯威夫特3此API調用,這將是非常有益的謝謝

+1

與問題無關,但您不應使用Data(contentsOf:url!)來下載數據。你應該使用URLSession'dataTask(with:URL)' –

回答

3

什麼編譯器說Data(contentsOf:)throws異常,所以你需要用do catch塊來處理它。現在按照評論中的建議,您需要使用dataTask(with:)而不是Data(contentsOf:)來下載數據。你也可以用你的代碼做完成塊,所以像下面那樣改變你的代碼。

func getDistance(completion: @escaping(String) -> Void) { 

    var dist = "" 
    let strUrl = "http://maps.googleapis.com/maps/api/directions/json?origin=\(closestLocation!.coordinate.latitude),\(closestLocation!.coordinate.longitude)&destination=\(currentUserLocation!.coordinate.latitude),\(currentUserLocation!.coordinate.longitude)&sensor=false&mode=\("DRIVING")" 
    let url = URL(string: strUrl)! 
    let task = URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in 
     guard let data = data, error == nil else { 
      print(error?.localizedDescription ?? "") 
      completion(dist) 
      return 
     } 
     if let result = (try? JSONSerialization.jsonObject(with: data, options: [])) as? [String:Any], 
      let routes = result["routes"] as? [[String:Any]], let route = routes.first, 
      let legs = route["legs"] as? [[String:Any]], let leg = legs.first, 
      let distance = leg["distance"] as? [String:Any], let distanceText = distance["text"] as? String { 

      dist = distanceText 
     } 
     completion(dist) 
    }) 
    task.resume() 
} 

現在只需撥打getDistance函數就可以這樣。

self.getDistance { (distance) in 
    //Update UI on main thread 
    DispatchQueue.main.async { 
     print(distance) 
     self.label.text = distance 
    } 
} 
+0

但是然後我遇到了問題,無法存儲該距離變量的值。我試圖把這個值放在我的一個視圖控制器的標籤上 – trludt

+0

@trludt你不是簡單地在'getDistance'的完成中設置標籤文本而不是'print'語句,就像'self.getDistance {(distance)in yourLabel.text =距離 }' –

+0

需要一段時間讓標籤顯示值。它在技術上是有效的,但我需要這些信息在視圖加載後立即顯示出來。 – trludt