次のモデルを検討してください。
_class Person: Object {
dynamic var name = ""
let hobbies = Dictionary<String, String>()
}
_
Alamofireリクエストから取得したタイプ_[String:String]
_のオブジェクトをRealmにストックしようとしていますが、hobbies
hasがRealmSwift Documentationに従ってlet
によって定義されるため、 _List<T>
_/_Dictionary<T,U>
_種類のタイプです。
_let hobbiesToStore: [String:String]
// populate hobbiestoStore
let person = Person()
person.hobbies = hobbiesToStore
_
また、init()
を再定義しようとしましたが、常に致命的なエラーなどが発生しました。
RealSwiftで辞書を単純にコピーまたは初期化するにはどうすればよいですか?ここで些細なことを見逃していますか?
Dictionary
はレルムのプロパティタイプとしてサポートされていません。新しいクラスを導入する必要があります。そのクラスのオブジェクトは、以下に示すように、それぞれがキーと値のペアと、それに対する多対多の関係を記述します。
class Person: Object {
dynamic var name = ""
let hobbies = List<Hobby>()
}
class Hobby: Object {
dynamic var name = ""
dynamic var descriptionText = ""
}
逆シリアル化するには、JSONの辞書構造をHobbyオブジェクトにマップし、キーと値を適切なプロパティに割り当てる必要があります。
私は現在エミュレートしています。これは、辞書のJSON表現をカプセル化するプライベートで永続化されたNSDataによって裏付けられた私のモデルのDictionaryプロパティを公開します:
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"]
}
}
これは最も効率的な方法ではないかもしれませんが、 nbox を使用して、受信したJSONデータをローカルのRealmモデルにすばやく簡単にマップできます。
辞書をJSON文字列としてRealmに保存します。次に、JSONを取得し、辞書に変換します。以下の拡張機能を使用します。
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]
} }
そして
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"
}
}
}
おそらく少し非効率ですが、私のために機能します(Int-> Stringの例の辞書、あなたの例に似ています):
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[$0].val] = _values[$0].val };
return ret;
}
}
set {
_keys.removeAll()
_values.removeAll()
_keys.appendContentsOf(newValue.keys.map({ IntObj(value: [$0]) }))
_values.appendContentsOf(newValue.values.map({ StringObj(value: [$0]) }))
}
}
var _keys = List<IntObj>();
var _values = List<StringObj>();
override static func ignoredProperties() -> [String] {
return ["dict"];
}
}
レルムは文字列/整数のリストを格納できないため、これらはオブジェクトではないため、「偽のオブジェクト」を作成します。
class IntObj: Object {
dynamic var val : Int = 0;
}
class StringObj: Object {
dynamic var val : String = "";
}
同様に配列を格納するためのスタックオーバーフローに関する別の答えに触発されました(現在、ポストは私を避けています)...