问题描述
我尝试从 JSON 文件(使用 swiftyJSON)写入 Realm DB 时出现以下错误:
libc++abi.dylib:以 NSException 类型的未捕获异常终止 *** 由于未捕获的异常“RLMException”而终止应用程序,原因:“值无效”{ “车辆”:真的, “可见”:真实, “身份证”:0, “武器”:假, “流派”:“[幻想,一般]”, “名称”:“汽车” }' 来初始化类型为 'Item' 的对象:缺少键 'id''
我的 JSON 文件结构如下:
[
{
"id": 0,"name": "Car","genres": "[Fantasy,General]","viewable": true,"weapon": false,"vehicle": true
},{
"id": 1,"name": "Truck","genres": "[General]",]
我的领域数据库类是:
class Item: Object {
@objc dynamic var id: Int = 0
@objc dynamic var name = ""
let genres = List<String>()
@objc dynamic var visable: Bool = false
@objc dynamic var weapon: Bool = false
@objc dynamic var vehicle: Bool = false
override static func primaryKey() -> String? {
return "id"
}
override static func indexedProperties() -> [String] {
return ["genre","visable"]
}
}
将JSON写入RealmDB的代码如下:
func jsonAdd() {
if let path = Bundle.main.path(forResource: "Data",ofType: "json") {
do {
let data = try Data(contentsOf: URL(fileURLWithPath: path),options: .mappedIfSafe)
let json = JSON(data)
for (index,subJson):(String,JSON) in json {
do {
try realm.write {
realm.create(Item.self,value: subJson,update: .modified)
}
} catch let error as NSError {
print("Unable to write")
print(error)
}
}
} catch {
print("Error")
}
}
}
我认为这个问题是一个 JSON 映射问题,但将 JSON 写入 Realm DB 包括流派作为列表的任何帮助将不胜感激。
注意:我已经设法在“写入”函数之前使用以下代码(基于 Realm 文档)写入 Realm DB,但似乎无法使其适用于我的 JSON 结构。
let newdata = "{\"id\": 0,\"name\": \"Car\",\"genres\": [\"Fantasy\",\"General\"],\"viewable\": true,\"weapon\": false,\"vehicle\": true}".data(using: .utf8)!
let json = try! JSONSerialization.jsonObject(with: newdata,options: [])
谢谢!
解决方法
通过以下方法解决:
-
我的 JSON 结构略有变化,如下所示:
[ { "id": 0,"name": "Car","genres": ["Fantasy","General"],"viewable": true,"weapon": false,"vehicle": true },{ "id": 1,"name": "Truck","vehicle": true } ]
-
创建了一个新的流派对象以更好地处理列表
class Genres: Object { @objc dynamic var id = 0 @objc dynamic var name = "" override static func primaryKey() -> String? { return "id" } } class Item: Object { @objc dynamic var id = 0 @objc dynamic var name = "" var genres = List<Genres>() @objc dynamic var viewable: Bool = false @objc dynamic var weapon: Bool = false @objc dynamic var vehicle: Bool = false override static func primaryKey() -> String? { return "id" } override static func indexedProperties() -> [String] { return ["genres","viewable"] } }
3) 至关重要的是,在 jsonADD 函数中更新了代码以创建一个新的项目对象,然后在尝试写入 Realm DB 之前将 JSON 值映射到该对象:
for (key,subJson):(String,JSON) in jsonObjects {
let thisItem = Item()
thisItem.id = subJson["id"].intValue
thisItem.name = subJson["name"].stringValue
thisItem.visable = subJson["viewable"].boolValue
thisItem.weapon = subJson["weapon"].boolValue
thisItem.vehicle = subJson["vehicle"].boolValue
let genreArray = subJson["genres"].arrayValue
for genre in genreArray {
let string = genre.stringValue
let predicate = NSPredicate(format: "name = %@",string)
if let foundGenre = realm.objects(Genres.self).filter(predicate).first {
thisItem.genres.append(foundGenre)
}
}
do {
try realm.write {
realm.create(Item.self,value: thisItem,update: .modified)
}
} catch let error as NSError {
print("Unable to write")
print(error)
}
}