Comment puis-je stocker un dictionnaire avec RealmSwift?
Considérant le modèle suivant:
class Person: Object {
dynamic var name = ""
let hobbies = Dictionary<String, String>()
}
j'essaie de stocker dans le domaine un objet de type [String:String]
que j'ai obtenu à partir d'un Alamofire demande, mais ne peut pas car hobbies
a à définir par let
selon la Documentation RealmSwift puisque c'est un List<T>
/Dictionary<T,U>
type de type.
let hobbiesToStore: [String:String]
// populate hobbiestoStore
let person = Person()
person.hobbies = hobbiesToStore
j'ai aussi essayé de redéfinir init()
mais se retrouvait toujours avec une erreur fatale ou autrement.
Comment puis-je simplement copier ou initialiser un Un dictionnaire dans RealSwift? Est-ce que je manque quelque chose de banal ici?
4 réponses
Dictionary
n'est pas supporté en tant que type de propriété dans Realm.
Vous aurez besoin d'introduire une nouvelle classe, dont les objets décrivent chacun une clé-valeur-paire et à-beaucoup de relation à cela comme vu ci-dessous:
class Person: Object {
dynamic var name = ""
let hobbies = List<Hobby>()
}
class Hobby: Object {
dynamic var name = ""
dynamic var descriptionText = ""
}
pour la desérialisation, vous aurez besoin de mapper votre structure de dictionnaire dans votre JSON aux objets de passe-temps et assigner la clé et la valeur à la propriété appropriée.
je suis actuellement l'émulation ceci en exposant une propriété de dictionnaire ignorée sur mon modèle, soutenue par un privé, a persisté NSData qui encapsule une représentation JSON du dictionnaire:
class Model: Object {
private dynamic var dictionaryData: NSData?
var dictionary: [String: String] {
get {
guard let dictionaryData = dictionaryData else {
return [String: String]()
}
do {
let dict = try NSJSONSerialization.JSONObjectWithData(dictionaryData, options: []) as? [String: String]
return dict!
} catch {
return [String: String]()
}
}
set {
do {
let data = try NSJSONSerialization.dataWithJSONObject(newValue, options: [])
dictionaryData = data
} catch {
dictionaryData = nil
}
}
}
override static func ignoredProperties() -> [String] {
return ["dictionary"]
}
}
Il pourrait ne pas être le moyen le plus efficace mais il me permet de continuer à utiliser Unbox pour mapper rapidement et facilement les données entrantes de JSON à mon modèle local de domaine.
je sauverais le dictionnaire comme chaîne JSON dans Realm. Ensuite, récupérez le JSON et convertissez-vous en Dictionnaire. Utilisez les extensions ci-dessous.
extension String{
func dictionaryValue() -> [String: AnyObject]
{
if let data = self.data(using: String.Encoding.utf8) {
do {
let json = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments) as? [String: AnyObject]
return json!
} catch {
print("Error converting to JSON")
}
}
return NSDictionary() as! [String : AnyObject]
} }
et
extension NSDictionary{
func JsonString() -> String
{
do{
let jsonData: Data = try JSONSerialization.data(withJSONObject: self, options: .prettyPrinted)
return String.init(data: jsonData, encoding: .utf8)!
}
catch
{
return "error converting"
}
}
}
peut-être un peu inefficace, mais fonctionne pour moi (exemple de dictionnaire D'Int - >chaîne, analogue pour votre exemple):
class DictObj: Object {
var dict : [Int:String] {
get {
if _keys.isEmpty {return [:]} // Empty dict = default; change to other if desired
else {
var ret : [Int:String] = [:];
Array(0..<(_keys.count)).map{ ret[_keys[].val] = _values[].val };
return ret;
}
}
set {
_keys.removeAll()
_values.removeAll()
_keys.appendContentsOf(newValue.keys.map({ IntObj(value: []) }))
_values.appendContentsOf(newValue.values.map({ StringObj(value: []) }))
}
}
var _keys = List<IntObj>();
var _values = List<StringObj>();
override static func ignoredProperties() -> [String] {
return ["dict"];
}
}
Realm ne peut pas stocker une liste de chaînes / Ints parce que ce ne sont pas des objets, alors faites des "faux objets":
class IntObj: Object {
dynamic var val : Int = 0;
}
class StringObj: Object {
dynamic var val : String = "";
}
inspiré par une autre réponse ici sur le débordement de la pile pour stocker des tableaux de manière similaire (post m'échappe actuellement)...