JSON Parsing of ios - ios

I am trying to parse the below JSON but am not getting the data from this JSON.
In the below JSON I am trying to fetch choices but its not getting with my below code
NSString *filePathChoices = [[NSBundle mainBundle] pathForResource:#"questions" ofType:#"json"];
NSData *JSONDataChoices = [NSData dataWithContentsOfFile:filePathChoices options:NSDataReadingMappedIfSafe error:nil];
NSMutableDictionary *jsonObjectChoices = [NSJSONSerialization JSONObjectWithData:JSONDataChoices options:NSJSONReadingMutableContainers error:nil];
NSArray *arrayChoices = [jsonObjectChoices objectForKey:#"choices"];
//NSDictionary *jsonDict = [arrayChoices objectAtIndex:indexPath.row];
cell.textLabel.text = [arrayChoices objectAtIndex:indexPath.row];
From this below JSON i am fetching the choices into tableview
{
"questions": [
{
"question": "1. An ITM option has is priced at $3.00. The strike is at $20 and the underlying is trading at $19. What is the extrinsic value of the option?",
"choices": ["Ontario","New Brunswick","Manitoba","Quebec"],
"correctAnswer": 0
},
{
"question": "2. True or False. If a trader is long some calls and long some puts, he is likely to be?",
"choices": ["Ontario", "New Brunswick", "Nova Scotia", "Quebec"],
"correctAnswer": 3
},
{
"question": "3. Which of these provinces start with 'New'?",
"choices": ["Ontario", "New Brunswick", "Quebec", "Manitoba"],
"correctAnswer": 1
},
{
"question": "4. Which of these begin with the word 'Man'?",
"choices": ["Ontario", "New Brunswick", "Quebec", "Manitoba"],
"correctAnswer": 3
},
{
"question": "5. Which of these begin with the word 'Nova'?",
"choices": ["Ontario", "Nova Scotia", "British Columbia", "New Brunswick"],
"correctAnswer": 1
},
]
}

Choice is not on the top level.
So if you data structure is exactly as you've described it, you first need to get a question, and then get choice on this question.
Example:
NSArray *questions = [jsonObjectChoices objectForKey:#"questions"];
Now, get a question (here we take the first one)
NSDictionnary *question=[questions objectAtIndex:0]
And then, if you want to get the choices for this question
NSArray *choices=[question objectForKey:#"choices"];

you can't directly dispaly the array of values in cell. Replace the code with below code to solve it
NSString *filePathchoice = [[NSBundle mainBundle] pathForResource:#"questions" ofType:#"json"];
NSData *JSONData = [NSData dataWithContentsOfFile:filePathchoice options:NSDataReadingMappedIfSafe error:nil];
NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:JSONData options:NSJSONReadingMutableContainers error:nil];
NSArray *array = [jsonObject objectForKey:#"questions"];
questions = [[NSMutableArray alloc] initWithCapacity:[array count]];
for (NSDictionary *dict in array) {
question = [[Question alloc] initWithObject:dict];
[questions addObject:question];
}
cell.textLabel.text = [choices objectAtIndex:indexPath.row];
cell.textLabel.font=[UIFont fontWithName:#"Bold" size:12];

Your json is not vaild modify your json file as below and try
{
"questions": [
{
"question": "1. An ITM option has is priced at $3.00. The strike is at $20 and the underlying is trading at $19. What is the extrinsic value of the option?",
"choices": [
"Ontario",
"New Brunswick",
"Manitoba",
"Quebec"
],
"correctAnswer": 0
},
{
"question": "2. True or False. If a trader is long some calls and long some puts, he is likely to be?",
"choices": [
"Ontario",
"New Brunswick",
"Nova Scotia",
"Quebec"
],
"correctAnswer": 3
},
{
"question": "3. Which of these provinces start with 'New'?",
"choices": [
"Ontario",
"New Brunswick",
"Quebec",
"Manitoba"
],
"correctAnswer": 1
},
{
"question": "4. Which of these begin with the word 'Man'?",
"choices": [
"Ontario",
"New Brunswick",
"Quebec",
"Manitoba"
],
"correctAnswer": 3
},
{
"question": "5. Which of these begin with the word 'Nova'?",
"choices": [
"Ontario",
"Nova Scotia",
"British Columbia",
"New Brunswick"
],
"correctAnswer": 1
}
] }

The go to library I use in my projects is JsonModel.
Example one line request to get the json.
[JSONHTTPClient postJSONFromURLWithString:#"http://example.com/api"
params:#{#"postParam1":#"value1"}
completion:^(id json, JSONModelError *err) {
//check err, process json ...
}];
For this json :
{
"order_id": 104,
"total_price": 103.45,
"products" : [
{
"id": "123",
"name": "Product #1",
"price": 12.95
},
{
"id": "137",
"name": "Product #2",
"price": 82.95
}
]
}
You only need to subclass JSONModel and add this to your .h file :
#protocol ProductModel
#end
#interface ProductModel : JSONModel
#property (assign, nonatomic) int id;
#property (strong, nonatomic) NSString* name;
#property (assign, nonatomic) float price;
#end
#implementation ProductModel
#end
#interface OrderModel : JSONModel
#property (assign, nonatomic) int order_id;
#property (assign, nonatomic) float total_price;
#property (strong, nonatomic) NSArray<ProductModel, ConvertOnDemand>* products;
#end
#implementation OrderModel
#end
Advantages JSONModel :
One line fetches for json / or you can choose another fetch method.
Easily convert JSONModel objects to / from NSDictionary, text.
Optional parameters, direct conversion to the data types you specify
and custom error handling and many more.
Installation :
Clone source, copy paste the JSONModel folder into your project.
Subclass JSONModel, add the matching properties from json to your
header file (be careful, if your json is potentially malformatted,
you should use the parameter that instructs the framework
that in your json, these could be null or missing).
Fetch and parse your json like in your above example, and then test
all of the properties for inconsistencies.
In your example, you have a "," in plus, just before "]"
The corrected code :
{
"questions": [
{
"question": "1. An ITM option has is priced at $3.00. The strike is at $20 and the underlying is trading at $19. What is the extrinsic value of the option?",
"choices": [
"Ontario",
"New Brunswick",
"Manitoba",
"Quebec"
],
"correctAnswer": 0
},
{
"question": "2. True or False. If a trader is long some calls and long some puts, he is likely to be?",
"choices": [
"Ontario",
"New Brunswick",
"Nova Scotia",
"Quebec"
],
"correctAnswer": 3
},
{
"question": "3. Which of these provinces start with 'New'?",
"choices": [
"Ontario",
"New Brunswick",
"Quebec",
"Manitoba"
],
"correctAnswer": 1
},
{
"question": "4. Which of these begin with the word 'Man'?",
"choices": [
"Ontario",
"New Brunswick",
"Quebec",
"Manitoba"
],
"correctAnswer": 3
},
{
"question": "5. Which of these begin with the word 'Nova'?",
"choices": [
"Ontario",
"Nova Scotia",
"British Columbia",
"New Brunswick"
],
"correctAnswer": 1
}
]
}
The model that you can use to parse this :
#interface QuestionsFetch : JSONModel
#property (strong, nonatomic) NSArray<QuestionModel>* questions;
#protocol QuestionModel #end
#interface QuestionModel : JSONModel
#property (strong, nonatomic) NSString* question;
#property (strong, nonatomic) NSArray<ChoicesModel>* choices;
#protocol ChoicesModel #end
#interface ChoicesModel : JSONModel
#property (strong, nonatomic) NSArray* choice;
If you have any problems with importing / parsing, leave a comment.

Related

How to update existing object with partial data in restkit?

I have get API which returns following data
{
"id": "45832",
"name": "test name",
"parentId":"xyz",
//other fields
}
I am able to save this data using restkit. I have another api to get changes which returns only updated fields. for example
{
"id": "45832",
"name": "test name2",
//other updated fields
}
I want this data to update existing object in db. But in my case it sets parentId and other missing attributes to null. I have set identification attribute in entity mapping.
EDIT:
Here is the class for managed object with entity mapping.
#import "ZEntity.h"
#import "ZContent.h"
#import "ZThumb.h"
#implementation ZEntity
#dynamic availableFrom;
#dynamic dueDate;
#dynamic entityId;
#dynamic name;
#dynamic perCompleted;
#dynamic state;
#dynamic type;
#dynamic thumb;
#dynamic contents;
#dynamic completedOn;
#dynamic totalScore;
#dynamic parent;
#dynamic settings;
+ (RKEntityMapping *)map{
RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([self class]) inManagedObjectStore:[RKManagedObjectStore defaultStore]];
mapping.persistentStore = [RKManagedObjectStore defaultStore].persistentStoreCoordinator.persistentStores.firstObject;
NSAssert(mapping.persistentStore != nil, #"Requires Persistent Store");
mapping.identificationAttributes = #[#"entityId"];
[mapping addAttributeMappingsFromDictionary:#{
#"id" : #"entityId",
#"type" : #"type",
#"name" : #"name",
#"dueDate" : #"dueDate",
#"state" : #"state",
#"availableFrom" :#"availableFrom",
#"percCompletion" : #"perCompleted",
#"completedOn" : #"completedOn",
#"totalScore" : #"totalScore"
}];
[mapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"thumb" toKeyPath:#"thumb" withMapping:[ZThumb map]]];
return mapping;
}
#end
Response descriptor
RKResponseDescriptor* entitiesD = [RKResponseDescriptor responseDescriptorWithMapping:[ZEntity map]
method:RKRequestMethodAny pathPattern:nil keyPath:#"objects"
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
Json response
{
"total": 9,
"start": 1,
"count": 10,
"objects": [{
"id": "636488166759829858",
"type": "UPDATE",
"name": "copy1",
"canReattempt": false,
"score": 0,
"totalScore": 300,
"thumb": {
"id": "THUMB_QUPDATE4",
"expiry": 1472545125,
"url_180_120": "//s3-ap-southeast-1.amazonaws.com/mtgame-cdn.mindtickle.com/allaboard4.0/thumb/Q-Update-Thumbnail_04.png?AWSAccessKeyId=AKIAJYDLQOOEIA6NZLPQ&Expires=1472545125&Signature=To8a5SN7CoCiWDmmtXLkyANKulw%3D"
},
"dueDate": 1440845008,
"dueDateObj": {
"dueOn": 1440845008,
"dueDateExpiryAction": "NONE"
},
"state": "ACTIVE",
"percCompletion": 0.0,
"availableFrom": 1440585808,
"completedOn": 0,
"startTime": null,
"expiryTime": null,
"certificateCutOffScore": -1,
"lastPublishTime": 1440585653,
"completionCertificateEnabled": null
}]
}
In earlier calls I have set parent field for Entity class which is a relationship (I have verified this through sqlite browser too). In this json there is no parent returned. Once this call finished, parent is set to null. I have to keep existing parent value.

Map array of objects in array of parent objects

I am having trouble mapping an array of objects (comments) in array of parent objects (requests) from JSON via RestKit's mapping functionality.
All my data returns properly, but for some reason the comment objects are never populated!
See my code below:
request.json:
{
"data": {
"priorityRequests": [
{
"id": 123456,
"title": "Request 1",
"comments": [
{
"author": "John Smith",
"content": "This is a comment"
}, {
"author": "Jane Smith",
"content": "This is another comment"
}
]
}, {
"id": 654321,
"title": "Request 2",
"comments": [
{
"author": "John Smith",
"content": "This is a comment"
}, {
"author": "Jane Smith",
"content": "This is another comment"
}
]
}
]
}
}
Comment.h/m
#interface Comment : NSObject
#property ( strong, nonatomic ) NSString *author;
#property ( strong, nonatomic ) NSString *content;
#end
#implementation Comment
#end
Request.h/m
#import "Request.h"
#interface Request : NSObject
#property ( strong, nonatomic ) NSString *id;
#property ( strong, nonatomic ) NSString *title;
#property ( strong, nonatomic ) Comment *comments;
#end
#implementation Request
#end
RequestManager.m snippet
RKObjectMapping *requestMapping = [ RKObjectMapping mappingForClass: [ Request class ] ];
[ requestMapping addAttributeMappingsFromDictionary:#{
#"id" : #"id",
#"title" : #"versionNumber"
}];
RKObjectMapping *commentMapping = [ RKObjectMapping mappingForClass: [ Comment class ] ];
[ commentMapping addAttributeMappingsFromDictionary:#{
#"title": #"title",
#"author": #"author"
}];
// Failed attempt 1:
[ requestMapping addPropertyMapping: [ RKRelationshipMapping
relationshipMappingFromKeyPath: #"comments"
toKeyPath: #"comments"
withMapping: commentMapping ]
];
// end
// Failed attempt 2:
RKRelationshipMapping* requests_comments = [ RKRelationshipMapping
relationshipMappingFromKeyPath: #"comments"
toKeyPath: #"comments"
withMapping: commentMapping
];
[ requestMapping addPropertyMapping: requests_comments ];
// end
RequestCommunicator.m snippet
NSDictionary *mappingsDictionary = #{ "data.priorityRequest" : requestMapping };
RKMapperOperation *mapper = [ [ RKMapperOperation alloc ]
initWithRepresentation: parsedData // parsed json as above
mappingsDictionary: mappingsDictionary
];
NSError *mappingError = nil;
BOOL isMapped = [ mapper execute: &mappingError ];
// If no errors, returned array of mapped objects
if (isMapped && !mappingError) {
// All data except for comments here
// _comments = (Comment *) nil
[ self.delegate receivedResponseObject: [ mapper mappingResult ].array ];
... etc.
I found a fix to this issue, and although it might not be everyone's cup of tea, hopefully it can help someone else down the track.
In my Requests NSObject, I changed the mapping from type 'Comment' to 'NSArray':
- #property ( strong, nonatomic ) Comment *comments;
+ #property ( strong, nonatomic ) NSArray *comments;

iOS parse string with multiple JSON objects?

I'm having some troubles when my app receives multiple JSON objects at the same time. I'm using a TCP socket that is open to my server which sends me messages. The reason i seem to recieve multiple messages is probably due to network lag.
This is what a server message can look like (i then put this into a NSString and try to parse the JSON):
{
"id": "156806",
"type": "message",
"userCity": "",
"userCountry": "",
"os": "",
"browser": "",
"trafficType": "",
"seKeyword": "",
"seType": "",
"currentPage": "",
"userId": "1",
"agentId": "352",
"customField1": "",
"visitorNick": "Visitor 147220060",
"msg": "asd",
"time": "16:05",
"channel": "V147220060",
"visits": "254"
} {
"type": "previewStopped",
"msg": "",
"visitorNick": "Mackan",
"customField1": "",
"visitorNick": "Visitor V147220060",
"time": "16:05",
"channel": "V147220060"
} {
"id": "156807",
"type": "message",
"userCity": "",
"userCountry": "",
"os": "",
"browser": "",
"trafficType": "",
"seKeyword": "",
"seType": "",
"currentPage": "",
"userId": "1",
"agentId": "352",
"customField1": "",
"visitorNick": "Visitor 147220060",
"msg": "as",
"time": "16:05",
"channel": "V147220060",
"visits": "254"
} {
"id": "156808",
"type": "message",
"userCity": "",
"userCountry": "",
"os": "",
"browser": "",
"trafficType": "",
"seKeyword": "",
"seType": "",
"currentPage": "",
"userId": "1",
"agentId": "352",
"customField1": "",
"visitorNick": "Visitor 147220060",
"msg": "da",
"time": "16:05",
"channel": "V147220060",
"visits": "254"
}
And here is how i currently parse the NSString, note that the above JSON is outputData in the code below:
// Parse the message from the server
NSError* error;
NSDictionary *JSON =
[NSJSONSerialization JSONObjectWithData: [outputData dataUsingEncoding:NSUTF8StringEncoding]
options: NSJSONReadingMutableContainers
error: &error];
NSString* type = [JSON objectForKey:#"type"];
if(error) {
NSLog(#"PARSE ERROR ------------->>>>> : %#\n", error);
}
NSLog(#"SERVER TYPE --> %#\n", type);
if([type isEqualToString:#"message"]) {
[self messageReceived:outputData];
}
The above works perfectly when i only recieve one JSON in outputData but when multiple JSONs are recieved it trows an error:
PARSE ERROR ------------->>>>> : Error Domain=NSCocoaErrorDomain
Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)"
(Garbage at end.) UserInfo=0x14e9acb0 {NSDebugDescription=Garbage at
end.}
Any ideas how to handle this?
Hmm...you could wrap it yourself. Take the data you get and prepend "{ "dataarray": [" to the beginning, and "] }" to the end. This will produce an array, the elements of which will be your individual JSON entities.
Try this:
NSData *jsonData = [outputData dataUsingEncoding:NSUTF8StringEncoding];
NSArray *dict = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&e];
NSDictionary *JSON = [dict objectAtIndex:0];
NSString* type = [JSON objectForKey:#"type"];
EDIT:
An example of JSON, because your "" can cause problems:
{
aula = "AULA M04";
cuatrimestre = "Primer quadrimestre";
dia = Dimecres;
edificio = "AULARI V";
fin = "18:00";
inicio = "15:00";
}
Hope it helps!
It's erroring out because you don't have valid JSON in your string. You'll need to do something like the following to get it into the correct format:
NSString *formattedString = [NSString stringWithFormat:#"[%#]", [outputData stringByReplacingOccurrencesOfString:#"} {" withString:#"},{"]];
NSError *error = nil;
NSArray *JSON = [NSJSONSerialization JSONObjectWithData:[formattedString dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:&error];
That is assuming outputData is an NSString.
If your data stream contains multiple JSONs in sequence, it strictly isn't JSON anymore. Rather, it is a custom protocol which embeds JSON.
You need to first define your custom protocol. It can be defined as an arbitrary number of JSONs in sequence - if this fits your needs. NSJSONSerialization isn't capable to parse your custom protocol, though.
You could define your protocol differently, for example: your data is a contiguous stream of messages, where a message is a "blob" prepended by value representing the length in bytes, e.g.:
message := message_size CRLF blob
message_size := digits
data := message*
That is, your data may look as follows:
2\n\r[]4\n\r5["a"]
This is of course a pretty naive protocol, but it should be sufficient to demonstrate the basic idea.
Your blob could then be JSON UTF-8.
This "protocol" can be easily parsed with a custom parser, where the "blob" (a single JSON) will be passed through a JSON parser, possibly wrapped into a NSData object.

Get NSArray/NSDictionary for Nested JSON

I have this JSON :
{
"_id" : "class_1",
"schedule" : [
{
"date" : "1-1-2014",
"subjects" : [
{
"time_range" : "08:00-10:00",
"subject" : "Sports"
},
{
"time_range" : "10:00-12:00",
"subject" : "History"
}
]
},
{
"date" : "2-1-2014",
"subjects" : [
{
"time_range" : "08:00-10:00",
"subject" : "Physics"
},
{
"time_range" : "10:00-12:00",
"subject" : "Chemistry"
},
{
"time_range" : "10:00-12:00",
"subject" : "Biology"
}
]
},
{
"date" : "3-1-2014",
"subjects" : [
{
"time_range" : "08:00-10:00",
"subject" : "English"
},
{
"time_range" : "10:00-12:00",
"subject" : "Maths"
}
]
},
{
"date" : "4-1-2014",
"subjects" : [
{
"time_range" : "08:00-10:00",
"subject" : "Spanish"
},
{
"time_range" : "10:00-12:00",
"subject" : "Choreography"
},
{
"time_range" : "12:00-14:00",
"subject" : "Music"
},
{
"time_range" : "14:00-16:00",
"subject" : "Sports"
},
{
"time_range" : "16:30-18:30",
"subject" : "Religion"
}
]
}
]
}
What I would like to do is get an NSArray/NSMutableArray or NSDictionary/NSMutableDictionary` with the subjects for a GIVEN date. So for example if I type in the date 4-1-2014, I would like to get an array or dictionary with the 5 subjects that are contained in that date.
What I would like to do is get an NSArray/NSMutableArray or NSDictionary/NSMutableDictionary with the subjects for a GIVEN date. So for example if I type in the date 1-1-2014, I would like to get an array or dictionary with the 2 subjects that are contained in that date.
This is what I have tried:
//NSDICTIONARY CONTAINING CLASS DATA FOR CLASS ID
NSDictionary *classData =
[NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingAllowFragments error:&error];
//NSMUTABLEDICTIONARY CONTAINING SCHEDULE DATA FOR CLASS ID
NSMutableArray *scheduleDatabyClassID = [classData objectForKey:#"schedule"];
//NSMUTABLEARRAY CONTAINING SCHEDULE SUBJECTS OF CLASS ID
NSMutableArray *subjectsDatabyDate =[[NSMutableArray alloc] init] ;
for (NSMutableDictionary *subjectsData in scheduleDatabyClassID ){
NSString *subjectsData_temp = [subjectsData objectForKey:#"subjects"];
NSString *schedule_date = [subjectsData objectForKey:#"date"];
NSString *check = #"25-11-2013";
if ([schedule_date isEqualToString:check]) {
[subjectsDatabyDate addObject:subjectsData_temp];
}
}
Below is what I would like to get, but WITHOUT MANUALLY setting the index to 0. I want subjectsDataByDate : for the value (1-1-2014) for example.
NSLog(#"subjectsDatabyDate \n %# ", [subjectsDatabyDate objectAtIndex:0]);
This did the trick. As I mentioned, I needed a function that returns me an NSArray with containing the GIVEN date:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"date==%#",#"1-1-2014"];
NSArray *result_wanted = [scheduleDatabyClassID filteredArrayUsingPredicate:predicate];
NSLog(#"THE RESULT \n %# ", result_wanted);
If you do this for many different dates, and repeatedly, I would proceed somehow different.
NSDictionary is a class for key-value pairs. Your whole JSON data is actually a dictionary with keys "_id" and "schedule", and "schedule" has an array value. But looking at the data, a dictionary would have been much more appropriate, with for example "1-1-2014" as key and the rest as data. So you could turn the whole array into a dictionary, similar to your own code:
NSMutableDictionary *subjectsDatabyDate =[NSMutableDictionary dictionary] ;
for (NSDictionary *subjectsData in scheduleDatabyClassID )
{
NSString *schedule_date = [subjectsData objectForKey:#"date"];
subjectsDatabyDate [schedule_date] = subjectsData;
}
Now you can access any date very quickly:
NSDictionary* result_wanted = subjectsDatabyDate [#"1-1-2014"];
The difference is that access to an NSDictionary uses a hash table that will go directly to the item that you want, while the "filteredArray" has to iterate through the whole array, every time you look for a date.

Core Data - Sort descriptor for parent / child hierarchy

I get a JSON object from a HTML request which contains a hierarchical structure.
Sample from JSON object:
{
"_id": "4f870f064f95ae0da8000002",
"name": "Category",
"parent_id": null
},
{
"_id": "4f870f0e4f95ae0da8000004",
"name": "Brand",
"parent_id": null
},
{
"_id": "4f8715bd4f95ae0da8000028",
"name": "Dermalogica",
"parent_id": "4f870f0e4f95ae0da8000004"
},
{
"_id": "4f8715de4f95ae0da800002a",
"name": "Molton Brown",
"parent_id": "4f870f0e4f95ae0da8000004"
},
{
"_id": "4f8715ea4f95ae0da800002c",
"name": "Waxing",
"parent_id": "4f870f064f95ae0da8000002"
},
{
"_id": "4f8715f34f95ae0da800002e",
"name": "Mens Hair",
"parent_id": "4f870f064f95ae0da8000002"
},
{
"_id": "4f8715fd4f95ae0da8000030",
"name": "Ladies Hair",
"parent_id": "4f870f064f95ae0da8000002"
},
{
"_id": "4f87161f4f95ae0da8000032",
"name": "Massage",
"parent_id": "4f870f064f95ae0da8000002"
}
When I save it in the same way in just one entity, how would I define the fetch request (sorting) so that the objects are sorted with their parent / child relation ?
There is no way to sort this kind of data using sortDescriptors.
This is how I solve the problem, having comments of article with threaded style discussions. After I download all comments, I need to reindexComments
-(void)reindexComments{
NSArray *articleComments = self.comments.allObjects;
[self fetchChildsWithComments:articleComments forParentId:0 num:1];
}
-(NSUInteger)fetchChildsWithComments:(NSArray*)articleComments forParentId:(NSUInteger)parentId num:(NSUInteger)num{
NSArray *childComments = [articleComments filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"parentId == %u", parentId]];
childComments = [childComments sortedArrayUsingComparator:^NSComparisonResult(Comment *c1, Comment *c2) {
if (c1.commentIdValue < c2.commentIdValue){
return NSOrderedAscending;
}else{
return NSOrderedDescending;
}
}];
for (Comment *newRootComment in childComments){
newRootComment.numValue = num;
num++;
num = [self fetchChildsWithComments:articleComments forParentId:newRootComment.commentIdValue num:num];
}
return num;
}
and finally I just sort by numValue field to get my nice threaded discussion
One Way - to use NSOrderedSet - http://developer.apple.com/library/mac/#documentation/Foundation/Reference/NSOrderedSet_Class/Reference/Reference.html
Second,more convinient(since NSOrderedSet is introduced in iOS 5),just a soimple NSFetchRequest with sortDescriptors.Since it is an Array, you can use a many descritors at a time as you want. So, using descriptors by parent_id and id should give you desired result.
NSFetchRequest *request = [[NSFetchRequest alloc]init];
request.entity = [NSEntityDescription entityForName:#"Child" inManagedObjectContext:context];
// request.predicate = [NSPredicate predicateWithFormat:#"parent_id = %#",parent_ID];You don't need any predicate,right?
request.sortDescriptors = [NSArray arrayWithObjects:[NSSortDescriptor sortDescriptorWithKey:#"parent_id" ascending:YES],[NSSortDescriptor sortDescriptorWithKey:#"_id" ascending:YES],nil];
return [context executeFetchRequest:request error:&error];
And,in Objective-C it's not convinient to use underlines in names.
Hope, that helps.

Resources