如何使用Swift解析本地JSON文件中的bookInfo与bookAudio两个数组
代码修正说明
你原来的代码存在几个明确的错误,修正后就可以同时解析两个数组:
- 拼写错误1:
parseLoop方法里你取的bookTop.bookDesk不存在,BookDesc结构体的对应属性名是bookStruct - 拼写错误2:
parseBooks方法末尾返回的loopsInfo是未定义变量,你实际要返回的是自己定义的收集变量 - 逻辑缺陷:
parseBooks原来的返回值只有[BookInfo],要同时拿两个数组需要调整返回值类型,同时收集两个数组的解析结果 - 路径错误:你前面遍历了
BooksFolders子目录找JSON,后面获取文件URL时指定subdirectory:nil是在Bundle根目录找,路径不匹配会找不到文件
修正后的完整代码
首先新增存储bookAudio解析结果的变量:
// 原有存储bookInfo的数组 var booksCollect = [BookInfo]() // 新增存储bookAudio的数组 var audiosCollect = [BookAudio]()
修正解析相关方法:
struct BookDesc: Decodable { let bookStruct: BookStruct } struct BookStruct: Decodable { let bookInfo: [BookInfo] let bookAudio: [BookAudio] } struct BookAudio: Decodable { let name: String let instrument: String let bookSong: String } struct BookInfo: Decodable { let name: String let genre: String let imagename: String } func parseBooks() -> ([BookInfo], [BookAudio]) { var infoList = [BookInfo]() var audioList = [BookAudio]() // 修正子目录参数为BooksFolders,匹配JSON实际存放路径 guard let urls = Bundle.main.urls(forResourcesWithExtension:".json", subdirectory:"BooksFolders") else { return (infoList, audioList) } for url in urls { do { let bookStruct = try parseLoop(url: url) // 同时收集两个数组的解析结果 infoList.append(contentsOf: bookStruct.bookInfo) audioList.append(contentsOf: bookStruct.bookAudio) } catch { print("\(error) reading \(url)") } } return (infoList, audioList) } func parseLoop(url: URL) throws -> BookStruct { let jsonData = try Data(contentsOf: url) let bookTop = try JSONDecoder().decode(BookDesc.self, from: jsonData) // 修正属性名拼写错误 return bookTop.bookStruct } func prepareInit() { let (infoResult, audioResult) = parseBooks() booksCollect = infoResult audiosCollect = audioResult tableView.reloadData() }
额外注意:你给出的JSON示例中
bookAudio数组的每个元素末尾多了一个尾随逗号,老版本的JSONDecoder可能会报错,遇到解析失败可以先把JSON里的多余逗号删掉。
内容的提问来源于stack exchange,提问作者dextermikles
相关产品推荐
相关产品推荐

