在 Swift 中使用 swiftyJSON 成功将 JSON 写入 Realm DB

Successfully write JSON to Realm DB using swiftyJSON in Swift

我正在尝试从 JSON 文件(使用 swiftyJSON)写入 Realm DB,出现以下错误:

libc++abi.dylib: terminating with uncaught exception of type NSException *** Terminating app due to uncaught exception 'RLMException', reason: 'Invalid value '{ "vehicle" : true, "viewable" : true, "id" : 0, "weapon" : false, "genres" : "[Fantasy, General]", "name" : "Car" }' to initialize object of type 'Item': missing key 'id''

我的 JSON 文件结构如下:

  [
  {
    "id": 0,
    "name": "Car",
    "genres": "[Fantasy, General]",
    "viewable": true,
    "weapon": false,
    "vehicle": true
  },
  {
    "id": 1,
    "name": "Truck",
    "genres": "[General]",
    "viewable": true,
    "weapon": false,
    "vehicle": true
  },
]

我的领域数据库 Class 是:

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,包括流派列表,我们将不胜感激。

注意:我已经设法在 'Write' 函数之前使用以下代码(基于 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: [])

谢谢!

通过以下方法解决:

  1. 对我的 JSON 结构稍作改动如下:

     [
       {
         "id": 0,
         "name": "Car",
         "genres": ["Fantasy", "General"],
         "viewable": true,
         "weapon": false,
         "vehicle": true
       },
       {
         "id": 1,
         "name": "Truck",
         "genres": ["Fantasy", "General"],
         "viewable": true,
         "weapon": false,
         "vehicle": true
       }
     ]
    
  2. 创建了一个新的流派对象以更好地处理列表

     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 函数中更新了代码以创建一个新的 Item 对象,然后在尝试写入 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)
        }
    }