2016-07-15 12 views
0

私はGoogleのジオロケーターAPIを使用して自動的にいくつかのものをマッピングしています。リクエストでJSON文字列を返しますが、解析するのが難しいです。私はフレディとSwiftyJSONのようなものを試しましたが、私が望むフィールドを抽出することはできません。ここでSwift JSON Parsing - フィールドにアクセスできません/返りません

は、私のコードのサンプルです:ここで

func sendJsonRequest(ConnectionString: String, 
           HTTPMethod : HttpMethod = HttpMethod.Get, 
           JsonHeaders : [String : String] = [ : ], 
           JsonString: String = "") -> NSData? { 

    // create the request & response 
    let request = NSMutableURLRequest(URL: NSURL(string: ConnectionString)!, cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData, timeoutInterval: 5) 

    // create some JSON data and configure the request 
    let jsonString = JsonString; 
    request.HTTPBody = jsonString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true) 

    // handle both get and post 
    request.HTTPMethod = HTTPMethod.rawValue 

    // we'll always be sending json so this is fine 
    request.setValue("application/json", forHTTPHeaderField: "Content-Type") 

    // add the headers. If there aren't any then that's ok 
    for item in JsonHeaders { 
     request.addValue(item.1, forHTTPHeaderField: item.0) 
    } 
    print("Request:") 
    print(request) 

    let session = NSURLSession.sharedSession() 
    var data : NSData? 

    var urlTask = session.dataTaskWithRequest(request) { (Data, Response, Error) in 
     data = Data 
    } 
    urlTask.resume() 

    while (data == nil) { 

    } 

    return data 

} 

// return the coordinates of a given location 
func getCoordinates() -> Coordinates { 
    var result = Coordinates() 

    let ConnectionString = "https://maps.googleapis.com/maps/api/geocode/json?address=43201" 
    let jsondata = sendJsonRequest(ConnectionString) 

    let data = jsondata 

    let json = JSON(data!) 

    print(json) 


    return result 
} 

getCoordinates() 

は、私は別のJSONクライアントから取得していた出力の例です:

{ 
"results": [ 
    { 
     "address_components": [ 
      { 
       "long_name": "43201", 
       "short_name": "43201", 
       "types": [ 
        "postal_code" 
       ] 
      }, 
      { 
       "long_name": "Columbus", 
       "short_name": "Columbus", 
       "types": [ 
        "locality", 
        "political" 
       ] 
      }, 
      { 
       "long_name": "Franklin County", 
       "short_name": "Franklin County", 
       "types": [ 
        "administrative_area_level_2", 
        "political" 
       ] 
      }, 
      { 
       "long_name": "Ohio", 
       "short_name": "OH", 
       "types": [ 
        "administrative_area_level_1", 
        "political" 
       ] 
      }, 
      { 
       "long_name": "United States", 
       "short_name": "US", 
       "types": [ 
        "country", 
        "political" 
       ] 
      } 
     ], 
     "formatted_address": "Columbus, OH 43201, USA", 
     "geometry": { 
      "bounds": { 
       "northeast": { 
        "lat": 40.011147, 
        "lng": -82.9723898 
       }, 
       "southwest": { 
        "lat": 39.976962, 
        "lng": -83.0250691 
       } 
      }, 
      "location": { 
       "lat": 39.9929821, 
       "lng": -83.00122100000002 
      }, 
      "location_type": "APPROXIMATE", 
      "viewport": { 
       "northeast": { 
        "lat": 40.011147, 
        "lng": -82.9723898 
       }, 
       "southwest": { 
        "lat": 39.976962, 
        "lng": -83.0250691 
       } 
      } 
     }, 
     "place_id": "ChIJ9Rz24rWOOIgR3EEuL2Ge4oo", 
     "types": [ 
      "postal_code" 
     ] 
    } 
], 
"status": "OK" 
} 

私は、フィールドの結果を取得しようとしています.geometry.location。 Freddy JSON解析ライブラリを使用して結果フィールドを取得できましたが、ジオメトリフィールドにアクセスできませんでした。私が間違っているかどうかを誰かが見てみることができますか? SwiftyJSONはJSONを解析することさえできません。

答えて

2

dataTaskWithRequestの引数として渡されたクロージャは、ネットワーク条件を考慮して即座にまたは途中で呼び出すことができる非同期型の意味です。戻り値voidの間に元のsendJsonRequestメソッドでクロージャを渡す方が良いでしょう。 dataTaskWithResultクロージャが呼び出されると、応答でクロージャを呼び出すことができます。

コードの面では、それは次のようになります。

func sendJsonRequest(connectionString: String, 
           httpMethod : HttpMethod = HttpMethod.Get, 
           jsonHeaders : [String : String] = [ : ], 
           jsonString: String = "", 
           completion: (data: NSData?, error: NSError?) -> Void) { 
    … //Your code 
    var urlTask = session.dataTaskWithRequest(request) { (optionalData, optionalResponse, optionalError) in 
     NSOperationQueue.mainQueue().addOperation { 
      if let data = optionalData { 
      completion(data, nil) 
      } 
      else if let error = optionalError { 
      completion(nil, error) 
      } 
     } 
    } 
    urlTask.resume() 
} 

// return the coordinates of a given location 
func getCoordinates(withCompletion completion: (Coordinates) -> Void) { 

    let connectionString = "https://maps.googleapis.com/maps/api/geocode/json?address=43201" 
    sendJsonRequest(connectionString: connectionString) { 
     (optionalData, optionalError) in 
     if let data = optionalData { 
      let json = JSON(data) 
      print(json) 
      //Do your conversion to Coordinates here 
      let coordinates = //? 
      completion(coordinates) 
     } 
     // Handle errors, etc… 
    } 
} 

ワンノート、引数や変数は小文字にします。クラス名のみ大文字にする必要があります。

+0

チップをありがとう!残念ながら、これは私のjson構文解析の問題を解決するものではありませんが、コールバックでそのデータをUIに戻すことができることを知ってうれしいです。 –

+0

@FKunecke、私は解析を修正して答えを更新しました。あなたのメソッドは、遊び場ではよりよく見えるかもしれませんが、実生活では、あなたの実装は、アプリケーションのUIがフリーズする原因となるメインスレッドをブロックします。 –

0

それはあなたがそれを簡単にするためにJSON.stringifyを使用することができ、可変

var results = { 
"results": [ 
    { 
     "address_components": [ 
      { 
       "long_name": "43201", 
       "short_name": "43201", 
       "types": [ 
        "postal_code" 
       ] 
      }, 
      { 
       "long_name": "Columbus", 
       "short_name": "Columbus", 
       "types": [ 
        "locality", 
        "political" 
       ] 
      }, 
      { 
       "long_name": "Franklin County", 
       "short_name": "Franklin County", 
       "types": [ 
        "administrative_area_level_2", 
        "political" 
       ] 
      }, 
      { 
       "long_name": "Ohio", 
       "short_name": "OH", 
       "types": [ 
        "administrative_area_level_1", 
        "political" 
       ] 
      }, 
      { 
       "long_name": "United States", 
       "short_name": "US", 
       "types": [ 
        "country", 
        "political" 
       ] 
      } 
     ], 
     "formatted_address": "Columbus, OH 43201, USA", 
     "geometry": { 
      "bounds": { 
       "northeast": { 
        "lat": 40.011147, 
        "lng": -82.9723898 
       }, 
       "southwest": { 
        "lat": 39.976962, 
        "lng": -83.0250691 
       } 
      }, 
      "location": { 
       "lat": 39.9929821, 
       "lng": -83.00122100000002 
      }, 
      "location_type": "APPROXIMATE", 
      "viewport": { 
       "northeast": { 
        "lat": 40.011147, 
        "lng": -82.9723898 
       }, 
       "southwest": { 
        "lat": 39.976962, 
        "lng": -83.0250691 
       } 
      } 
     }, 
     "place_id": "ChIJ9Rz24rWOOIgR3EEuL2Ge4oo", 
     "types": [ 
      "postal_code" 
     ] 
    } 
], 
"status": "OK" 
}; 



console.log(results); // you can see the object 
Object {results: Array[1], status: "OK"} 
console.log(results.results[0]); // Accessing the first object inside the array 
Object {address_components: Array[5], formatted_address: "Columbus, OH 43201, USA", geometry: Object, place_id: "ChIJ9Rz24rWOOIgR3EEuL2Ge4oo", types: Array[1]} 
console.log(results.results[0].geometry); // Accessing the geometry object. 
Object {bounds: Object, location: Object, location_type: "APPROXIMATE", viewport: Object} 

に結果を割り当て情報

をretriveするには、以下の操作を行うことができ、javascriptオブジェクトです。

-1

Freddy JSONライブラリで動作するように自分のコードを取得しました。誰も似たような問題に遭遇した場合のために、私の新しいコードはあります:

func getCoordinates(address: String) -> Coordinates { 
    var result = Coordinates() 

    let ConnectionString = _connectionUrl + address 
    let jsondata = sendJsonRequest(ConnectionString) 

    //print(json) 
    // returns a [string : AnyObject] 
    let data = jsondata 
    do { 
     let json = try JSON(data: data!) 
     let results = try json.array("results")[0] 

     let geometry = try results.dictionary("geometry") 
     print(geometry) 
     let location = geometry["location"]! 

     print(location) 
     let lat = try location.double("lat") 
     let lng = try location.double("lng") 

     result.Latitude = lat 
     result.Longitude = lng 

    } catch { 
     let nsError = error as NSError 
     print(nsError.localizedDescription) 
    } 
} 
+0

'sendJsonRequest'をそのまま使うべきではありません。これはひどい実装です。もう一度見て、SushiGrass Jacobの答えに従ってください。 – OOPer

関連する問題