我正在使用Alamofire,Objectmapper,Realm,一切都在一件事情上:我无法映射嵌套对象。
class Voting: Object, Mappable {
dynamic var votingID: String = ""
dynamic var question: String = ""
var votingOptions = List<VotingOption>()
required convenience init?(_ map: Map) {
self.init()
}
func mapping(map: Map) {
votingID <- map["id"]
question <- map["question"]
votingOptions <- map["votingOptions"]
}
override class func primaryKey() -> String {
return "votingID"
}
}
class VotingOption: Object, Mappable{
dynamic var optionID: String = ""
dynamic var text: String = ""
required convenience init?(_ map: Map) {
self.init()
}
func mapping(map: Map) {
optionID <- map["id"]
text <- map["optionText"]
}
override class func primaryKey() -> String {
return "optionID"
}
}
我试图映射的JSON是:
{
"Voting": [
{
"question": "Which option do yo prefer?",
"id": "7f073efd-6f3d-43f2-9fe4-5cad683b77a2",
"votingOptions": [
{
"optionText": "Option 3",
"id": "3bc0a618-8791-4862-a7fd-5f2df464697d"
},
{
"optionText": "Option 1",
"id": "84c6a830-814b-40c8-a252-c074be5d689a"
},
{
"optionText": "Option 2",
"id": "8872ef6f-fc70-445a-802e-d39944006467"
}
]
}
]
}
VotingOption中的映射功能永远不会被调用。
答案 0 :(得分:4)
旧的ListTransform
解决方案在Swift 3中不再有效。
这就是我现在正在使用的;例如,将其放在名为ListExtensions.swift
的文件中。
import Foundation
import ObjectMapper
import RealmSwift
/// Maps object of Realm's List type
func <- <T: Mappable>(left: List<T>, right: Map)
{
var array: [T]?
if right.mappingType == .toJSON {
array = Array(left)
}
array <- right
if right.mappingType == .fromJSON {
if let theArray = array {
left.append(objectsIn: theArray)
}
}
}
这允许您像这样简单地使用它:
class Parent: Object, Mappable {
dynamic var id: Int = 0
var children = List<Child>()
required convenience init?(_ map: Map) {
self.init()
}
func mapping(map: Map) {
id <- map["id"]
children <- map["children"]
}
}
答案 1 :(得分:3)
您遇到的问题是由于ObjectMapper不了解Realm的List
类型。它不知道它是一个集合类型,它必须在适当的位置进行变异而不是被分配。您可以在ObjectMapper GitHub issue #143中看到对此的讨论,包括一些建议的解决方法。
另请注意,List
子类上的任何Object
属性都应使用let
而不是var
声明。
答案 2 :(得分:3)
qs = Article.objects.all()
qs = qs.extra(select = {
'recent_comments': """
SELECT
json_build_object('comments',
array_agg(
json_build_object('id', id, 'user_id', user_id, 'body', body)
)
)
FROM (
SELECT
c.id,
c.user_id,
c.body
FROM app_comment c
WHERE c.article_id = app_article.id
ORDER BY c.id DESC
LIMIT 3
) sub
"""
})
for article in qs:
print(article.recent_comments)
# Output:
# {u'comments': [{u'user_id': 1, u'id': 3, u'body': u'foo'}, {u'user_id': 1, u'id': 2, u'body': u'bar'}, {u'user_id': 1, u'id': 1, u'body': u'joe'}]}
# ....
然后在你的模型中这样的事情。
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
}
}
答案 3 :(得分:-1)
您可以使用像:
这样的运算符函数扩展Realm.List类型的ObjectMapperpublic func <- <T: Object where T: Mappable, T: JSPrimaryKey>(left: List<T>, right: Map) {
if right.mappingType == MappingType.FromJSON {
if let value = right.currentValue {
left.removeAll()
if let json = value as? [[String : AnyObject]] {
let objs = RealmS().add(T.self, json: json)
left.appendContentsOf(objs)
}
}
}
}
试试自己。