我需要在RealmSwift中表示的是以下JSON方案:
{
"id": 1234,
"title": "some value",
"tags": [ "red", "blue", "green" ]
}
它是一个我磕磕绊绊的基本字符串数组。我在Realm中猜测我需要将“标签”表示为
dynamic id: Int = 0
dynamic title: String = ""
let tags = List<MyTagObject>()
在Realm中制作标签自己的表,但是如何使用ObjectMapper映射它?这是我有多远......
func mapping(map: Map) {
id <- map["id"]
title <- map["title"]
tags <- map["tags"]
}
...但是标签行当然没有编译,因为List和Realm不能使用[String]类型。
这感觉像是一个有点常见的问题,我希望有人能够面对这个问题,可以评论或指向一个有建议的帖子。
更新1 MyTagObject如下所示:
class MyTagObject: Object {
dynamic var name: String = ""
}
更新2 我发现这个帖子处理领域对象,但假设数组有命名元素而不是简单字符串。 https://gist.github.com/Jerrot/fe233a94c5427a4ec29b
答案 0 :(得分:3)
首先,我们应该假设我们的模型同时扩展了Object
和Mappable
。
让我们创建一个包装器模型来存储基元(String
)类型:
class StringObject: Object {
dynamic var value = ""
}
然后我们描述了根模型(而不是包装器)的相应属性和映射规则:
var tags = List<StringObject>()
var parsedTags: [String] {
var result = [String]()
for tag in tags {
result.append(tag.value)
}
return result
}
override static func ignoredProperties() -> [String] {
return ["parsedTags"]
}
func mapping(map: Map) {
if let unwrappedTags = map.JSON["tags"] as? [String] {
for tag in unwrappedTags {
let tagObject = StringObject()
tagObject.value = tag
tags.append(tagObject)
}
}
}
我们需要一个tags
属性来存储和获取有关Realm标签的数据。
然后parsedTags
属性简化了通常数组格式的标记提取。
ignoredProperties
定义允许在节省数据的同时避免Realm的一些失败(因为我们当然不能在Realm中存储非Realm数据类型)。
最后,我们手动解析mapping
函数中的标签,将其存储在Realm中。
答案 1 :(得分:1)
如果您的tags数组包含带有键的Dictionary对象:“name”
,它将起作用{
"id": 1234,
"title": "some value",
"tags": [ ["name" : "red"], ... ]
}
如果您无法修改JSON对象,我建议您以编程方式将json映射到域。
for tagName in tags {
let tagObject = MyTagObject()
tagObject.name = tagName
myObject.tags.append(tagObject)
}
答案 2 :(得分:1)
我的解决方案是使用ObjectMapper TransformType
作为自定义方法,将JSON映射到Realm List<String>
类型。无需2个Realm模型。
使用示例JSON:
{
"id": 1234,
"title": "some value",
"tags": [ "red", "blue", "green" ]
}
TransformType
对象:import Foundation
import ObjectMapper
import RealmSwift
public struct StringArrayTransform: TransformType {
public init() { }
public typealias Object = List<String>
public typealias JSON = [String]
public func transformFromJSON(_ value: Any?) -> List<String>? {
guard let value = value else {
return nil
}
let objects = value as! [String]
let list = List<String>()
list.append(objectsIn: objects)
return list
}
public func transformToJSON(_ value: Object?) -> JSON? {
return value?.toArray()
}
}
import Foundation
import RealmSwift
import ObjectMapper
class MyObjectModel: Object, Mappable {
@objc dynamic id: Int = 0
@objc dynamic title: String = ""
let tags = List<MyTagObject>()
required convenience init?(map: Map) {
self.init()
}
func mapping(map: Map) {
id <- map["id"]
title <- map["title"]
tags <- (map["tags"], StringArrayTransform())
}
}
完成!
这行很神奇:tags <- (map["tags"], StringArrayTransform())
。这告诉ObjectMapper使用我们在上面显示的自定义StringArrayTransform
,它使用JSON String数组并将其转换为领域List<String>
。
答案 3 :(得分:0)
遵循此代码
import ObjectMapper
import RealmSwift
//Create a Model Class
class RSRestaurants:Object, Mappable {
@objc dynamic var status: String?
var data = List<RSData>()
required convenience init?(map: Map) {
self.init()
}
func mapping(map: Map) {
status <- map["status"]
data <- (map["data"], ListTransform<RSData>())
}
}
//Use this for creating Array
class ListTransform<T:RealmSwift.Object> : TransformType where T:Mappable {
typealias Object = List<T>
typealias JSON = [AnyObject]
let mapper = Mapper<T>()
func transformFromJSON(_ value: Any?) -> Object? {
let results = List<T>()
if let objects = mapper.mapArray(JSONObject: value) {
for object in objects {
results.append(object)
}
}
return results
}
func transformToJSON(_ value: Object?) -> JSON? {
var results = [AnyObject]()
if let value = value {
for obj in value {
let json = mapper.toJSON(obj)
results.append(json as AnyObject)
}
}
return results
}
}