You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift 4获取各频道歌曲报错:Root与Playlist结构体格式问题求助

修复Swift 4中JSON解析Root/Playlist结构体的异常问题

我当初刚学Swift JSON解析的时候也踩过不少结构体匹配的坑,太懂这种明明结构看起来一致却报错的痛苦了!结合你说的Previous和Song结构一致的情况,咱们一步步排查修复:

1. 先搞清楚「JSON结构」和「Swift结构体」的匹配度

这是最容易出错的核心点,你可以先把API返回的原始JSON打印出来,逐层级对比:

  • 属性名大小写/拼写必须完全对应:Swift 4默认大小写敏感,比如JSON里是"songTitle",你结构体里写song_title就会直接解析失败。如果不想改属性名,就用CodingKeys做映射:
    struct Song: Codable {
        let songTitle: String
        let artistName: String
        
        // 用CodingKeys映射JSON的key
        enum CodingKeys: String, CodingKey {
            case songTitle = "song_title"
            case artistName = "artist_name"
        }
    }
    
  • 可选值标记不能漏:如果JSON里某个字段可能为null(比如有些频道可能还没有上一首歌曲),结构体里对应的属性必须加?,比如let previousSong: Song?,否则会因为缺失值报错。
  • 直接复用Song结构体,删掉Previous:既然你说两者结构完全一致,没必要单独定义Previous,直接在Playlist里用Song类型就行,既减少冗余,也避免不小心写出不一致的结构。

2. 验证Root和Playlist的嵌套层级

举个实际的例子,假设你的API返回JSON是这样的:

{
  "playlist": {
    "current_song": {
      "title": "Hello",
      "artist": "Adele"
    },
    "previous_song": {
      "title": "Rolling in the Deep",
      "artist": "Adele"
    }
  }
}

那对应的正确Swift结构体应该是:

// 最外层的Root结构
struct Root: Codable {
    let playlist: Playlist
}

// 播放列表结构
struct Playlist: Codable {
    let currentSong: Song
    let previousSong: Song? // 上一首可能为空,加可选标记
    
    enum CodingKeys: String, CodingKey {
        case currentSong = "current_song"
        case previousSong = "previous_song"
    }
}

// 歌曲结构(同时复用给当前和上一首)
struct Song: Codable {
    let title: String
    let artist: String
}

3. 捕获具体的解析错误信息

别只知道“解析失败”,把错误详情打出来,能直接定位问题:

// 假设你已经拿到了JSON数据jsonData
do {
    let decodedData = try JSONDecoder().decode(Root.self, from: jsonData)
    print("当前歌曲:\(decodedData.playlist.currentSong.title)")
    if let prevSong = decodedData.playlist.previousSong {
        print("上一首歌曲:\(prevSong.title)")
    }
} catch let decodingError {
    print("解析错误详情:\(decodingError)")
    // 错误信息会明确告诉你是key找不到、类型不匹配还是层级错误
}

比如如果报错keyNotFound(CodingKeys(stringValue: "current_song", intValue: nil)...,那就是Playlist里的currentSong对应的JSON key写错了,直接修正就行。

4. 最后检查几个常见小坑

  • 别把数组和字典搞混:如果JSON里是数组(比如"songs": [...]),结构体里必须写成let songs: [Song],不能写成字典类型。
  • 数值类型要匹配:比如JSON里的duration是数字180,结构体里不能写成String类型,必须用Int或Double。
  • 所有嵌套结构体都要遵循Codable:Swift 4会自动给属性都符合Codable的结构体合成实现,但如果手动写了init(from:),要确保所有属性都正确解码。

内容的提问来源于stack exchange,提问作者David Ruland

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:04:47