I\'m using Alamofire, Objectmapper, Realm and everything is working beside one thing: I can\'t map nested objects.
class Voting: Object, Mappable {
dyna
You can extend ObjectMapper for Realm.List type with a operator function like as:
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)
}
}
}
}
Try yourself.
ObjectMappper + Realm List type
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 <- <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)
}
}
}
This allows you to simply use it like this:
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"]
}
}
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
.
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
}
}
Then in your model something like this.
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>())
}
}