我的“JSON”对象有一个链接,它捕获用户在搜索栏中键入的内容以完成链接,然后开始url过程。在JSON完成解析之后,第一个链接使用另一个链接进行响应。在我的if let validLink = result.link中,您可以看到我将链接信息存储到一个数组中。现在,我不确定是否应该在if let validLink = result中开始另一个JSON响应,或者是否应该像在下面的代码中那样创建一个新函数,然后基本上复制并粘贴下面相同的JSON信息来重新解析它。第二个链接出现解析错误。最有效、最正确的方法是什么?我真的被困在这里了。
我尝试创建另一个函数,该函数使用第一次JSON解析中的信息,使用新链接再次重新解析。
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchBar.resignFirstResponder()
if let searchText = searchController.searchBar.text, !searchText.isEmpty {
let url = URL(string: "http://djp-dev/api/item?q=\(String(describing: searchText))&dev=1")
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
guard let data = data,
error == nil else {
print(error?.localizedDescription ?? "Response Error")
return }
do {
let jsonResult = try JSONDecoder().decode(Response.self, from: data)
let resultsArray = jsonResult.results
for result in resultsArray {
if let validLink = result.link {
print(validLink)
self.collectLink.append(validLink)
self.mainParse()
}
}
} catch {
print("Parse Error")
}
}
task.resume()
}
}
func mainParse() {
let url = URL(string: "http://djp-dev\(collectLink[0])?dev=1")
print(url!)
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
guard let data = data,
error == nil else {
//print(error?.localizedDescription ?? "Response Error")
return }
do {
let jsonResult = try JSONDecoder().decode(JSONResponse.self, from: data)
let mainArray = jsonResult.locations
for main in mainArray {
print("""
Manufacture = \(main.rid)
Description = \(main.description)
""")
/*if let validLink = result.description! {
}*/
}
} catch {
print("Parse Error")
}
}
task.resume()
DispatchQueue.main.async {
self.tableView.reloadData()
}
}基本上,我要求http://djp-dev/api/item?q=\(String(describing: searchText))&dev=1在它返回给我的响应中提供一个链接。我希望使用它发送给我的链接来启动另一个JSON请求。我不确定是应该将所有这些都放在一个请求中,还是应该用一个全新的JSON请求创建一个全新的函数。if let validLink = result.link { }是我收到第二个链接信息的时候。
发布于 2019-08-23 08:52:22
所以我想通了。我使用的是不带CodingKeys的可解码。感谢Vadian为我指明了正确的方向。下面是我的例子:
struct Response : Decodable {
let results: [Results]
enum CodingKeys: String, CodingKey {
case results = "photos"
}
}
struct Results : Decodable {
let url : String?
enum CodingKeys: String, CodingKey {
case url = "url"
}
}发布于 2019-08-24 15:27:17
@vadian说的是,Codable自动使用变量名作为编码键。因此您可以简单地添加Decodable,如下所示:
struct Response: Decodable {
let results: [Results]
private enum CodingKeys: String, CodingKey {
case results = "photos"
}
}
struct Results: Decodable {
let url: String?
}如果将results的名称更改为photos,您可以这样做
struct Response: Decodable {
let photos: [Results]
}
struct Results: Decodable {
let url: String?
}相反,如果您需要对数据进行后处理,例如,将String转换为Date,则需要自己实现init(from decoder: Decoding) throws。我强烈推荐阅读Encoding and decoding custom types。
发布于 2019-08-29 01:15:40
如果您有一个示例json,可以使用许多免费的在线工具来创建具有可编码协议的自定义swift结构/类
https://app.quicktype.io就是一个这样的例子
https://stackoverflow.com/questions/57433089
复制相似问题