Swift中如何解析JSON嵌套数组并为内层数组成员做命名映射?
问题解决方案
1. 编译报错:Value of type 'MovesResponse' has no member 'count'
原因
MovesResponse是自定义结构体,本身不是数组类型,没有count属性。你要获取的是结构体内部moves数组的长度。
解决方法
将movesModel.count > 0改为movesModel.moves.count > 0。
2. JSON无效报错
原因
标准JSON规范要求字符串必须使用双引号包裹,你原代码中使用的单引号'CAT (7)'不符合JSON格式要求,导致解析器认为数据非法。
解决方法
把jsonMoves中所有字符串的单引号替换为双引号。
3. 类型不匹配报错
原因
你定义的MovesResponse中moves字段类型为[[MoveModel]],相当于告诉解析器moves是二维数组,且内层每个元素都是MoveModel类型的字典对象。但实际你的JSON里moves的内层是[Int, String, String]格式的普通数组,没有字典的键值对结构,所以解析器找不到对应结构报错。
解决方法
给MoveModel实现自定义解码逻辑,按顺序从数组容器中读取三个值,同时把MovesResponse中moves的类型改为[MoveModel]。
最终可运行完整代码
// 修正后的JSON,单引号改双引号 let jsonMoves:String = """ { "moves": [ [0, "CAT (7)", "ACT"], [1, "EXTRA (14)", "ERXT"], [0, "TOP (22)", "PO"], [1, "TOY (9)", "Y"] ] } """ // 修正后的结构体定义 struct MovesResponse: Codable { let moves: [MoveModel] } struct MoveModel: Codable { let mine: Int let words: String let letters: String // 自定义解码,从数组容器按顺序取值 init(from decoder: Decoder) throws { var container = try decoder.unkeyedContainer() mine = try container.decode(Int.self) words = try container.decode(String.self) letters = try container.decode(String.self) } } // 修正后的解析代码 let decoder = JSONDecoder() if let movesData = jsonMoves.data(using: .utf8), let movesModel = try? decoder.decode(MovesResponse.self, from: movesData), movesModel.moves.count > 0 { print("Parsed moves: ", movesModel.moves) // 可以直接通过属性名访问对应值 for move in movesModel.moves { print("mine: \(move.mine), words: \(move.words), letters: \(move.letters)") } } else { print("Can not parse moves") }
完成以上修改后,你就可以直接通过mine、words、letters三个属性名访问内层数组的对应元素。
内容的提问来源于stack exchange,提问作者Alexander Farber
相关产品推荐
相关产品推荐

