Mit Swift4, iOS11.1, Xcode9.1,Fehlende Daten mit URLSession und JSONDecode in Swift4
Die folgende parseData Methode funktioniert fast. Alles scheint gut zu funktionieren (und ein korrekter JSON-Datensatz wird von dieser URLSession und JSONDecode abgerufen).
Was mich jedoch wirklich überrascht, ist die Tatsache, dass ein normaler Browser verschiedene JSON-Daten anzeigt (d. H. 20x wird so viel abgerufen wie im Vergleich zu dieser iOS-URLSession-Methode). Warum das ??
Im folgenden Code finden Sie zwei Druckanweisungen. Die erste zeigt die URLRequest-Zeichenfolge (einschließlich aller Abfrage- und Typparameter). Die zweite gibt die Anzahl der abgerufenen JSON-Datensätze aus.
Wenn Sie einen Browser verwenden und den JSON mit genau der gleichen URLRequest-Zeichenfolge abrufen, beträgt die Anzahl der Datensätze 20 Sätze. Mit der URLSession ist es nur 1 Satz
Warum dieser Unterschied in JSON Datenlänge geliefert ?????????? Hier
ist 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).
Hier ist PRINT_LOG 2:
count = 1
Hier ist mein Code:
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()
}
Der Vollständigkeit halber ist hier die passende Struct:
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
}
}
Danke für jede Hilfe zu diesem Thema.
Ich bekomme 'count = 20' mit Ihrem Code. Möglicherweise müssen Sie herausfinden, was anders ist, wenn Sie "count = 1" erhalten, nicht nur aus Ihrem Code. – OOPer
Genau dieser Unterschied ist meine Frage :)? Keine Ahnung, ich lande mit count = 1 !! Was ist Ihr Info.plist sagen über Zugriffsrechte (i.e.mine sagt: \t ' \t \t NSAllowsArbitraryLoads \t \t \t \t NSExceptionDomains \t \t maps.googleapis. com NSExceptionRequiresForwardSecrecy \t \t \t 'Was sonst könnte dieses Problem verursachen? Einige Spracheinstellungen (d. H. Lokalisierung)? Oder was noch? Jede Hilfe wird geschätzt! –
iKK