期望解码String但是找到了字典

时间:2018-04-16 08:41:02

标签: json swift

每次出错时我都无法从灯具数组中解析数据

控制台日志中出现

错误:

  

下载
  错误信息:typeMismatch(Swift.String,Swift.DecodingError.Context(codingPath:[LiveZscores.EventsFull。(CodingKeys in _B768B663C3B4834FEE8438F5C59CA80A).fixtures,Foundation。(_ JSONKey in _12768CA107A31EF2DCE034FD75B541C9)(stringValue:" Index 0", intValue:可选(0)),LiveZscores.EventsData。(CodingKeys in _B768B663C3B4834FEE8438F5C59CA80A).result],debugDescription:"期望解码String而不是找到字典。",underlyingError:nil))

我的代码:

ViewController.swift

final let url = URL(string: "http://api.football-data.org/v1/fixtures")

override func viewDidLoad() {
    super.viewDidLoad()

    downloadJson()

}

func downloadJson() {
    guard let downloadURL = url else { return }

    URLSession.shared.dataTask(with: downloadURL) { (data, urlResponse, error) in
        guard let data = data, error == nil, urlResponse != nil else {
            print ("something")
            return
        }
        print ("downloaded")
        do {
            let decoder = JSONDecoder()
            let events = try decoder.decode(EventsFull.self, from: data)
            print (events.fixtures)

        }catch {
            print("Error info: \(error)")
        }


    }.resume()

}

Events.swift

class EventsFull: Codable {
    let fixtures: [EventsData]

    init(fixtures: [EventsData]) {
        self.fixtures = fixtures
    }
}

class EventsData: Codable {

    let date: String
    let status: String
    let matchday: Int
    let homeTeamName: String
    let awayTeamName: String
    let result: String
    let odds: Double

    init(date: String, status: String, matchday: Int, homeTeamName: String, awayTeamName: String, result: String, odds: Double) {

        self.date = date
        self.status = status
        self.matchday = matchday
        self.homeTeamName = homeTeamName
        self.awayTeamName = awayTeamName
        self.result = result
        self.odds = odds
    }

}

1 个答案:

答案 0 :(得分:3)

请学习阅读错误消息,尤其是Codable消息非常容易阅读。

这是更有条理的消息

typeMismatch(Swift.String, 
         Swift.DecodingError.Context(codingPath: [LiveZscores.EventsFull.(CodingKeys in _B768B663C3B4834FEE8438F5C59CA80A).fixtures, Foundation.(_JSONKey in _12768CA107A31EF2DCE034FD75B541C9)(stringValue: "Index 0", intValue: Optional(0)), 
                                                  LiveZscores.EventsData.(CodingKeys in _B768B663C3B4834FEE8438F5C59CA80A).result], debugDescription: "Expected to decode String but found a dictionary instead.", underlyingError: nil))

Swift.String是struct / class

中的预期类型

最重要的codingPath信息是

codingPath: [LiveZscores.EventsFull.fixtures, 
             LiveZscores.EventsData.result], debugDescription: "Expected to decode String but found a dictionary instead.", underlyingError: nil))

结构result中的密钥EventsData中出现错误,该密钥位于EventsFull的结构fixtures中,并且该消息清楚地告诉您什么是'错

看一下JSON:key result的值是一个可以用另一个struct表示的字典。

通常,您不需要继承自NSObject的类来解码JSON,结构就足够了,您不需要初始化程序,Codable协议提供初始化程序。

所有可以null的密钥都必须声明为可选,Result中的两个密钥和odds中的密钥EventsData都可以是null。< / p>

struct EventsFull: Decodable {
    let fixtures: [EventsData]
}

struct EventsData: Decodable {
    let date: String
    let status: String
    let matchday: Int
    let homeTeamName: String
    let awayTeamName: String
    let result: Result
    let odds: Double?
}

struct Result : Decodable {
    let goalsHomeTeam : Int?
    let goalsAwayTeam : Int?
}