Edited at
RealmDay 3

RealmObjectをDictionaryに変換する

More than 3 years have passed since last update.


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