2015-06-30 1 views
2

Я тестирую Realm, но я не могу найти простой способ конвертировать свой объект в JSON. Мне нужно передать данные в мой интерфейс REST. Как это сделать с помощью swift?Могу ли я сериализовать объект RealmObject для JSON или NSDictionary в Realm для Swift?

class Dog: Object { 
    dynamic var name = "" 
} 

class Person : Object { 
    dynamic var name = "" 
    let dogs = List<Dog>() 
} 

Я что-то вроде этого пытается, но я не могу перебирать неизвестные объекты (список)

extension Object { 
    func toDictionary() -> NSDictionary { 
    let props = self.objectSchema.properties.map { $0.name } 
    var dicProps = self.dictionaryWithValuesForKeys(props) 

    var mutabledic = NSMutableDictionary() 
    mutabledic.setValuesForKeysWithDictionary(dicProps) 

    for prop in self.objectSchema.properties as [Property]! { 

     if let objectClassName = prop.objectClassName { 
     if let x = self[prop.name] as? Object { 
      mutabledic.setValue(x.toDictionary(), forKey: prop.name) 
     } else { 
      //problem here! 
     } 
     } 
    } 
    return mutabledic 
    } 
} 

** извините за уродливый код.

+0

вы можете предоставить нам источник на то, что вы пробовали? – Steve

ответ

1

Я думаю, что я нашел решение. Я не уверен в производительности.

extension Object { 
    func toDictionary() -> NSDictionary { 
    let properties = self.objectSchema.properties.map { $0.name } 
    let dicProps = self.dictionaryWithValuesForKeys(properties) 

    var mutabledic = NSMutableDictionary() 
    mutabledic.setValuesForKeysWithDictionary(dicProps) 

    for prop in self.objectSchema.properties as [Property]! { 

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

каждый [Свойство] (https://realm.io/docs/swift/latest/api/Classes/Property.html) имеет свойство 'type', которое является [PropertyType] (https://realm.io/docs/swift /latest/api/Typealiases.html#/s:10RealmSwift12PropertyType). Используйте его, чтобы понять, является ли ваше свойство объектом вместо поиска [...]. –

+0

Также обратите внимание на круговые ссылки: когда один объект ссылается на другой объект и наоборот. –

+0

Нет, потому что я не могу наложить объект на PropertyType. – petto

1

Я тоже новичок в Realm, но я думаю, что самый простой способ, чтобы отразить на Object's schema:

class Person: Object { 
    dynamic var name = "" 
    dynamic var age = 0 
} 

let person = Person() 

let schema = person.objectSchema 

let properties = schema.properties.map() { $0.name } 

let dictionary = person.dictionaryWithValuesForKeys(properties) // NSDictionary 

println(properties) 
println(dictionary) 
+0

Спасибо, это работает отлично, но не работает со свойствами списка как 'класса Person: Object { динамического имя вара =«» динамической переменная возраст = 0 пусть собаки = Список () }' – petto

2

Это мое решение. используйте unsafeBitCast, чтобы избежать предупреждения о сбое.

extension Object { 
    func toDictionary() -> [String:AnyObject] { 
     let properties = self.objectSchema.properties.map { $0.name } 
     var dicProps = [String:AnyObject]() 
     for (key, value) in self.dictionaryWithValuesForKeys(properties) { 
      if let value = value as? ListBase { 
       dicProps[key] = value.toArray() 
      } else if let value = value as? Object { 
       dicProps[key] = value.toDictionary() 
      } else { 
       dicProps[key] = value 
      } 
     } 
     return dicProps 
    } 
} 

extension ListBase { 
    func toArray() -> [AnyObject] { 
     var _toArray = [AnyObject]() 
     for i in 0..<self._rlmArray.count { 
      let obj = unsafeBitCast(self._rlmArray[i], Object.self) 
      _toArray.append(obj.toDictionary()) 
     } 
     return _toArray 
    } 
} 
0

Swift 4

//getRealmJSON(realmObject: Person(), realmType: Person.self) -> JSON Results 

func getRealmJSON(realmObject: Object, realmType: Any) -> String { 
    do { 
     let realm = try Realm() 
     let table = realm.objects(realmType as! Object.Type) 
     if table.count == 0 {return "Empty Table"} 
     let mirrored_object = Mirror(reflecting: realmObject) 
     var properties = [String]() 
     for (_, attr) in mirrored_object.children.enumerated() { 
      if let property_name = attr.label as String! { 
       properties.append(property_name) 
      } 
     } 
     var jsonObject = "[" 
     for i in 1...table.count { 
      var str = "{" 
      var insideStr = String() 
      for property in properties { 
       let filteredTable = table.value(forKey: property) as! [Any] 
       insideStr += "\"\(property)\": \"\(filteredTable[i - 1])\"," 
      } 
      let index = insideStr.characters.index(insideStr.startIndex, offsetBy: (insideStr.count - 2)) 
      insideStr = String(insideStr[...index]) 
      str += "\(insideStr)}," 
      jsonObject.append(str) 
     } 
     let index = jsonObject.characters.index(jsonObject.startIndex, offsetBy: (jsonObject.count - 2)) 
     jsonObject = "\(String(jsonObject[...index]))]" 
     return jsonObject 
    }catch let error { print("\(error)") } 
    return "Problem reading Realm" 
} 
Смежные вопросы