2017-01-18 25 views
2

私は緯度と経度を取得するためにgoogle places APIを使用していますが、辞書を解析することはできません。非機能型の値を呼び出すことはできません「どれを?!」:私はスウィフトの解析辞書3.0

let lat = ((((dic["results"] as! AnyObject).value(forKey: "geometry") as AnyObject).value(forKey: "location") as AnyObject).value(forKey: "lat") as AnyObject).object(0) as! Double 

エラー、次のコードを使用しています

AnyObjectではなくnsdictionaryでチェックしましたが、うまくいきませんでした。 上記のコードから正しくlatを得る方法を知っている人はいますか?

Responce:

{ 
results =  (
      { 
     "address_components" =    (
          { 
       "long_name" = Palermo; 
       "short_name" = Palermo; 
       types =      (
        locality, 
        political 
       ); 
      }, 
          { 
       "long_name" = "Province of Palermo"; 
       "short_name" = PA; 
       types =      (
        "administrative_area_level_2", 
        political 
       ); 
      }, 
          { 
       "long_name" = Sicily; 
       "short_name" = Sicily; 
       types =      (
        "administrative_area_level_1", 
        political 
       ); 
      }, 
          { 
       "long_name" = Italy; 
       "short_name" = IT; 
       types =      (
        country, 
        political 
       ); 
      } 
     ); 
     "formatted_address" = "Palermo, Italy"; 
     geometry =    { 
      bounds =     { 
       northeast =      { 
        lat = "38.219548"; 
        lng = "13.4471566"; 
       }; 
       southwest =      { 
        lat = "38.0615392"; 
        lng = "13.2674205"; 
       }; 
      }; 
      location =     { 
       lat = "38.1156879"; 
       lng = "13.3612671"; 
      }; 
      "location_type" = APPROXIMATE; 
      viewport =     { 
       northeast =      { 
        lat = "38.2194316"; 
        lng = "13.4471566"; 
       }; 
       southwest =      { 
        lat = "38.0615392"; 
        lng = "13.2674205"; 
       }; 
      }; 
     }; 
     "place_id" = ChIJmdBOgcnoGRMRgNg7IywECwo; 
     types =    (
      locality, 
      political 
     ); 
    } 
); 
status = OK; 

}

+0

GoogleプレイスAPI –

+0

からの返答を表示することはできますか?[ObjectMapper](https://github.com/Hearst-DD/ObjectMapper)を使用する場合はどうすればよいですか? –

答えて

4

で明確にするため、私が使用することをお勧めしますタイプの別名:

typealias JSONDictionary = [String:Any] 

let results = dic["results"] as? [JSONDictionary] { 
     for result in results { 
     if let geometry = result["geometry"] as? JSONDictionary, 
      let location = geometry["location"] as? JSONDictionary { 
       if let lat = location["lat"] as? Double, 
       let lng = location["lng"] as? Double { 
        print(lat, lng) 
       } 
     } 
    } 
    } 

Sでいくつかのルールwift:あなたは絶対に選択肢がない場合を除き

  • は全くNSDictionary/NSArrayを使用しないでください。
  • Swift 3のJSON辞書は[String:Any]、JSON配列[[String:Any]]です。
  • キャストAnyは可能な限り具体的にタイプダウンします。
  • リモートサーバーからJSONを解析する際には、常にオプションのバインディングを使用してランタイムエラーを回避します。
+0

素敵な説明。 –

0
let geometry = = item["geometry"] as NSArray 
let location = geometry["location"] as Dictionary 

let latitude = location["lat"] as Double 
let longitude = location["long"] as Double 

はこれを試してみてください、その頭からは、私は100%それを正しく覚えていないが、あなたは、ジオメトリ列の内側に、そこにされている場所の内側に位置辞書を持っています緯度/経度パラメータ。

4

クリスチャンの答えは、いくつかの重要な構文とオプションの型キャストを無視していますが、やや正しいです。あなたは、実際のAPIコールを作っているどこかのコードでと仮定:

class SomeClass { 
    func getLocationData() { 
     //do your api call stuff here and get "result" 
     let location: Location? = Location(json: result as? [String:Any]) 
    } 
} 

あなたはおそらく構造体で、何らかの方法で応答を処理することができます

struct Location { 
    var lat: Double 
    var long: Double 

    init(lat: Double, long: Double) { 
     self.lat = lat 
     self.long = long 
    } 

    init?(json: [String:Any]?) { 
     guard let results = json?["results"] as? [Any], 
      let first = results[0] as? [String:Any], 
      let geometry = first["geometry"] as? [String:Any], 
      let location = geometry["location"] as? [String:Any], 
      let latitude = location["lat"] as? Double, 
      let longitude = location["lng"] as? Double else { 
      return nil 
     } 
     self.lat = latitude 
     self.long = longitude 
    } 
} 

構造体の初期化子のポイントは、条件を使用していますtypeをアンラップしてJSONレスポンスオブジェクトのそれぞれのメンバーを適切な型にキャストします。

これは、APIから受け取った実際のJSONオブジェクトに基づいて大きく異なる可能性があることに注意してください。あなたが既に解析しようとしているSwiftコードに加えて、生のテキストで実際のJSONレスポンスを投稿することができれば役に立ちます。私の回答はあなたが提供した情報に基づいて最善を尽くします。 APIレスポンスから未処理のJSONオブジェクトを提供するということは、おそらくもっと高い信頼度をもって書くことができます。

編集:後、あなたが複数のステップでJSONを解析する必要がGoogleプレイスAPIから結果を取得し、解析し、遊び場スニペット

import PlaygroundSupport 
import Foundation 

PlaygroundPage.current.needsIndefiniteExecution = true 

struct Location { 
    var lat: Double 
    var long: Double 

    init(lat: Double, long: Double) { 
     self.lat = lat 
     self.long = long 
    } 

    init?(json: [String:Any]?) { 
     guard let results = json?["results"] as? [Any], 
      let first = results[0] as? [String:Any], 
      let geometry = first["geometry"] as? [String:Any], 
      let location = geometry["location"] as? [String:Any], 
      let latitude = location["lat"] as? Double, 
      let longitude = location["lng"] as? Double else { 
      return nil 
     } 
     self.lat = latitude 
     self.long = longitude 
    } 
} 

func getLocationData() { 
    let base = "https://maps.googleapis.com/maps/api/geocode/json" 
    let args = [ 
     "address=%50%61%6C%65%72%6D%6F%2C%20%50%72%6F%76%69%6E%63%65%20%6F%66%20%50%61%6C%65%72%6D%6F%2C%20%49%74%61%6C%79", 
     "sensor=false", 
    ] 

    let urlStr = "\(base)?\(args.joined(separator: "&"))" 
    guard let url = URL(string: urlStr) else { return } 
    var request = URLRequest(url: url) 
    request.httpMethod = "GET" 

    URLSession.shared.dataTask(with: request, 
     completionHandler: { (data, response, error) -> Void in 
      guard let jsonData = data else { return } 
      if let jsonResult = try? JSONSerialization.jsonObject(with: jsonData, options: .mutableContainers) as? [String:Any] { 
       let location: Location? = Location(json: jsonResult) 
       print("Location: \(location?.lat), \(location?.long)") 
      } 
     } 
    ).resume() 
} 

getLocationData() 
+0

私は私が何をしなければならないと思います。使用しているAPIのURLを教えてください。 JSONレスポンスの「Swifty」ログ版を読むのは難しいです。 @ user2702179 –

+0

https://maps.googleapis.com/maps/api/geocode/json?address=%50%61%6C%65%72%6D%6F%2C%20%50%72%6F%76% 69%6E%63%65%20%6F%66%20%50%61%6C%65%72%6D%6F%2C%20%49%74%61%6C%79&sensor = false – user2702179

+0

@ user2702179ご覧ください動作しているプレイグラウンドスニペットとJSON結果を正常に解析できるLocation構造体を修正した私の応答 –

関連する問題