为何JSON树中的连续数字键会导致转换为NSDictionary失败?
问题原因与解决方案
这个坑我之前踩过!问题出在Firebase对JSON数据的自动类型转换逻辑上:
当Firebase解析到键是连续整数形式的字符串(比如你这里的"1"、"2"、"3")时,会默认把这部分数据识别成数组(NSArray),而不是你预期的字典(NSDictionary)。这时候你硬要把它转成NSDictionary,自然会失败。
验证方法
你可以在回调里先打印下返回值的类型,确认是不是数组:
r.child(accessKey).child("matches").observeSingleEvent(of: .value) { snapshot in print("返回值类型:\(type(of: snapshot.value))") // 大概率会输出NSArray或者Array<Any> }
两种解决方案
方案1:适配数组类型处理数据
既然Firebase自动转成了数组,那我们就按数组来解析。注意数组的索引是从0开始的,对应原数据里的"1"是数组第0个元素,"2"是第1个,以此类推:
r.child(accessKey).child("matches").observeSingleEvent(of: .value) { snapshot in guard let matchesArray = snapshot.value as? [Any] else { print("无法解析为数组") return } // 遍历数组处理每个match for (arrayIndex, matchData) in matchesArray.enumerated() { guard let matchDict = matchData as? [String: [String]] else { continue } let originalMatchNumber = arrayIndex + 1 print("第\(originalMatchNumber)场比赛数据:\(matchDict)") // 比如获取Red队成员:matchDict["0931-Red"] } }
方案2:修改Firebase数据的键名,避免自动转数组
如果更习惯用字典处理,那可以给数字键加个前缀(比如"match_"),打破连续整数键的规则,Firebase就会保持字典类型:
修改后的JSON结构示例:
"matches" : { "match_1" : { "0931-Red" : [ "John Smith" ], "2022-Blue" : [ "Paul Adams" ] }, "match_2" : { "1489-Red" : [ "Matthew Brown" ], "1565-Blue" : [ "Ian Fowler" ] }, "match_3" : { "1652-Red" : [ "" ], "2626-Blue" : [ "" ] } }
之后你再转NSDictionary就可以正常解析了:
r.child(accessKey).child("matches").observeSingleEvent(of: .value) { snapshot in guard let matchesDict = snapshot.value as? [String: [String: [String]]] else { print("无法解析为字典") return } // 遍历字典处理 for (matchKey, matchData) in matchesDict { print("比赛\(matchKey)数据:\(matchData)") } }
内容的提问来源于stack exchange,提问作者bearacuda13
相关产品推荐
相关产品推荐

