可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm using Alamofire, Objectmapper, Realm and everything is working beside one thing: I can't map nested objects.
class Voting: Object, Mappable { dynamic var votingID: String = "" dynamic var question: String = "" var votingOptions = List() required convenience init?(_ map: Map) { self.init() } func mapping(map: Map) { votingID 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 String { return "optionID" } }
The JSON that I'm trying to map is:
{ "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" } ] } ] }
The mapping funktion in VotingOption never gets called.
回答1:
The old ListTransform solution no longer works in Swift 3.
This is what I'm using now; put this in a file called, ListExtensions.swift, for example.
import Foundation import ObjectMapper import RealmSwift /// Maps object of Realm's List type func (left: List, right: Map) { var array: [T]? if right.mappingType == .toJSON { array = Array(left) } array
This allows you can simply use it like this:
class Parent: Object, Mappable { dynamic var id: Int = 0 var children = List() required convenience init?(_ map: Map) { self.init() } func mapping(map: Map) { id
回答2:
The problem you're seeing is due to ObjectMapper having no knowledge of Realm's List type. It is not aware that it is a collection type, and that it must be mutated in place rather than being assigned to. You can see discussion of this, including some suggested workarounds, in ObjectMapper GitHub issue #143.
Note also that any List properties on Object subclasses should be declared with let rather than var.
回答3:
class ListTransform : TransformType where T:Mappable { typealias Object = List typealias JSON = [AnyObject] let mapper = Mapper() func transformFromJSON(_ value: Any?) -> Object? { let results = List() 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 } }
Then in your model something like this.
class Parent: Object, Mappable { dynamic var id: Int = 0 var children = List() required convenience init?(_ map: Map) { self.init() } func mapping(map: Map) { id ()) } }
回答4:
You can extend ObjectMapper for Realm.List type with a operator function like as:
public func (left: List, 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) } } } }
Try yourself.
ObjectMappper + Realm List type