Xcode - API 搜索大小大于 14 时失败
Xcode - API Failing When Search Size is Greater Than 14
从 iTunes API https://itunes.apple.com/search?term=\(search)&entity=software&limit=14
获取数据时,如果限制是更大的数字(例如 30、40、50 等),则获取失败。该限制由 URL 末尾的 limit=14
表示。 14 是返回的结果数。这可以更改为任何数字。
在 Postman 中拨打电话时,我可以将限制输入为任意数字,并且可以正常工作。另外,当XCtest中运行大数的api时,测试通过。似乎只有在应用程序中进行实时调用时才会失败。
错误出现在guard let 语句中。在下面的代码中,如果数字太大(例如 50),它会打印“获取数据失败”——表明存在 URL 问题。当使用较小的数字(例如 10)时,提取成功并且数据 returns 在我的 table 视图中。您还可以更改搜索词。目前我将其设置为“Apple”。
下面是 API 的代码:
import Foundation
import UIKit
struct Response: Codable {
var resultCount: Int
var results: [Result]
}
struct Result: Codable {
var screenshotUrls, ipadScreenshotUrls, appletvScreenshotUrls: [String]
var artworkUrl60, artworkUrl512, artworkUrl100, artistViewUrl: String
var supportedDevices, advisories: [String]
var isGameCenterEnabled: Bool
var features: [String]
var kind, minimumOsVersion, trackCensoredName, fileSizeBytes: String
var contentAdvisoryRating: String
var genreIds: [String]
var primaryGenreName, artistName, trackContentRating, trackName, releaseDate, sellerName, currentVersionReleaseDate, releaseNotes, version: String
var primaryGenreId: Int
var currency, description: String
var price: Double
var averageUserRating: Double
}
class API {
var storedData = Response(resultCount: Int.init(), results: [])
func loadData(search: String, completionHandler: @escaping (Response) -> Void) {
guard let url = URL(string:"https://itunes.apple.com/search?term=\(search)&entity=software&limit=40") else {
print("failed to fetch data")
return
}
let request = URLRequest(url: url)
URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
if let response = try? JSONDecoder().decode(Response.self, from: data) {
DispatchQueue.main.async {
self.storedData.resultCount = response.resultCount
self.storedData.results = response.results
completionHandler(self.storedData)
}
return
}
}
print("failed \(error?.localizedDescription ?? "unknown error")")
}
.resume()
}
func reloadTableData() {
DataManager.shared.viewController.tableView.reloadData()
}
}
关于为什么当 运行 应用程序时更大的数字导致 guard let 失败,但在我的测试或邮递员中没有失败,有什么想法吗?
编辑
下面是我调用函数的方式。我在 viewdidload 中调用它。它使用一个完成处理程序,所以它看起来像下面这样:
api.loadData(search: "ibm") { Results in
self.filteredResults = self.api.storedData.results //stores value in filtered results array
self.tableView.reloadData() //refreshes table view - table view is referencing the filteredResults array
}
JSON 中缺少很多键,当您设置的限制超过 20 个时:
- 在解码 JSON 时始终使用 doCatch 并打印
error
,它会告诉您出了什么问题,因为以下错误,您的源解码失败:
keyNotFound(CodingKeys(stringValue: "releaseNotes", intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "results", intValue: nil), _JSONKey(stringValue: "Index 15", intValue: 15)], debugDescription: "No value associated with key CodingKeys(stringValue: \"releaseNotes\", intValue: nil) (\"releaseNotes\").", underlyingError: nil))
- 尝试在结构
Optional
中创建所有变量以暂时解决解码问题。
使属性可选
struct Response: Codable {
var resultCount: Int?
var results: [Result]?
}
struct Result: Codable {
var screenshotUrls, ipadScreenshotUrls, appletvScreenshotUrls: [String]?
var artworkUrl60, artworkUrl512, artworkUrl100, artistViewUrl: String?
var supportedDevices, advisories: [String]?
var isGameCenterEnabled: Bool?
var features: [String]?
var kind, minimumOsVersion, trackCensoredName, fileSizeBytes: String?
var contentAdvisoryRating: String?
var genreIds: [String]?
var primaryGenreName, artistName, trackContentRating, trackName, releaseDate, sellerName, currentVersionReleaseDate, releaseNotes, version: String?
var primaryGenreId: Int?
var currency, description: String?
var price: Double?
var averageUserRating: Double?
}
将其放入 if-let
数据块中:
do {
let response = try JSONDecoder().decode(Response.self, from: data)
DispatchQueue.main.async {
self.storedData.resultCount = response.resultCount
self.storedData.results = response.results
completionHandler(self.storedData)
}
} catch let error {
print(error)
}
从 iTunes API https://itunes.apple.com/search?term=\(search)&entity=software&limit=14
获取数据时,如果限制是更大的数字(例如 30、40、50 等),则获取失败。该限制由 URL 末尾的 limit=14
表示。 14 是返回的结果数。这可以更改为任何数字。
在 Postman 中拨打电话时,我可以将限制输入为任意数字,并且可以正常工作。另外,当XCtest中运行大数的api时,测试通过。似乎只有在应用程序中进行实时调用时才会失败。
错误出现在guard let 语句中。在下面的代码中,如果数字太大(例如 50),它会打印“获取数据失败”——表明存在 URL 问题。当使用较小的数字(例如 10)时,提取成功并且数据 returns 在我的 table 视图中。您还可以更改搜索词。目前我将其设置为“Apple”。
下面是 API 的代码:
import Foundation
import UIKit
struct Response: Codable {
var resultCount: Int
var results: [Result]
}
struct Result: Codable {
var screenshotUrls, ipadScreenshotUrls, appletvScreenshotUrls: [String]
var artworkUrl60, artworkUrl512, artworkUrl100, artistViewUrl: String
var supportedDevices, advisories: [String]
var isGameCenterEnabled: Bool
var features: [String]
var kind, minimumOsVersion, trackCensoredName, fileSizeBytes: String
var contentAdvisoryRating: String
var genreIds: [String]
var primaryGenreName, artistName, trackContentRating, trackName, releaseDate, sellerName, currentVersionReleaseDate, releaseNotes, version: String
var primaryGenreId: Int
var currency, description: String
var price: Double
var averageUserRating: Double
}
class API {
var storedData = Response(resultCount: Int.init(), results: [])
func loadData(search: String, completionHandler: @escaping (Response) -> Void) {
guard let url = URL(string:"https://itunes.apple.com/search?term=\(search)&entity=software&limit=40") else {
print("failed to fetch data")
return
}
let request = URLRequest(url: url)
URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
if let response = try? JSONDecoder().decode(Response.self, from: data) {
DispatchQueue.main.async {
self.storedData.resultCount = response.resultCount
self.storedData.results = response.results
completionHandler(self.storedData)
}
return
}
}
print("failed \(error?.localizedDescription ?? "unknown error")")
}
.resume()
}
func reloadTableData() {
DataManager.shared.viewController.tableView.reloadData()
}
}
关于为什么当 运行 应用程序时更大的数字导致 guard let 失败,但在我的测试或邮递员中没有失败,有什么想法吗?
编辑
下面是我调用函数的方式。我在 viewdidload 中调用它。它使用一个完成处理程序,所以它看起来像下面这样:
api.loadData(search: "ibm") { Results in
self.filteredResults = self.api.storedData.results //stores value in filtered results array
self.tableView.reloadData() //refreshes table view - table view is referencing the filteredResults array
}
JSON 中缺少很多键,当您设置的限制超过 20 个时:
- 在解码 JSON 时始终使用 doCatch 并打印
error
,它会告诉您出了什么问题,因为以下错误,您的源解码失败:
keyNotFound(CodingKeys(stringValue: "releaseNotes", intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "results", intValue: nil), _JSONKey(stringValue: "Index 15", intValue: 15)], debugDescription: "No value associated with key CodingKeys(stringValue: \"releaseNotes\", intValue: nil) (\"releaseNotes\").", underlyingError: nil))
- 尝试在结构
Optional
中创建所有变量以暂时解决解码问题。
使属性可选
struct Response: Codable {
var resultCount: Int?
var results: [Result]?
}
struct Result: Codable {
var screenshotUrls, ipadScreenshotUrls, appletvScreenshotUrls: [String]?
var artworkUrl60, artworkUrl512, artworkUrl100, artistViewUrl: String?
var supportedDevices, advisories: [String]?
var isGameCenterEnabled: Bool?
var features: [String]?
var kind, minimumOsVersion, trackCensoredName, fileSizeBytes: String?
var contentAdvisoryRating: String?
var genreIds: [String]?
var primaryGenreName, artistName, trackContentRating, trackName, releaseDate, sellerName, currentVersionReleaseDate, releaseNotes, version: String?
var primaryGenreId: Int?
var currency, description: String?
var price: Double?
var averageUserRating: Double?
}
将其放入 if-let
数据块中:
do {
let response = try JSONDecoder().decode(Response.self, from: data)
DispatchQueue.main.async {
self.storedData.resultCount = response.resultCount
self.storedData.results = response.results
completionHandler(self.storedData)
}
} catch let error {
print(error)
}