【问题标题】:unable to decode json with text in get request无法在获取请求中使用文本解码 json
【发布时间】:2018-07-23 12:41:53
【问题描述】:

我需要像这样创建 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
            }
        }
    }
}

}

【问题讨论】:

  • 请显示DeclarationInfo的定义。我得到ЧЕРАХ 的代码与您显示的完全相同,只是我使用了自己的DeclarationInfo 版本。
  • OOPer,使用 DeclarationInfo 更新。请看一下

标签: ios json swift decode


【解决方案1】:

永远不会在解码 JSON 时使用 try? 忽略错误。 Codable 错误具有令人难以置信的描述性,可以准确地告诉您出了什么问题。

始终使用do catch 块状

do {
    let declarationInfo = try jsonDecoder.decode(DeclarationInfo.self, from: data)
} catch { print error }

并打印 error 而不是无用的文字字符串。


该错误与西里尔文字无关。

one of your previous questions 的 cmets 中建议的 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: "没有与键 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
}

再次重申:不要忽略错误,它们会帮助您立即解决问题。

【讨论】:

  • 完全同意。 尤其是出现Codable 错误。几乎不可能在不查看错误的情况下找出 Codable 出错的地方,因为没有任何函数可以设置断点。
【解决方案2】:

更新

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)

你会打印出错误,你会知道为什么解码失败

【讨论】:

    猜你喜欢
    • 2020-08-09
    • 2014-06-22
    • 2017-09-20
    • 1970-01-01
    • 2017-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-08
    相关资源
    最近更新 更多