CoreData fetch nested objects - ios

I have a json which contain objects where each object have child object, for example
[
{
"id": 1,
"name": "obj1"
},
{
"id": 2,
"name": "obj2"
},
{
"id": 3,
"name": "obj3",
"child": {
"id": 2,
"name": "obj2"
}
},
{
"id": 4,
"name": "obj4",
"child": {
"id": 5,
"name": "obj5"
}
}
]
So in core data i have entity MyObject which has relation to child (to itself, to one), and relation to parent (to many)
So when i try fetch object by predicate like
[NSPredicate predicateWithFormat:#"parent.#count = 0"]
I got only object with id in [1,3,4], but no with id = 2 (here error) and id = 5 (here all correct), because it's was sets parent when it's mapped when object with id = 3 save to data base.
If no use predicate i got 5 object, include obj5.
But i need fetch from coredata exactly count of object what i got from json.
I need fetch only object with id in [1,2,3,4].
How do i need write predicate, if it's possible?

The data you got from JSON is a subset of all your objects, but the logic according to which it is selected is not persisted in your object model.
You persist the relationship between child and parent (hint: for readability, rename it as parents if it is to-many), but the selection in your JSON example is not based on any of those criteria.
One easy way to get all the objects is to extract the top level ids delivered by the JSON feed and use that in the predicate:
NSArray *ids = [jsonArray valueForKey:#"id"];
[NSPredicate predicateWithFormat:#"idNumber in %#", ids];
(Note that I changed your attribute name from id to idNumber in order to avoid possible language quirks, as id is a reserved word.)

Related

NSOrderedSet response from server and Core Data

I want to show data as it came from the backend So let's have an example json file:
{
"fonts": [
{
"name": "Helvetica",
"styleIdentifier": "H0",
"size": 17
},
{
"name": "Helvetica",
"styleIdentifier": "H1",
"size": 14
},
{
"name": "Helvetica-Bold",
"styleIdentifier": "H0Bold",
"size": 17
},
{
"name": "HelveticaNeue-Light",
"styleIdentifier": "H0Light",
"size": 40
}
]
}
So i create a relationship (many - many) with ordered option selected. And by the input i see it's always write in the same way to Core Data, but when I try to fetch it
configuratation.fonts where fonts is a NSOrderedSet i get items in completly random order. I miss sth in spec? Or I should sort it somehow?
__EDIT__
Firstly when i get a data from above json I have a configuration set with empty font relation. Then I fetch this and insert it into core data with:
NSMutableArray *returnArray = [NSMutableArray new];
for(NSDictionary *fontDictionary in jsonArray) {
Font *fontObj = [Font font:fontDictionary inContext:context];
[returnArray addObject:fontObj];
}
And in this array data is in correct order. Then in configuration object i add it to NSOrderedSet by:
-(void)appendTracks:(NSArray<Font*>*)fontArray {
self.fonts = [NSOrderedSet orderedSetWithArray: fontArray];
}
And then i try to fetch it by simply use reference:
configuration.fonts
And in this step data are completly not in correct order.
Do not set the NSOrderedSet directly.
Either modify the existing set:
[self.fonts addObjectsFromArray:fontArray];
Or:
Xcode generates methods to add and remove entries from ordered sets within the generated NSManagedObject class.
Assuming you have an Entity called ManagedConfiguration which holds an ordered to many relation called fonts:
ManagedConfiguration *managedObjectConfigurationInstance = //create or fetch configuration in ManagedObjectContext
NSOrderedSet<ManagedFont> *fonts = //created or fetched fonts in wanted order
managedObjectConfigurationInstance.addToFonts(fonts)
replaceFonts, removeFromFontsAtIndex aso. methods are also generated.
Depending on your requirements, you might want to store the fonts in random order and apply a NSSortDescriptor to your NSFetchRequest to fetch the data in a specific order.
Instead of trying to set the data directly to your property(fonts), you need to first fetch the mutable copy of your NSOrderedSet from the NSmanagedObject Subclass (I assume it to be Font).
NSMutableOrderedSet *orderedSet = [self mutableOrderedSetValueForKey:#"fonts"];
Then add the objects from the array to this orderedSet.
[orderedSet addObjectsFromArray:array];
Now you would have properly set the the values for the key fonts.
So your appendTracks function would now look like this.
-(void)appendTracks:(NSArray<Font*>*)fontArray {
NSMutableOrderedSet *orderedSet = [self mutableOrderedSetValueForKey:#"fonts"];
[orderedSet addObjectsFromArray:fontArray];
}
Now execute your fetch request. You should receive the data in the set order in the array.
PS:I had used your JSON response to test this.

How to create paramater(mutabledictionary) which inclued mutablearray in dictionary in ios

I have paramaters which needed to be passed in POST type.
The paramaters are
{
"couponamt": 0,
"pincode": 110093,
"proinfo":
[
{ "prodPrice": 2289,
"prodSize": "",
"proid": 41211,
"promapid": 68804,
"proname": "Spigen SGP10905 Gunmetal iPhone 6 (5.5inch) Case ",
"qty": 1,
"vendorId": 1050
},
{ "prodPrice": 6422,
"prodSize": "3X8 Feet",
"proid": 61554,
"promapid": 110886,
"proname": "Kaka Carpet K00108 Camel Tibbati Gabbeh Carpet",
"qty": 1,
"vendorId": 1066
},
{ "prodPrice": 3996,
"prodSize": "XL",
"proid": 99003,
"promapid": 162976,
"proname": "AbsurdABWS15-625GreyWomenSweatshirt",
"qty": 4,"vendorId": 885
}
],
"shipcharge": 75,
"totalAmount": 1599,
"usedwalletamount": 0
}
I want to pass this paramter with my url to create request.And it is in the form of array.Kindly revert ASAP.
Thanks
Firstly, create NSMutableDictionary with 7 keys namely prodPrice, prodSize, proid, promapid, proname, qty, vendorId.
Set desired values for your keys.
After this, create NSMutableArray and add all your dictionaries to this array.
Now create 1 final NSMutableDictionary which will be used as value for whatever parameter key your server is expecting.
In this dictionary, set your above created NSMutableArray as value for key proinfo. Similarly set values for other keys couponamt, pincode, shipcharge etc.
Finally append this dictionary with your base url.
So as far I get the original question we need to create the below structure:
- NSMutableDictionary
-NSMutableArray
-NSDictionary
- NSDictionary
You simply need to create the NSMutableArray and NSDictionary object.
Based on your requirement you can add dictionary on respective indexes in NSMutableArray, which can be collectively added in the NSMutableDictionary.

Parsing JSON in Objective C with key names as incremented integers

not really sure how to even word this question BUT I have some JSON that I need to parse which is formatted like so:-
"nodes": {
"4": {
"node_id": 4,
"title": "TITLE 1",
"description": "",
},
"7": {
"node_id": 7,
"title": "TITLE 2",
"description": "",
},
"12": {
"node_id": 12,
"title": "TITLE 3",
"description": "",
},
Normally I would grab values with the standard [dictionary objectForKey#"key"] but as the items begin with an integer (string) I am finding it hard to parse correctly. Am I missing something really simple here?
If you just want to access one value than you would do the following.
// Assume JSONObject is the "root" dictionary
NSDictionary *fourDictionary = JSONObject[#"nodes"]["4"] // This will get the object from "4":{}
Now if the JSON in question can have a dynamic number of objects than this is much trickier. The easiest solution would be to get the provider of the JSON to rewrite it as an array of objects. You could than look up the object you want using the object's node_id value.
If this is not possible than you could attempt to write a for loop to loop through all of the keys in the "nodes" object and access the items from the dictionary that way.
i.e.
NSMutableArray *arrayOfNodes = [NSMutableArray array];
NSDictionary *nodes = JSONObject[#"nodes"];
for(NSString *numberKey in [nodes allKeys])
{
NSDictionary *nodeObject = nodes[numberKey]
[arrayOfNodes addObject:nodeObject];
}
// Do anything else with the nodes now that they are in an array.

Restkit/Core Data relationship mappings, entity to same type of entity (parent/child)

I am following the Alexander Edge tutorial on RestKit 0.2.0 but I am confused about how to apply it to my needs. Specifically, I am consuming a web service that returns objects in the following structure:
{
"ObjectIdMember": 200,
"ObjectNameMember": "Baseball Bat",
"SubObjectIdMember": 4124
},
{
"ObjectIdMember": 200,
"ObjectNameMember": "Baseball Glove",
"SubObjectIdMember": 4555
},
The idea is that an Object entity can have many sub-objects. Roughly speaking, the purpose of getting the Object is to use the DisplayName to populate section headers in a table view, and group sub-objects in sections by object.
How do I capture this sort of relationship (or define it) using RestKit + Core Data? The tutorial only suggests what you might do if there is a subobject defined in the response, but this is a different situation.
I know that I could just decorate and use a subclass of Object with a -(NSArray *)getSubObjects, but Core Data would not be aware of what I was doing in the sense that this would not be using any relationships.
I believe what you want is RKConnectionDescription, which can establish a relationship in Core Data using foreign keys.
The example in the docs gives the following json:
{ "project":
{ "id": 12345,
"name": "My Project",
"userID": 1
}
}
with the following mapping configuration:
NSEntityDescription *projectEntity = [NSEntityDescription entityForName:#"Project" inManagedObjectContext:managedObjectContext];
NSRelationshipDescription *userRelationship = [projectEntity relationshipsByName][#"user"];
RKConnectionDescription *connection = [[RKConnectionDescription alloc] initWithRelationship:userRelationship attributes:#{ #"userID": #"userID" }];

Indexing an NSMutableDictiobary?

I have an NSMutableDictionary which holds objects of string type like this:
{
{
{"ID":"23"},
{"NAME":"Ted"}
},
{
{"ID":"46"},
{"NAME":"Karren"}
},
{
{"ID":"6"},
{"NAME":"Phillip"}
}
}
I need a way to access object with ID #x in an indexed manner.
Now, since the object with ID=46 is in index #1
I need a way to make the dictionary still have it's objects in their index as it is, but is it possible to add a key to that object?
Like:
"6":"{
{"ID":"6"},
{"NAME":"Phillip"}
}"
If possible to show some code.
Otherwise, how can I do that another way.
Thanks
What about using predicates ?
NSArray *resultArray = [[[myDictionary allValues] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"ID == %#", #"6"]];
you retrieve all your dictionary values, and use a predicate to return a single element array with the value you were looking for
(code not tested but should work)
First of all you need to do something with the strucutre,
[
{
"ID": 23,
"Name": "Ted"
},
{
"ID": 46,
"Name": "Karen"
},
{
"ID": 6,
"Name": "Philip"
}
]
This would make your work a lot easier. You can search/sort it based on ID or Name easily.
//All users array
NSArray *users = ....
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"ID = %d",userID];
//Find User against a user id
NSDictionary *user = [[users filteredArrayUsingPredicate:predicate] lastObject];

Resources