Realm + Swift,嵌套JSON

时间:2016-08-24 15:22:23

标签: json swift dictionary realm

自从过去2天以来我遇到了问题。我无法将我的JSON转换为Realm对象。

我有一个像下面这样的json:

{
  "gender" : "male",
  "id" : "123456789",
  "age_range" : {
    "min" : 21
  },
  "last_name" : "LastName" 
}

我有这个领域模型:

class UserObject: Object {

    dynamic var userId: String = ""
    dynamic var lastName: String?
    dynamic var gender: String?
    var ageRange = List<AgeRangeObject>()

    required convenience init?(_ map: Map) {
        self.init()
    }
}

class AgeRangeObject: Object {

    dynamic var min: Int = 0
}

我尝试使用ObjectMapper创建此模型的实例以将json解析为字典,然后创建模型实例:

    let userJSONModel = Mapper<User>().map(jsonString)

    let realm = try! Realm()

    do {
        try realm.write {

            let dict: [String : AnyObject] = [
                "userId" : (userJSONModel?.userId)!,
                "ageRange" : (userJSONModel?.ageRange)!,
                "lastName" : (userJSONModel?.lastName)!,
                "gender" : (userJSONModel?.gender)!
            ]

            let userModel = UserObject(value: dict)

            realm.add(userModel)
        }
    } catch {
        print("Exception")
    }

问题出现在这一行:let userModel = UserObject(value: dict)

我收到了以下错误:

*** Terminating app due to uncaught exception 'RLMException', reason: 'Invalid value 'min' to initialize object of type 'AgeRangeObject': missing key 'min''

我正在查看stackoverflow:

Nested Arrays throwing error in realm.create(value: JSON) for Swift

How to convert Realm object to JSON with nested NSDate properties?

但我的情况有所不同。 你知道那个年龄段字典的问题是什么吗?为什么它不能很好地解析它? 谢谢。

2 个答案:

答案 0 :(得分:3)

在您的JSON中,ageRange是字典,而UserObject.ageRange属性是List<AgeRangeObject>。你的模型不匹配。

您需要更新模型以反映JSON的结构:

var ageRange = List<AgeRangeObject>()

变为

dynamic var ageRange: AgeRangeObject? = nil

反之亦然,更新您的JSON以反映模型的结构:

{
  "gender" : "male",
  "id" : "123456789",
  "age_range" : [{
    "min" : 21
  }],
  "last_name" : "LastName" 
}

答案 1 :(得分:0)

{
  "key1" : "value1",
  "key2" : "value2",
  "array1" : [{
    "key" : value
  }],
 "key3" : "value3" 
}

为此,您可以使用ObjectMapper的TransformType。

参考:https://github.com/APUtils/ObjectMapperAdditions

我的代码:

@objcMembers class RealmObject: Object, Mappable {

  dynamic var listValues = List<MyRealmObject>()

  required convenience init?(map: Map) {
    self.init()
  }

 // Mappable
 func mapping(map: Map) {
   listValues <- (map["listValues"], RealmlistObjectTransform())
  }

}

@objcMembers class MyRealmObject: Object, Mappable {

    required convenience init?(map: Map) {
      self.init()
    }

    // Mappable
    func mapping(map: Map) {

    }
  }

class RealmlistObjectTransform: TransformType {
    typealias Object = List<MyRealmObject> // My Realm Object here
    typealias JSON = [[String: Any]] // Dictionary here

    func transformFromJSON(_ value: Any?) -> List<MyRealmObject>? {
      let list = List<MyRealmObject>()
      if let actors = value as? [[String: Any]]  {
        let objects = Array<MyRealmObject>(JSONArray: actors)
        list.append(objectsIn: objects)
      }
      return list
    }

    func transformToJSON(_ value: List<MyRealmObject>?) -> [[String: Any]]? {
      if let actors = value?.sorted(byKeyPath: "").toArray(ofType: MyRealmObject.self).toJSON() {
        return actors
      }
      return nil
    }
  }