考虑以下模型:
class Person: Object {
dynamic var name = ""
let hobbies = Dictionary<String, String>()
}
我正在尝试在Realm中存储我从Alamofire请求中获得的[String:String]
类型的对象,但由于hobbies
必须通过来定义let
根据RealmSwift文档,因为它是List<T>
/ Dictionary<T,U>
类型。
let hobbiesToStore: [String:String]
// populate hobbiestoStore
let person = Person()
person.hobbies = hobbiesToStore
我还尝试重新定义init()
,但总是会出现致命错误。
如何在RealSwift中简单地复制或初始化字典? 我在这里错过了一些小事吗?
答案 0 :(得分:29)
Dictionary
作为属性类型。
您需要引入一个新类,其对象描述每个类的键 - 值对和多对关系,如下所示:
class Person: Object {
dynamic var name = ""
let hobbies = List<Hobby>()
}
class Hobby: Object {
dynamic var name = ""
dynamic var descriptionText = ""
}
对于反序列化,您需要将JSON中的字典结构映射到Hobby对象,并将键和值分配给相应的属性。
答案 1 :(得分:24)
我目前通过在我的模型上公开一个被忽略的Dictionary属性来模拟这个,该属性由一个私有的持久化NSData支持,该NSData封装了一个字典的JSON表示:
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"]
}
}
它可能不是最有效的方式,但它允许我继续使用Unbox快速轻松地将传入的JSON数据映射到我的本地Realm模型。
答案 2 :(得分:4)
我会将字典保存为Realm中的JSON字符串。然后检索JSON并转换为字典。使用以下扩展名。
$ awk '{for(i=1;i<NF;i++) printf "%s%s",$i,i==NF-1 ? ORS : OFS; print ">" $NF}' file
A cars1 black
>NY
A cars2
>W
A cars3 black
>SP
和
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]
} }
答案 3 :(得分:2)
也许有点效率低下,但对我有用(来自Int-&gt; 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"];
}
}
Realm无法存储字符串/ Ints列表,因为这些不是对象,所以make&#34;假对象&#34;:
class IntObj: Object {
dynamic var val : Int = 0;
}
class StringObj: Object {
dynamic var val : String = "";
}
受到堆栈溢出的另一个答案的启发,类似地存储数组(post目前正在躲避我)......
答案 4 :(得分:0)
2021 年更新
从 Realm 10.8.0 开始,可以使用 Map
类型在 Realm 对象中存储字典。
official documentation 中的示例:
class Dog: Object {
@objc dynamic var name = ""
@objc dynamic var currentCity = ""
// Map of city name -> favorite park in that city
let favoriteParksByCity = Map<String, String>()
}