Skip to content

Instantly share code, notes, and snippets.

@Jerrot
Last active March 17, 2024 13:10
Show Gist options
  • Save Jerrot/fe233a94c5427a4ec29b to your computer and use it in GitHub Desktop.
Save Jerrot/fe233a94c5427a4ec29b to your computer and use it in GitHub Desktop.
Transform arrays with ObjectMapper to Realm's List type
// Based on Swift 1.2, ObjectMapper 0.15, RealmSwift 0.94.1
// Author: Timo Wälisch <[email protected]>
import UIKit
import RealmSwift
import ObjectMapper
import SwiftyJSON
class ArrayTransform<T:RealmSwift.Object where T:Mappable> : TransformType {
typealias Object = List<T>
typealias JSON = Array<AnyObject>
let mapper = Mapper<T>()
func transformFromJSON(value: AnyObject?) -> List<T>? {
var result = List<T>()
if let tempArr = value as! Array<AnyObject>? {
for entry in tempArr {
let mapper = Mapper<T>()
let model : T = mapper.map(entry)!
result.append(model)
}
}
return result
}
// transformToJson was replaced with a solution by @zendobk from https://gist.github.com/zendobk/80b16eb74524a1674871
// to avoid confusing future visitors of this gist. Thanks to @marksbren for pointing this out (see comments of this gist)
func transformToJSON(value: Object?) -> JSON? {
var results = [AnyObject]()
if let value = value {
for obj in value {
let json = mapper.toJSON(obj)
results.append(json)
}
}
return results
}
}
// SampleModel.swift
// Author: Timo Wälisch <[email protected]>
import UIKit
import ObjectMapper
import RealmSwift
import SwiftyJSON
class SampleModel: Object, Mappable {
// MARK: Realm - stored properties
dynamic var title: String = ""
var products = List<ProductModel>()
// MARK: ObjectMapper
class func newInstance(map: Map) -> Mappable? {
return SampleModel()
}
/// Mapping between ObjectMapper (JSON) and the model properties
func mapping(map: Map) {
title <- map["title"]
products <- (map["products"], ArrayTransform<ProductModel>())
}
}
@pabloruan0710
Copy link

Very Crazy, if properties is managed in Realm, the correct is used let for declaration of List and not var ?

@gulzatique
Copy link

gulzatique commented Apr 6, 2017

Thanks it worked for me But I needed to change it according to Swift warnings and errors and this is what I ended up with:

class ArrayTransform<T:RealmSwift.Object> : TransformType where T:Mappable {
    typealias Object = List<T>
    typealias JSON = Array<AnyObject>
    
    let mapper = Mapper<T>()
    
    func transformFromJSON(_ value: Any?) -> List<T>? {
        let result = List<T>()
        if let tempArr = value as! Array<AnyObject>? {
            for entry in tempArr {
                let mapper = Mapper<T>()
                let model : T = mapper.map(JSON: entry as! [String : Any])!
                result.append(model)
            }
        }
        return result
    }
    
    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
    }
}

@calvinsug
Copy link

What if i want to Map my List of Integer or String object? @pendla
I still can't solve it

class X: Object, StaticMappable {
 var strings = List<RealmString>()

 class func objectForMapping(map: Map) -> BaseMappable? {
     return X()
 }

func mapping(map: Map) {
      strings <- (map["strings"], ListTransform<RealmString>())
}
}

class RealmString: Object, StaticMappable {
 dynamic var value = ""
 
 class func objectForMapping(map: Map) -> BaseMappable? {
     return RealmString()
 }
 
 func mapping(map: Map) {
     value <- map
 }

}

Json should be like this :
{
x: ["a","b","c"]
}

@miralem-cebic
Copy link

miralem-cebic commented Dec 8, 2017

Thanks for sharing this code!

Here is my solution for Swift 4.0.2 & Xcode 9.2

import RealmSwift
import ObjectMapper

class ArrayTransform<T:RealmSwift.Object> : TransformType where T:Mappable {
    typealias Object = List<T>
    typealias JSON = Array<AnyObject>

    func transformFromJSON(_ value: Any?) -> List<T>? {
        let result = List<T>()
        if let tempArr = value as! Array<AnyObject>? {
            for entry in tempArr {
                let mapper = Mapper<T>()
                let model : T = mapper.map(JSONObject: entry)!
                result.append(model)
            }
        }
        return result
    }

    func transformToJSON(_ value: List<T>?) -> Array<AnyObject>? {
        if (value!.count > 0) {
            var result = Array<T>()
            for entry in value! {
                result.append(entry)
            }
            return result
        }
        return nil
    }
}

@nadia-am
Copy link

nadia-am commented Jan 1, 2018

@sudeep23 did you find any solution? i have the same problem.

@levibostian
Copy link

@calvinsug I have encountered that problem myself. Storing a list of primitive data types in a Realm List apposed to storing a Realm List of Realm Models.

I give a possible solution here: https://stackoverflow.com/a/54581186/1486374

@ElonPark
Copy link

Thanks

I 'm use not optional forced unwrapping
This is my solution for Swift 4.2 & Xcode 10.1

import RealmSwift
import ObjectMapper

class ArrayTransform<T: RealmSwift.Object>: TransformType where T: Mappable {
    typealias Object = List<T>
    typealias JSON = Array<AnyObject>
    
    /**
     - Parameter value: JSON Value
     - Returns: if value is `nil` or not Array will be return empty List<T>
    */
    func transformFromJSON(_ value: Any?) -> Object? {
        let result = Object()
        guard let _value = value,
            let objectArray = _value as? Array<AnyObject> else { return result }

        let mapper = Mapper<T>()
        
        for object in objectArray {
            //if model is `nil` continue to next object
            guard let model = mapper.map(JSONObject: object) else {
                continue
            }
            
            result.append(model)
        }
        
        return result
    }
    
    /**
     - Parameter value: RealmSwift Object
     - Returns: if value is `nil` or empty will be return empty Array<AnyObject>
     */
    func transformToJSON(_ value: Object?) -> JSON? {
        var result = JSON()
        guard let _value = value, _value.count > 0 else { return  result }
        
        result = _value.map { $0 }
      
        
        return result
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment