无法使用 get 请求中的文本解码 json
unable to decode json with text in get request
我需要像这样创建 GET 请求:
https://public-api.nazk.gov.ua/v1/declaration/?q=Чер
https://public-api.nazk.gov.ua/v1/declaration/?q=Володимирович
= 之后的最后一个字符是西里尔符号
我的 get 请求是这样的:
var hostURL = "https://public-api.nazk.gov.ua/v1/declaration/?q="
hostURL = hostURL + searchConditions
let escapedSearchConditions = hostURL.addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed)
let url = URL(string: escapedSearchConditions!)!
请求是:
https://public-api.nazk.gov.ua/v1/declaration/?q=%D0%9F%D1%80%D0%BE
来自服务器的 return 必要数据,但无法解码 returned 数据。
它适用于搜索条件中的整数但不适用于西里尔文本(
import Foundation
struct Declarant: Codable {
var id: String
var firstname: String
var lastname: String
var placeOfWork: String
var position: String
var linkPDF: String
}
struct DeclarationInfo: Codable {
let items: [Declarant]
}
导入基金会
struct DeclarationInfoController {
func fetchDeclarationInfo (with searchConditions: String, completion: @escaping(DeclarationInfo?) -> Void) {
var hostURL = "https://public-api.nazk.gov.ua/v1/declaration/?q="
hostURL = hostURL + searchConditions
let escapedSearchConditions = hostURL.addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed)
let url = URL(string: escapedSearchConditions!)!
print(url)
let dataTask = URLSession.shared.dataTask(with: url) {
(data, response, error) in
let jsonDecoder = JSONDecoder()
print("Trying to decode data...")
if let data = data,
let declarationInfo = try? jsonDecoder.decode(DeclarationInfo.self, from: data) {
completion(declarationInfo)
print(declarationInfo)
} else {
print("Either no data was returned, or data was not properly decoded.")
completion(nil)
}
}
dataTask.resume()
}
}
import UIKit
class DeclarationViewController: UIViewController {
let declarationInfoController = DeclarationInfoController()
@IBOutlet weak var searchBar: UISearchBar!
@IBOutlet weak var resultLabel: UILabel!
@IBAction func beginSearchButton(_ sender: UIButton) {
declarationInfoController.fetchDeclarationInfo(with: searchBar.text!) { (declarationInfo) in
if let declarationInfo = declarationInfo {
DispatchQueue.main.async {
self.resultLabel.text = declarationInfo.items[0].lastname
}
}
}
}
}
更新
if let data = data,
let declarationInfo = try? jsonDecoder.decode(DeclarationInfo.self, from: data) {
completion(declarationInfo)
print(declarationInfo)
} else {
print("Either no data was returned, or data was not properly decoded.")
completion(nil)
}
来自
do {
if let data = data {
let declarationInfo = try jsonDecoder.decode(DeclarationInfo.self, from: data)
completion(declarationInfo)
print(declarationInfo)
return
} catch {
print(error)
}
completion(nil)
你会打印出错误,你会知道解码失败的原因吗
从不使用try?
解码JSON时忽略错误。 Codable
错误具有令人难以置信的描述性,可以准确地告诉您哪里出了问题。
使用总是一个do catch
块像
do {
let declarationInfo = try jsonDecoder.decode(DeclarationInfo.self, from: data)
} catch { print error }
并打印 error
而不是无用的文字字符串。
该错误与西里尔文字无关。
评论中建议的 JSON 结构
struct Item: Codable {
let id, firstname, lastname, placeOfWork: String
let position, linkPDF: String
}
揭示了错误(强调了最重要的部分)
keyNotFound(CodingKeys(stringValue: "position", intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "items", intValue: nil), _JSONKey(stringValue: "Index 11", intValue: 11)], debugDescription: "No value associated with key CodingKeys(stringValue: \"position\", intValue: nil) (\"position\").", underlyingError: nil))
它清楚地描述了在结构 Item
中,数组索引 11 处的项中的键 position
没有值。
解决方案是将这个特定的结构成员声明为可选
struct Item: Codable {
let id, firstname, lastname, placeOfWork: String
let position : String?
let linkPDF: String
}
再次强调:不要忽略错误,它们会帮助您立即解决问题。
我需要像这样创建 GET 请求:
https://public-api.nazk.gov.ua/v1/declaration/?q=Чер
https://public-api.nazk.gov.ua/v1/declaration/?q=Володимирович
= 之后的最后一个字符是西里尔符号
我的 get 请求是这样的:
var hostURL = "https://public-api.nazk.gov.ua/v1/declaration/?q="
hostURL = hostURL + searchConditions
let escapedSearchConditions = hostURL.addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed)
let url = URL(string: escapedSearchConditions!)!
请求是: https://public-api.nazk.gov.ua/v1/declaration/?q=%D0%9F%D1%80%D0%BE
来自服务器的 return 必要数据,但无法解码 returned 数据。
它适用于搜索条件中的整数但不适用于西里尔文本(
import Foundation
struct Declarant: Codable {
var id: String
var firstname: String
var lastname: String
var placeOfWork: String
var position: String
var linkPDF: String
}
struct DeclarationInfo: Codable {
let items: [Declarant]
}
导入基金会
struct DeclarationInfoController {
func fetchDeclarationInfo (with searchConditions: String, completion: @escaping(DeclarationInfo?) -> Void) {
var hostURL = "https://public-api.nazk.gov.ua/v1/declaration/?q="
hostURL = hostURL + searchConditions
let escapedSearchConditions = hostURL.addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed)
let url = URL(string: escapedSearchConditions!)!
print(url)
let dataTask = URLSession.shared.dataTask(with: url) {
(data, response, error) in
let jsonDecoder = JSONDecoder()
print("Trying to decode data...")
if let data = data,
let declarationInfo = try? jsonDecoder.decode(DeclarationInfo.self, from: data) {
completion(declarationInfo)
print(declarationInfo)
} else {
print("Either no data was returned, or data was not properly decoded.")
completion(nil)
}
}
dataTask.resume()
}
}
import UIKit
class DeclarationViewController: UIViewController {
let declarationInfoController = DeclarationInfoController()
@IBOutlet weak var searchBar: UISearchBar!
@IBOutlet weak var resultLabel: UILabel!
@IBAction func beginSearchButton(_ sender: UIButton) {
declarationInfoController.fetchDeclarationInfo(with: searchBar.text!) { (declarationInfo) in
if let declarationInfo = declarationInfo {
DispatchQueue.main.async {
self.resultLabel.text = declarationInfo.items[0].lastname
}
}
}
}
}
更新
if let data = data,
let declarationInfo = try? jsonDecoder.decode(DeclarationInfo.self, from: data) {
completion(declarationInfo)
print(declarationInfo)
} else {
print("Either no data was returned, or data was not properly decoded.")
completion(nil)
}
来自
do {
if let data = data {
let declarationInfo = try jsonDecoder.decode(DeclarationInfo.self, from: data)
completion(declarationInfo)
print(declarationInfo)
return
} catch {
print(error)
}
completion(nil)
你会打印出错误,你会知道解码失败的原因吗
从不使用try?
解码JSON时忽略错误。 Codable
错误具有令人难以置信的描述性,可以准确地告诉您哪里出了问题。
使用总是一个do catch
块像
do {
let declarationInfo = try jsonDecoder.decode(DeclarationInfo.self, from: data)
} catch { print error }
并打印 error
而不是无用的文字字符串。
该错误与西里尔文字无关。
struct Item: Codable {
let id, firstname, lastname, placeOfWork: String
let position, linkPDF: String
}
揭示了错误(强调了最重要的部分)
keyNotFound(CodingKeys(stringValue: "position", intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "items", intValue: nil), _JSONKey(stringValue: "Index 11", intValue: 11)], debugDescription: "No value associated with key CodingKeys(stringValue: \"position\", intValue: nil) (\"position\").", underlyingError: nil))
它清楚地描述了在结构 Item
中,数组索引 11 处的项中的键 position
没有值。
解决方案是将这个特定的结构成员声明为可选
struct Item: Codable {
let id, firstname, lastname, placeOfWork: String
let position : String?
let linkPDF: String
}
再次强调:不要忽略错误,它们会帮助您立即解决问题。