Swift中Facebook JSON含friends_v2致解码崩溃,如何适配?
Swift解码带外层字段的Facebook好友JSON解决方案
问题核心是你的JSON结构外层有friends_v2字段包裹好友数组,但原代码直接尝试解码成[Friends]类型,结构不匹配导致崩溃。只需新增一个顶层结构体匹配JSON的外层结构即可解决。
修改后的JSONManager.swift代码
struct Friends: Codable { var name: String var timestamp: Int var contact_info: String? } // 新增顶层结构体,匹配JSON外层结构 struct FriendsResponse: Codable { let friends_v2: [Friends] } extension Friends { static let allFriends: [Friends] = { let response: FriendsResponse = Bundle.main.decode(file: "friends.json") return response.friends_v2 }() static let allFriendsSample: Friends = allFriends[0] } extension Bundle { func decode<T: Decodable>(file: String) -> T { guard let url = self.url(forResource: file, withExtension: nil) else { fatalError("无法在项目中找到文件 \(file)") } guard let data = try? Data(contentsOf: url) else { fatalError("无法加载项目中的文件 \(file)") } let decoder = JSONDecoder() guard let loadData = try? decoder.decode(T.self, from: data) else { fatalError("无法解码项目中的文件 \(file)") } return loadData } }
关键修改说明
- 新增
FriendsResponse结构体,它的friends_v2属性完全对应JSON的外层字段,类型是好友数组[Friends] - 修改
Friends.allFriends的初始化逻辑:先解码得到FriendsResponse实例,再从中取出friends_v2数组赋值给allFriends - 原
Friends结构体无需改动,保持对单个好友数据的映射
可选优化建议
原代码中的try?会隐藏解码错误的具体信息,不利于调试,建议改成do-catch捕获错误:
func decode<T: Decodable>(file: String) -> T { guard let url = self.url(forResource: file, withExtension: nil) else { fatalError("无法在项目中找到文件 \(file)") } let data: Data do { data = try Data(contentsOf: url) } catch { fatalError("加载文件 \(file) 失败:\(error.localizedDescription)") } let decoder = JSONDecoder() do { return try decoder.decode(T.self, from: data) } catch { fatalError("解码文件 \(file) 失败:\(error.localizedDescription)") } }
ContentView无需修改,因为friends属性依然是[Friends]类型,原有逻辑完全兼容。
内容的提问来源于stack exchange,提问作者kAiN
相关产品推荐
相关产品推荐

