2017-11-28 4 views
0

Swift4、iOS11.1、Xcode9.1、Swift4のURLSessionとJSONDecodeのデータがありません

を使用しています

次のparseDataメソッドはほとんど動作します。すべて正常に動作しているようです(このURLSessionとJSONDecodeによって正しいJSONデータセットが取得されます)。

しかし、実際のところ驚くべきことは、通常のブラウザでは異なるJSONデータ(このiOS-URLSessionアプローチに比べて20倍も多くのデータが取得される)が表示されているということです。何故ですか ??

以下のコードでは、2つのprint文を見つけることができます。最初は実際のURLRequest文字列(すべてのクエリと型パラメータを含む)を示しています。 2つ目は取得したJSONデータセットの数を出力します。

ブラウザを使用して、まったく同じURLRequest-stringを使用してJSONをフェッチすると、データセットの数は20セットになります。 URLSessionでは1セットしかありません

なぜこのJSONデータ長の違いは??????????ここで

はPRINT_LOG 1:ここでは

https://maps.googleapis.com/maps/api/place/textsearch/json?query=Cham,%20Langackerstrasse&type=bus_station&key=AIzaSyDYtkKiJRuJ9tjkeOtEAuEtTLp5a0XR1M0 

(API key no longer valid - after having found the solution, I did change the API-key for security reasons. The Question and its Answer are still of value tough). 

はPRINT_LOG 2:ここでは

count = 1 

は私のコードです:完全性については

func parseData(queryString: String) { 

    // nested function 
    func createURLWithComponents() -> URL? { 
     let urlComponents = NSURLComponents() 
     urlComponents.scheme = "https"; 
     urlComponents.host = "maps.googleapis.com"; 
     urlComponents.path = "/maps/api/place/textsearch/json"; 
     // add params 
     urlComponents.queryItems = [ 
      URLQueryItem(name: "query", value: "Cham, Langackerstrasse"), 
      URLQueryItem(name: "type", value: "bus_station"), 
      URLQueryItem(name: "key", value: AppConstants.GOOGLE_MAPS_DIRECTIONS_API_KEY) 
     ] 

     return urlComponents.url 
    } 

    let myUrl = createURLWithComponents() 
    var myRequest = URLRequest(url: myUrl!) 
    myRequest.httpMethod = "GET" 
    myRequest.setValue("application/json; charset=UTF-8", forHTTPHeaderField: "Content-Type") 

    let myConfiguration = URLSessionConfiguration.default 
    let session = URLSession(configuration: myConfiguration, delegate: nil, delegateQueue: OperationQueue.main) 

    // Until here everything all right !!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
    // i.e. the following print is correct !!!!!!!!!!!!!!!!!!!!!!!!! 
    // (and when this print is copied to a Browser then the data fetched has 20 JSON-entries...) 
    // PRINT_LOG 1 
    print(myRequest.description) 

    let myTask = session.dataTask(with: myRequest) { (data, response, error) in 

     if (error != nil) { 
      print("Error1 fetching JSON data") 
     } 
     else { 
      do { 
       //Decode retrived data with JSONDecoder and assing type of Station object 
       let stationData = try JSONDecoder().decode(Station.self, from: data!) 

       // Here is the puzzling thing to happen !!!!!!!!!!!!!!!!!!!!!! 
       // i.e. the following print reveals count = 1 !!!!!!!!!!!!!!!!! 
       // ??? Why not 20 as with the Browser ???????????????????? 
       // PRINT_LOG 2 
       print("count = " + "\(String(describing: stationData.results.count))") 
      } 
      catch let error { 
       print(error) 
      } 
     } 
    } 
    myTask.resume() 
} 

、ここでは一致した構造体は次のとおりです。

struct Station: Codable { 

    let htmlAttributions: [String] 
    let nextPageToken: String? 
    let results: [Result] 
    let status: String 

    struct Result: Codable { 
     let formattedAddress: String 
     let geometry: Geometry 
     let icon: String 
     let id: String 
     let name: String 
     let photos: [Photo]? 
     let placeID: String 
     let rating: Double? 
     let reference: String 
     let types: [String] 

     struct Geometry: Codable { 
      let location: Coordinates 
      let viewport: Viewport 

      struct Coordinates: Codable { 
       let lat: Double 
       let lng: Double 
       init(from decoder: Decoder) throws { 
        let values = try decoder.container(keyedBy: CodingKeys.self) 
        lat = try values.decode(Double.self, forKey: .lat) 
        lng = try values.decode(Double.self, forKey: .lng) 
       } 
       enum CodingKeys : String, CodingKey { 
        case lat 
        case lng 
       } 
      } 

      struct Viewport: Codable { 
       let northeast: Coordinates 
       let southwest: Coordinates 

       enum CodingKeys : String, CodingKey { 
        case northeast 
        case southwest 
       } 
      } 

      enum CodingKeys : String, CodingKey { 
       case location 
       case viewport 
      } 
     } 

     struct Photo: Codable { 

      let height: Int 
      let htmlAttributions: [String] 
      let photoReference: String? 
      let width: Int 
      enum CodingKeys : String, CodingKey { 
       case height 
       case htmlAttributions = "html_attributions" 
       case photoReference = "photo_reference" 
       case width 
      } 
     } 

     enum CodingKeys : String, CodingKey { 
      case formattedAddress = "formatted_address" 
      case geometry 
      case icon 
      case id 
      case name 
      case photos 
      case placeID = "place_id" 
      case rating 
      case reference 
      case types 
     } 
    } 

    enum CodingKeys : String, CodingKey { 
     case htmlAttributions = "html_attributions" 
     case nextPageToken = "next_page_token" 
     case results 
     case status 
    } 
} 

ありがとうございました。

+0

あなたのコードで 'count = 20'を取得します。コードからだけでなく、 'count = 1'を得るときに何が違うのかを知る必要があるかもしれません。 – OOPer

+0

正確にこの違いは私の質問です:)?いいえ、私はカウント= 1で終わります!あなたのInfo.plistは、アクセス権について何を言っている(i.e.mineは言う:\t ' \t \t NSAllowsArbitraryLoads \t \t \t \t NSExceptionDomains \t \t maps.googleapisを。この問題を引き起こす可能性があります他に何COM NSExceptionRequiresForwardSecrecy \t \t \t '?一部の言語設定(ローカリゼーション)それともほかに何か?どんな助けにも感謝! – iKK

答えて

0

見つけた!

Info.plistがローカライズされていませんでした。 (つまり、実行 - >オプション - >適用言語の下で、言語をドイツ語に設定したAppフォームXCodeを実行しました)。私のInfo.plistは部分的にしかローカライズされていませんでした(つまり、私のファイルInfoPlist.stringsには少数のエントリしかありませんでしたが、完全な翻訳はできません)。そしてこの欠けている翻訳はこの問題につながります!!!!

純粋な英語で実行するとうまく動作し、予想どおり20個のエントリが得られます。

関連する問題