Swift中如何仅解码JSON部分内容(含嵌套结构)
解决Swift中Flickr API JSON解析返回nil的问题
嘿,我完全懂你不想写一堆Struct的心情,用字典映射到类对象确实灵活不少。你遇到的JSONSerialization返回nil的问题,大概率是这几个原因导致的——要么数据处理太随意,要么错误被吞了没抓到,咱们一步步来解决:
第一步:别用try?,先抓出错误根源
try?会把所有解析错误直接变成nil,你根本不知道是数据坏了还是格式不对。换成do-catch捕获错误,先搞清楚问题出在哪:
// 别强制解包data!用if let做安全处理 if let responseData = data { do { // 先把JSON转成Any类型,再逐层向下转换 let rawJson = try JSONSerialization.jsonObject(with: responseData, options: []) // 确认顶层是字典,再取出items数组 guard let jsonDict = rawJson as? [String: Any], let itemsArray = jsonDict["items"] as? [[String: Any]] else { print("JSON结构不符合预期——要么顶层不是字典,要么没有items数组") return } // 到这里items已经成功提取,接下来处理每个item里的media self.processFlickrItems(itemsArray) } catch { // 这里能看到具体的解析错误,比如JSON格式损坏、编码问题 print("JSON解析失败:\(error.localizedDescription)") } } else { print("请求返回的数据为空,检查Flickr API的请求是否成功") }
第二步:用字典初始化你的类对象
假设你有一个自定义的FlickrPhoto类,直接用遍历出来的item字典初始化就行,嵌套的media结构也能轻松处理:
class FlickrPhoto { var title: String? var imageUrl: String? var author: String? // 用字典初始化的方法 init(from dict: [String: Any]) { self.title = dict["title"] as? String self.author = dict["author"] as? String // 处理嵌套的media结构 if let mediaDict = dict["media"] as? [String: String] { // Flickr的media里的"m"是中等尺寸图片的URL self.imageUrl = mediaDict["m"] } } } // 批量转成类对象的方法 func processFlickrItems(_ items: [[String: Any]]) { let photos = items.map { FlickrPhoto(from: $0) } // 这里就得到了所有Photo对象的数组,接下来按需使用即可 print("共解析到\(photos.count)张图片") }
常见踩坑点排查
如果还是遇到nil,检查这几个地方:
- API请求是否成功:确认网络请求返回状态码为200,可打印responseData的字符串版本,看看是否拿到了正确的JSON数据。
- 字段名大小写:Flickr API返回的字段全是小写,比如
items、media、m,别写错成大写或者拼写错误。 - JSON顶层结构:Flickr的feed接口返回的是顶层字典,里面包含
items数组,别把顶层结构当成数组处理。
这样处理下来,既不用写一堆Codable Struct,又能安全解析出你需要的内容,还能明确抓到错误原因,比直接用try?靠谱多啦~
内容的提问来源于stack exchange,提问作者user185887
相关产品推荐
相关产品推荐

