【问题标题】:Alamofire, Objectmapper, Realm: Nested ObjectsAlamofire,Objectmapper,Realm:嵌套对象
【发布时间】:2016-02-21 14:42:11
【问题描述】:

我正在使用 Alamofire、Objectmapper、Realm,除了一件事之外,一切都在工作:我无法映射嵌套对象。

class Voting: Object, Mappable {

    dynamic var votingID: String = ""
    dynamic var question: String = ""
    var votingOptions = List<VotingOption>()

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

    func mapping(map: Map) {
        votingID <- map["id"]
        question <- map["question"]
        votingOptions <- map["votingOptions"]
    }

    override class func primaryKey() -> String {
        return "votingID"
    }   
}

class VotingOption: Object, Mappable{

    dynamic var optionID: String = ""
    dynamic var text: String = ""


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

    func mapping(map: Map) {
        optionID <- map["id"]
        text <- map["optionText"]
    }

    override class func primaryKey() -> String {
        return "optionID"
    }   
}

我要映射的 JSON 是:

{
    "Voting": [
        {
            "question": "Which option do yo prefer?",
            "id": "7f073efd-6f3d-43f2-9fe4-5cad683b77a2",
            "votingOptions": [
                {
                    "optionText": "Option 3",
                    "id": "3bc0a618-8791-4862-a7fd-5f2df464697d"
                },
                {
                    "optionText": "Option 1",
                    "id": "84c6a830-814b-40c8-a252-c074be5d689a"
                },
                {
                    "optionText": "Option 2",
                    "id": "8872ef6f-fc70-445a-802e-d39944006467"
                }
            ]
        }
    ]
}

VotingOption 中的映射函数永远不会被调用。

【问题讨论】:

    标签: swift realm alamofire objectmapper


    【解决方案1】:

    旧的ListTransform 解决方案不再适用于 Swift 3。

    这就是我现在使用的;例如,将其放入名为ListExtensions.swift 的文件中。

    import Foundation
    import ObjectMapper
    import RealmSwift
    
    /// Maps object of Realm's List type
    func <- <T: Mappable>(left: List<T>, right: Map)
    {
        var array: [T]?
    
        if right.mappingType == .toJSON {
            array = Array(left)
        }
    
        array <- right
    
        if right.mappingType == .fromJSON {
            if let theArray = array {
                left.append(objectsIn: theArray)
            }
        }
    }
    

    这使您可以像这样简单地使用它:

    class Parent: Object, Mappable {
        dynamic var id: Int = 0
        var children = List<Child>()
    
        required convenience init?(_ map: Map) {
            self.init()
        }
    
        func mapping(map: Map) {
            id <- map["id"]
            children <- map["children"]
        }
    }
    

    【讨论】:

    • 也面临这个问题。您的解决方案有帮助!你是救生员,谢谢!
    【解决方案2】:

    您看到的问题是由于 ObjectMapper 不了解 Realm 的 List 类型。它不知道它是一个集合类型,并且它必须就地变异而不是分配给它。您可以在 ObjectMapper GitHub issue #143 中查看对此的讨论,包括一些建议的解决方法。

    另请注意,Object 子类上的任何List 属性都应使用let 而不是var 声明。

    【讨论】:

      【解决方案3】:
      class ListTransform<T:RealmSwift.Object> : TransformType where T:Mappable {
          typealias Object = List<T>
          typealias JSON = [AnyObject]
      
          let mapper = Mapper<T>()
      
          func transformFromJSON(_ value: Any?) -> Object? {
              let results = List<T>()
              if let objects = mapper.mapArray(JSONObject: value) {
                  for object in objects {
                      results.append(object)
                  }
              }
              return results
          }
      
          func transformToJSON(_ value: Object?) -> JSON? {
              var results = [AnyObject]()
              if let value = value {
                  for obj in value {
                      let json = mapper.toJSON(obj)
                      results.append(json as AnyObject)
                  }
              }
              return results
          }
      }
      

      然后在你的模型中是这样的。

      class Parent: Object, Mappable {
          dynamic var id: Int = 0
          var children = List<Child>()
      
          required convenience init?(_ map: Map) {
              self.init()
          }
      
          func mapping(map: Map) {
              id <- map["id"]
              child <- (map["children"], ListTransform<Child>())
          }
      }
      

      【讨论】:

      • 谢谢,我已重用您的代码将 dict 解析为对象数组,其中 object 的字段包含该对象的 dict 中的键。
      • 试用当前版本
      【解决方案4】:

      您可以为 Realm.List 类型扩展 ObjectMapper,使用如下运算符函数:

      public func <- <T: Object where T: Mappable, T: JSPrimaryKey>(left: List<T>, right: Map) {
        if right.mappingType == MappingType.FromJSON {
          if let value = right.currentValue {
            left.removeAll()
            if let json = value as? [[String : AnyObject]] {
              let objs = RealmS().add(T.self, json: json)
              left.appendContentsOf(objs)
            }
          }
        }
      }
      

      自己试试吧。

      ObjectMappper + Realm List type

      【讨论】:

        猜你喜欢
        • 2016-02-18
        • 1970-01-01
        • 2016-02-17
        • 1970-01-01
        • 2018-04-29
        • 1970-01-01
        • 1970-01-01
        • 2019-08-03
        • 2017-01-25
        相关资源
        最近更新 更多