使用Swift4,iOS11.1,Xcode9.1,
Using Swift4, iOS11.1, Xcode9.1,
以下parseData方法几乎可以正常工作。一切似乎都可以正常工作(此URLSession和JSONDecode可以获取正确的JSON数据集)。
The following parseData method almost works. Everything seems to work fine (and a correct JSON-data set is fetched by this URLSession and JSONDecode).
但是,真正令我惊讶的是正常的浏览器显示不同的JSON数据(即,与该iOS-URLSession方法相比,获取的数据是其20倍)。为什么???
However, what is really surprising to me is the fact that a normal Browser shows different JSON-data (i.e. 20x as much is fetched than compared to this iOS-URLSession approach). Why is that ??
在下面的代码中,您可以找到两个打印语句。第一个显示实际的URLRequest字符串(包括所有查询和类型参数)。第二个打印出获取的JSON数据集的数量。
In the code below, you can find two print statements. The first showing the actual URLRequest-string (including all query- and type-parameters). The second prints the number of fetched JSON data-sets.
如果您使用浏览器并使用完全相同的URLRequest-string获取JSON,则数据集的数量为20套。有了URLSession,它只有1套
If you use a Browser and fetch the JSON with the exact same URLRequest-string, then the number of datasets is 20 sets. With the URLSession it is only 1 set
为什么传递的JSON数据长度存在这种差异??????????
Why this difference in JSON data-length delivered ??????????
这里是PRINT_LOG 1:
Here is PRINT_LOG 1 :
maps.googleapis/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:
Here is PRINT_LOG 2 :
count = 1这是我的代码:
func parseData(queryString: String) { // nested function func createURLWithComponents() -> URL? { let urlComponents = NSURLComponents() urlComponents.scheme = "https"; urlComponents.host = "maps.googleapis"; 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() }为完整起见,以下是匹配的结构:
For completeness, here is the matching 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 } }感谢f或对此有任何帮助。
Thanks for any help on this.
推荐答案找到了!!!
这是缺少的Info.plist本地化! (即,我在运行->选项->应用语言下运行了将语言设置为德语的应用程序表单XCode)。我的Info.plist只是部分本地化(即,我的文件 InfoPlist.strings 仅有几个条目,但没有完整的翻译)。而缺少的翻译会导致此问题!!!!
It was the missing Info.plist localization ! (i.e. I ran the App form XCode having the Language set to German under Run-->Options-->Appliation Language). My Info.plist was only partly localized (i.e. My file InfoPlist.strings had only a few entries yet - but not a complete translation). And this missing translation lead to this problem !!!!
以纯英语运行它可以正常工作,并且我得到了20条预期的条目。
Running it in pure English works fine and I get 20 entries as expected.
更多推荐
Swift4中使用URLSession和JSONDecode丢失数据
发布评论