如何使用Combine解析嵌套JSON结构,获取内部的Book数组数据
问题原因
你解码得到BookWrapper类型后,没有取出内部的books数组就直接赋值给了[Book]类型的books属性,类型不匹配导致无法得到正确结果。
解决方案
方案1:复用已定义的BookWrapper(推荐,可维护性高)
直接在原有Combine链上追加取内部属性的操作即可:
func fetchBooks() { URLSession.shared.dataTaskPublisher(for: url) .map{ $0.data } .decode(type: BookWrapper.self, decoder: JSONDecoder()) .replaceError(with: BookWrapper(books: [])) .map(\.books) // 取出Wrapper内的书籍数组 .eraseToAnyPublisher() .receive(on: DispatchQueue.main) .assign(to: &$books) }
如果需要处理接口返回的错误信息,可以给BookWrapper补全对应属性即可,不影响现有解码逻辑:
struct BookWrapper: Codable { var books: [Book] var errMsg: String? // 对应JSON中的可选字段 }
方案2:无需定义Wrapper的简化写法
如果不想额外定义Wrapper结构体,可以直接将外层JSON解码为字典类型,再取出对应数组:
func fetchBooks() { URLSession.shared.dataTaskPublisher(for: url) .map{ $0.data } .decode(type: [String: [Book]].self, decoder: JSONDecoder()) .replaceError(with: [:]) .map{ $0["books"] ?? [] } .eraseToAnyPublisher() .receive(on: DispatchQueue.main) .assign(to: &$books) }
该方案适合结构简单、后续不会扩展字段的接口场景。
内容的提问来源于stack exchange,提问作者BobC
相关产品推荐
相关产品推荐

