首页 > 解决方案 > 无法在获取请求中使用文本解码 json

问题描述

我需要像这样创建 GET 请求:

https://public-api.nazk.gov.ua/v1/declaration/?q=Чер

https://public-api.nazk.gov.ua/v1/declaration/?q=Володимирович

= 之后的最后一个字符是西里尔符号

我提出这样的请求:

 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

从服务器返回必要数据但返回的数据无法解码。
它适用于搜索条件中的整数,但不适用于西里尔文字(

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
            }
        }
    }
}

}

标签: iosjsonswiftdecode

解决方案


永远不要在解码 JSON时try?忽略错误。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))

它清楚地描述了在结构中,数组索引 11 处的项中的Item键没有值。position

解决方案是将这个特定的结构成员声明为可选

struct Item: Codable {
    let id, firstname, lastname, placeOfWork: String
    let position : String?
    let linkPDF: String
}

再一次:不要忽略错误,它们可以帮助您立即解决问题。


推荐阅读