LoginSignup
19
21

More than 5 years have passed since last update.

RealmObjectをDictionaryに変換する

Last updated at Posted at 2015-12-02

ObjectをDictionaryにする

Realm アドベントカレンダー三日目ですね.
ちっちゃな子ネタをどうぞ.

どれくらい思うことがあるのかわかりませんが,RealmのObjectをDictionaryとかに戻したい,相互変換したいって思ったことはありませんか?

私はあります.

import RealmSwift
extension Object {
    func toDictionary() -> Dictionary<String, AnyObject> {
        let properties = self.objectSchema.properties.map { $0.name }
        let dictionary = self.dictionaryWithValuesForKeys(properties)

        let mutabledic = NSMutableDictionary()
        mutabledic.setValuesForKeysWithDictionary(dictionary)

        for prop in self.objectSchema.properties as [Property]! {
            if let nestedObject = self[prop.name] as? Object {
                mutabledic.setValue(nestedObject.toDictionary() as NSDictionary, forKey: prop.name)
            } else if let nestedListObject = self[prop.name] as? ListBase {
                var objects = [AnyObject]()
                for index in 0..<nestedListObject._rlmArray.count {
                    let object = nestedListObject._rlmArray[index] as AnyObject
                    objects.append(object.toDictionary() as NSDictionary)
                }
                mutabledic.setObject(objects, forKey: prop.name)
            }
        }

        return mutabledic as NSDictionary as! Dictionary<String, AnyObject>
    }
}

簡単に解説してみると

        let properties = self.objectSchema.properties.map { $0.name }
        let dictionary = self.dictionaryWithValuesForKeys(properties)

        let mutabledic = NSMutableDictionary()
        mutabledic.setValuesForKeysWithDictionary(dictionary)

このあたりで,Realm固有の型以外をだいたいNSMutableDictionaryにコピーできています.

objectSchema.properties でObjectのschemaを取得できます.
dictionaryWithValuesForKeys(properties) でSchemaをザザっとNSDictionaryにコピーできてしまいます.

ここから下は,再帰したりしながらListBaseや,ObjectをDictionary化していくコードですね.

ついでに,Camel CaseをSnake Caseに変換するコードも用意しました.

extension String {
    func snakeCaseString() -> String {
        var result = ""
        self.characters.forEach( { char in
let string = "\(char)" as NSString
result += string.isEqualToString(string.capitalizedString) ? "_\(string.lowercaseString)" : "\(char)"
        })
        return result
}

やっていることは超単純で,文字を一文字づつチェックして,大文字だったら"_小文字"に置き換えるだけというものです.これでだいたいsnake caseにできちゃいます.

そして,このあたりを組み合わせてJSONにするとかすれば

API -> Object -> Dictionary -> JSON -> API

みたいな流れがすごくやりやすくなるかと思います.

私の場合は

APIKit → Himotoki → Object → Dictionary → Himotoki

みたいな変換をちらほらしています

参考:http://stackoverflow.com/questions/31150087/can-i-serialize-a-realmobject-to-json-or-to-nsdictionary-in-realm-for-swift

19
21
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
21