Swift 4从Firebase取数据至iOS TableView时NSUnknownKeyException报错求助
解决iOS Firebase数据解析时的
NSUnknownKeyException错误 Hey there, let's fix this frustrating KVC error you're running into! 😊
错误原因拆解
这个错误的核心是:Firebase尝试给你的NewWord对象设置名为vietnam的属性,但你的NewWord类没有这个属性,或者属性名和Firebase数据里的键不匹配(KVC是严格区分大小写和拼写的)。
一步步解决问题
1. 核对NewWord类的属性拼写
首先打开你的NewWord类,确保存在和Firebase数据键完全一致的属性:
- 如果Firebase数据库里的键是
vietnam,你的类里必须有var vietnam: String?(或者对应的数据类型),大小写、拼写丝毫不差! - 另外,如果你用KVC方式解析(比如
setValue:forKey:),NewWord必须继承自NSObject(因为KVC是Objective-C的特性,纯Swift类不支持)。
举个正确的类示例:
import Foundation import Firebase class NewWord: NSObject { // 属性名和Firebase键完全一致 var english: String? var vietnam: String? // 可选:直接从DataSnapshot初始化,避免KVC风险 init(snapshot: DataSnapshot) { let valueDict = snapshot.value as? [String: Any] self.english = valueDict?["english"] as? String self.vietnam = valueDict?["vietnam"] as? String super.init() } }
2. 检查Firebase数据的键名
登录Firebase控制台,确认你的数据节点里的键确实是vietnam——有没有写成vietnamese、Vietnam(首字母大写)这类拼写错误?这些小细节都会触发KVC找不到属性的问题。
3. 替换不安全的KVC赋值方式
如果你之前用的是setValue:forKey:这类KVC方法,建议换成直接从字典取值的方式(像上面示例里的init(snapshot:)),这种写法更安全,也能彻底避开KVC的坑。
比如,修改你的数据获取函数:
func fetchWordsFromFirebase() { let dbRef = Database.database().reference().child("your-word-node-name") dbRef.observe(.value) { snapshot in var wordList = [NewWord]() for childSnapshot in snapshot.children { guard let snap = childSnapshot as? DataSnapshot else { continue } let newWord = NewWord(snapshot: snap) wordList.append(newWord) } // 更新TableView数据 self.words = wordList self.tableView.reloadData() } }
4. 用Swift现代写法:Codable解析
如果你不想让NewWord继承NSObject,可以用Swift的Codable协议来解析,更符合Swift的设计风格:
class NewWord: Codable { var english: String? var vietnam: String? } // 在数据获取函数里解析 func fetchWordsWithCodable() { let dbRef = Database.database().reference().child("your-word-node-name") dbRef.observe(.value) { snapshot in var wordList = [NewWord]() for childSnapshot in snapshot.children { guard let snap = childSnapshot as? DataSnapshot, let valueDict = snap.value as? [String: Any], let jsonData = try? JSONSerialization.data(withJSONObject: valueDict), let word = try? JSONDecoder().decode(NewWord.self, from: jsonData) else { continue } wordList.append(word) } self.words = wordList self.tableView.reloadData() } }
内容的提问来源于stack exchange,提问作者Linh Đặng Tuấn
相关产品推荐
相关产品推荐

