为啥 JsonDecoder 在尝试解析邮递员网址但处理其他网址时出现错误?

Posted

技术标签:

【中文标题】为啥 JsonDecoder 在尝试解析邮递员网址但处理其他网址时出现错误?【英文标题】:Why JsonDecoder Giving Error while trying to parse postman Url but working on other urls?为什么 JsonDecoder 在尝试解析邮递员网址但处理其他网址时出现错误? 【发布时间】:2020-02-27 05:37:10 【问题描述】:

两个 URL 都包含 Json 格式的字典。

import UIKit
import Foundation
struct Course  : Decodable

    let foo1: String?
    let foo2: String?
    let fullName : String?
    let numFound : Int?


class ViewController: UIViewController 
    override func viewDidLoad() 
        super.viewDidLoad()

       // let jsonUrl = "https://api.plos.org/search?q=title:DNA" //Working On this Url
        let jsonUrl = "https://postman-echo.com/get?foo1=bar1&foo2=bar2"//Not Working On this Url
        guard   let url = URL(string: jsonUrl) else  return

        URLSession.shared.dataTask(with: url) (data,response,err) in

            guard let data = data
                else return

            do
            

                 let course = try  JSONDecoder().decode([String: Course].self , from: data)
                 course.forEach  print("\($0.key): \($0.value)")
            
            catch let jerr
            
                print(jerr)
            
        .resume()

    

This Is the Error If I am Using Postman Url

【问题讨论】:

【参考方案1】:

将 Postman URL 粘贴到浏览器中并查看 JSON。

它不起作用,因为对于其他键,除了 Course 之外还有其他值,因此解码 [String:Course] 字典失败。

你必须为根对象添加一个伞形结构

struct Root : Decodable 
    let args : Course


struct Course : Decodable   
    let foo1: String?
    let foo2: String?
    let fullName : String?
    let numFound : Int?


class ViewController: UIViewController 
    override func viewDidLoad() 
        super.viewDidLoad()

       // let jsonUrl = "https://api.plos.org/search?q=title:DNA" //Working On this Url
        let jsonUrl = "https://postman-echo.com/get?foo1=bar1&foo2=bar2"//Not Working On this Url
        guard let url = URL(string: jsonUrl) else  return

        URLSession.shared.dataTask(with: url) (data,response,err) in

            guard let data = data else return

            do  
                 let result = try  JSONDecoder().decode(Root.self , from: data)
                 print(result.args.foo1, result.args.foo2)
             catch 
                print(error)
            
        .resume()

    

【讨论】:

我必须为 Json 中的每个字典创建一个结构吗? 是的,你必须这样做。

以上是关于为啥 JsonDecoder 在尝试解析邮递员网址但处理其他网址时出现错误?的主要内容,如果未能解决你的问题,请参考以下文章

JSONDecoder 不解析数据

JSONDecoder 找不到存在的密钥

为啥流明不能识别正在发送的字段

JSONDecoder 解析不连贯

为啥我的 SwiftUI JSONDecoder 会出现致命错误?

如何在 iOS 中解析没有 JSONdecoder 的 JSON 对象? [复制]