2015-11-19 2 views
2

Я использую Alamofire, Objectmapper, Realm, и все работает рядом с одним: я не могу отображать вложенные объекты.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" 
       } 
      ] 
     } 
    ] 
} 

Отображение Funktion в VotingOption никогда не вызывается.

ответ

2

Старое 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"] 
    } 
} 
3

Проблема, которую вы видите, связана с ObjectMapper, не знающим тип Realm's List. Он не знает, что это тип коллекции, и что он должен быть мутирован на месте, а не назначен. Вы можете обсудить это, включая некоторые предлагаемые способы обхода, в ObjectMapper GitHub issue #143.

Заметим также, что любые List свойства на Object подклассов должны быть объявлены с let, а не var.

-1

Вы можете продлить ObjectMapper для Realm.List типа с функцией оператора вроде как:

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

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>()) 
    } 
} 
+0

спасибо, я повторно код для разбора Dict в массив объектов, где объект имеет поле, содержащее ключ в Словаре для этот объект. –

+0

Это больше не работает в Swift 3. –

+0

Пробуйте текущую версию – GregP

Смежные вопросы