I was just trying to parse a JSON-Object which includes a 2-dimensional array.
Example:
{
"2dimarray": [
[{"key": "val"}, {"key": "val"}],
[{"key": "val"}, {"key": "val"}]
]
}
Assuming the contents of 2dimarray[x][y] are only of one type, I added the mapping:
[objectMapping mapKeyPath:#"2dimarray" toRelationship:#"2dimarray" withMapping: myMappingForIncludedObjects];
In the log RestKit tells me:
W restkit.object_mapping:RKObjectMappingOperation.m:438 WARNING: Detected a relationship mapping for a collection containing another collection. This is probably not what you want. Consider using a KVC collection operator (such as #unionOfArrays) to flatten your mappable collection.
But actually it is what I want. Basicly I assumed that the object mapper would fill my Objective-C property NSArray* 2dimarray with NSArray*s that include objects that are mapped with myMappingForIncludedObjects. Instead, each array is mapped (which fails, of course) with myMappingForIncludedObjects.
What am I doing wrong? Or better: What do I need to do to archive the behavior I expected?
I believe that the issue you cite is Blake explaining the problem, not a solution. I don't think RestKit is set up to handle the mapping that you describe (an array of arrays of objects). You can walk through an example of what he describes in the issue as well as looking at his commit, and you'll see that the introduced logic was aimed at detecting the problem and logging it for debugging purposes.
Related
I'm new to Swift and I have to serialize an object structure into a JSON string in my iOS( iOS >= 8) project.
So I decided to use the ObjectMapper library (I integrated it with Cocoapod).
But my problem is that the structure is the following.
ObjectA can have a list of children objects as an array stored in an instance variable.
Objects that can be stored in the instance array can be of multiple types, say ObjectB and ObjectC. So, in Java with GSON I would have created an InterfaceD and made both of my classes implement it and made the array in ObjectA store InterfaceD types, but I can't figure how to do this with Swift object model as it results in empty {} JSON objects.
The resulting JSON should look like this.
{"children":[
{"type":"ObjectB", "value1":"foo"},
{"type":"ObjectC", "value1":"bar", "value2":"baz"}
]}
and I get
{"children":[
{},
{}
]}
Notice that the two entries that have to be serialized from objectA and ObjectC should have different structures.
I tried multiple things but each times I'm stuck in a dead end.
I tried using generics, tried to use Mappable protocol as my array type, I tried classic class inheritence but any one failed.
Have you any idea how I can achieve this ?
Note that I know that I could add a serialization function to each object and retrieve the strings recursively and concatenate them. But I really want to avoid implementing a JSON serializer by myself as I already use on successfully as Alamofire is already used in the project). Also implementing a new serializer is error prone and not a clean way to solve the problem IMO.
Thanks a lot.
I never had the solution but as a workaround I just made my objects produce a dictionnary from all its values. Then I recursively add child objects dictionnaries as the current dictionnary values.
It adds a toDict() function to each object that I forced with a protocol.
When the resulting object is only made of a tree of dictionnaries, the ObjectMapper serialization works fine...
I have a data structure that looks like following:
I'm trying to map it. I will have array of DayChoice objects.
Each of them contains index and string properties.
Now I face trouble with writing mapping, usually it goes like this:
But as you can see my DayChoice objects do not have keys, and are in arrays. How do I write mapping for this?
For anyone finding this, this seems to have been resolved in Realm-JSON #88.
So long story short, there's a discrepancy between the output of a NSMutableDictionary's contents and the result of calling allValues on the same object. Below is some debugger output after inspecting the object which demonstrates my problem: (made generic of course)
(lldb) po self.someDict.allKeys
<__NSArrayI 0xa5a2e00>(
<SomeObject: 0xa5a2dc0>,
<SomeObject: 0xa5a2de0>
)
(lldb) po self.someDict.allValues
<__NSArrayI 0xa895ca0>(
0.5,
0.5
)
(lldb) po self.someDict
{
"<SomeObject: 0xa5a2dc0>" = (null);
"<SomeObject: 0xa5a2de0>" = (null);
}
So as we can see, the actual output of the NSMutableDictionary contains null values for both its entries, but the contents of .allValues contains the proper data. These three outputs were taken at the same time in execution.
I'm not sure why this is happening, but I think it may have something to do with the fact that I'm encoding/decoding the object which this dictionary is a property of using CoreData. I believe I'm doing this properly:
[aCoder encodeObject:self.someDict forKey:#"someDict"];
and to decode
self.someDict = [aDecoder decodeObjectForKey:#"someDict"];
The weird thing is that if I inspect the dictionary before it ever gets encoded, it is still in the state described at the beginning of the post, so this is why I'm doubtful the CoreData actions are screwing with the contents.
As always, please don't hesitate to request additional information.
EDIT: The problem was as answered below. I was using a custom class which didn't cooperate with isEqual, so my solution was to change the storage and structure of my logic, which made using a Dictionary unnecessary.
I have not been able to duplicate the problem using NSString as keys and NSNumber as values. I suspect that your custom class does not properly implement hash and/or isEqual. Specifically, the results from those two methods must be consistent, meaning that if isEqual returns true, then the hash values for the two objects must be identical.
You also need to ensure that your class implements NSCopying properly and that a copy is equal to the original.
As a general rule, don't use custom objects for dictionary keys. Just use strings and be done with it.
As user3386109 points out, custom objects must properly implement the -hash and -isEqual methods in order to be used as dictionary keys, and even then, custom objects don't work correctly for dictionary keys for things like key/value coding.
I am using RestKit in my app, which needs to use an existing synchronization service that structures the incoming data this way:
{
"timestamp": 000000000001,
"status" : 0,
"syncData":[
{
"errors":[],
"rows":[ {"name":"AAA", ...},
{"name":"BBB", ...},
...],
"rtype":"FOO" },
{
"errors":[],
"rows":[ {"id":1, "description":"ZZZ", ....},
{"id":2, "description":"YYY", ....},
...],
"rtype":"BAR"
}, ...
I'm new to RestKit and trying to figure out the best way to solve this problem, and the complementary problem of sending this same structure of data back to the server. I'm using Core Data with RestKit.
I've mapped a SyncResponse entity to hold the top level data, and what I want to get out of this is a collection of FOO objects, "AAA", "BBB", etc., and a collection of BAR objects, "ZZZ", "YYY", etc., and a few dozen other collections of objects whose Class is indicated by the "rtype" field.
I've read the doc section on dynamic mapping and some example code and postings here, but I don't see how dynamic mapping works in this case as it is not of the {"a":{is A}, "b":{is B}} format. Is this possible using dynamic mapping, and if so, what concepts am I missing here?
Assuming it is possible, how do I, starting with collections of FOOs and BARs send data back, of course replacing the SyncResponse with something like a SyncUpdateRequest wrapper?
I don't think you'll be able to do this using a set of mappings alone.
Your best option may be to create your mappings for each item and one for the overall structure. The overall mapping just extracts the array as an NSArray of dictionaries. Once you have the array you can iterate over it yourself, check the type and then apply an RKMapperOperation to perform the mappings.
For sending your update request, I'd look at it as a quite separate thing. I'd build an array of dictionaries where the dictionaries have 'plain' key / value pairs for some information and 'complex' key / value pairs for the rows. Your request mapping is then in terms of this array of dictionaries (which cover the custom parts) and the rows (which should be the inverse of your response mapping for the class). Then RestKit should be able to handle it in the standard way (compared to the complexity of your response mapping above).
Right now I am using ArrayCollection. But I want to change that to Set as I want make sure do duplicate values come.
var addressList:ArrayCollection = new ArrayCollection();
One way is I can use Dictionary and store addresses as a key. And I can just use keys to iterate.
But I am looking for Java HashSet like implementation.
You want to download Polygonal Data Structures. The swc contains a HashSet. If you want Java-style template syntax for Flash, you should also check out Haxe.
The AS3 equivalent to HashMap or HashSet is the Dictionary class, and to a lesser extent, the Object class. Object keys are stored as strings, while with Dictionary the keys are objects. You can't have duplicate entries with either. Are you looking for a specific implementation other than that?