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
}
}
ありがとうございました。
あなたのコードで 'count = 20'を取得します。コードからだけでなく、 'count = 1'を得るときに何が違うのかを知る必要があるかもしれません。 – OOPer
正確にこの違いは私の質問です:)?いいえ、私はカウント= 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