Reputation: 318
I'm using RestKit to map JSON objects in my iOS project. So far everything works fine, but I'm having trouble mapping a subarray of custom types.
The JSON looks as such:
{ "Result" : "OK", "Total": "1","content": [
{"article":
{
"title": "sample_title",
"author": "sample_author",
"article_details": [
{"text":
{
"body": "sample_body",
}
},
{"image":
{
"image": "sample_image"
}
},
{"quote":
{
"quote": "sample_quote",
}
}
{"text":
{
"body": "sample_body",
}
},
]}
}]
}
Note that article_detail objects types can appear in any number or order. Futhermore, it is important to note that I need to store the order in which these objects appear, and each of its types.
To do so, and to simplify data manipulation, I auto generated two NSManagedObjects, using CoreData. Something as follows:
extension Article {
public var title: String?
public var author: String?
public var details: NSOrderedSet?
}
extension ArticleDetail {
public var body: String?
public var image: String?
public var quote: String?
}
My mappings are the following:
//Detail mapping
let detailsMapping = RKEntityMapping(forEntityForName: "ArticleDetail", in: objectManager.managedObjectStore)
detailsMapping?.addAttributeMappings(from: [
"image" : "image",
"body" : "body",
"quote" : "quote",
]
)
//Article mapping
let articleMapping = RKEntityMapping(forEntityForName: "Article", in: objectManager.managedObjectStore)
articleMapping?.addAttributeMappings(from: [
"title" : "title",
"author" : "author",
]
)
//Relation mapping
articleMapping!.addPropertyMapping(RKRelationshipMapping(fromKeyPath: "article_details.text", toKeyPath: "details", with: detailsMapping))
//Response descriptior
let articleResponseDescriptor = RKResponseDescriptor(
mapping: articleMapping,
method: RKRequestMethod.GET,
pathPattern: nil,
keyPath: "content.article",
statusCodes: IndexSet(integer: 200)
)
objectManager.addResponseDescriptor(articleResponseDescriptor)
This works fine for the article info. However, as expected, due to
fromKeyPath: "article_details.text"
it only maps "text" objects.
Identifying the type is easy, checking which parameters are nil in the article detail object.
A similar problem can be found in RestKit - Map keypath of an array to the object inside of that array
How can I accomplish this in Swift, using RestKit?
Thank you very much.
-N
Upvotes: 0
Views: 84
Reputation: 318
I managed to solve this issue yesterday. I used a class as a "wrapper" for each custom object.
So, the article simply contains an ordered set of Wrappers, saving the order if these objects, and the wrapper contains an article detail. Like so:
extension Article {
public var title: String?
public var author: String?
public var details: NSOrderedSet?
}
extension ArticleWrapper {
public var app_text: ArticleTextDetail?
public var app_image: ArticleImageDetail?
public var app_quote: ArticleQuoteDetail?
}
extension ArticleTextDetail {
...
}
extension ArticleImageDetail {
...
}
extension ArticleQuoteDetail {
...
}
The mappings look as such:
let wrapperMapping = RKEntityMapping(forEntityForName: "ArticleWrapper", in: objectManager.managedObjectStore)
let textMapping = RKEntityMapping(forEntityForName: "ArticleTextDetail", in: objectManager.managedObjectStore)
...
let imageMapping = RKEntityMapping(forEntityForName: "ArticleImageDetail", in: objectManager.managedObjectStore)
...
let quoteMapping = RKEntityMapping(forEntityForName: "ArticleQuoteDetail", in: objectManager.managedObjectStore)
...
let articleMapping = RKEntityMapping(forEntityForName: "Article", in: objectManager.managedObjectStore)
articleMapping?.addAttributeMappings(from: [
"title" : "title",
"author" : "author",
]
)
wrapperMapping!.addPropertyMapping(RKRelationshipMapping(fromKeyPath: "text", toKeyPath: "app_text", with: textMapping))
wrapperMapping!.addPropertyMapping(RKRelationshipMapping(fromKeyPath: "image", toKeyPath: "app_image", with: imageMapping))
wrapperMapping!.addPropertyMapping(RKRelationshipMapping(fromKeyPath: "quote", toKeyPath: "app_quote", with: quoteMapping))
articleMapping!.addPropertyMapping(RKRelationshipMapping(fromKeyPath: "article_details", toKeyPath: "details", with: wrapperMapping))
Everything works as intended now.
Thanks.
-N
Upvotes: 0