Group same named NSURLComponents queryItems into NSDictionary as array - objective-c

With no objective-C knowledge I am currently stuck at, what would be a simple task in other languages I know.
For a query string like this:
name1=value1&name2=value2&name1=value3
I need to end up with a NSDictionary in this shape:
#{
#"name1": #{
someField: #[
#"value1",
#"value3",
]
anotherField: #YES,
},
#"name2": #{
someField: #[
#"value2",
]
anotherField: #YES,
}
}
In javascript I could solve this by:
queryItems.reduce((result, item) => {
resultItem = result[item.name] || {
someField: [],
anotherField: true,
}
resultItem.someField.push(item.value)
return {
...result,
[item.name]: resultItem,
}
}, {})
I found this How do I convert url.query to a dictionary in Swift? but I am stuck with Objective-C in this project.

Check the function bellow. I hope I understand what you mean.
NSDictionary* queryItemsToDictionary(NSString* items) {
NSURLComponents* components = [[NSURLComponents alloc] initWithString:[#"?" stringByAppendingString:items]];
NSMutableDictionary* result = [NSMutableDictionary new];
for (NSURLQueryItem* item in components.queryItems) {
NSDictionary* valueForItem = [result objectForKey:item.name];
NSArray* someFieldValues = [valueForItem objectForKey:#"someField"];
if (someFieldValues == nil) {
someFieldValues = #[];
}
[result setObject:#{
#"someField": [someFieldValues arrayByAddingObject:item.value],
#"anotherField": #YES
} forKey:item.name];
}
return result;
}
This is how you can try it:
NSDictionary* dictionary = queryItemsToDictionary(#"name1=value1&name2=value2&name1=value3");
NSLog(#"%#", dictionary);

Related

i have a json data and i only return a captains on that data dynamically

{
"team":
{
"players":
{
"1":
{
"teamName":"Royal Challenge Bangalore",
"shortName":"RCB",
"11":{
"name":"Virat Kholi",
"Iscaptain":true,
"postion":"2",
"runs":"6000"
},
"12":{
"name":"Chris Gyale",
"postion":"1",
"runs":"4000"
},
"13":{
"name":"AB",
"postion":"4",
"runs":"5000"
}
},
"2":
{
"teamName":"Kolkatta Knight Riders",
"shortName":"KKR",
"11":{
"name":"Robin Uttapa",
"postion":"1",
"runs":"6000"
},
"12":{
"name":"Sunil Narayan",
"postion":"2",
"runs":"4000"
},
"13":{
"name":"Gautam Ganmbhir",
"Iscaptain":true,
"postion":"4",
"runs":"5000"
}
}
}
}
}`enter code here`
You can do it this way. captains will contain NSDictionary objects with related data
NSString *json = #"your json here...";
NSError *error;
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:[json dataUsingEncoding:NSUTF8StringEncoding]
options:0
error:&error];
if (error) {
// TODO: handle error...
}
NSArray *teams = [[[dict objectForKey:#"team"] objectForKey:#"players"] allObjects];
NSMutableArray *captains = [NSMutableArray new];
for (NSDictionary *team in teams) {
for (id item in [team allValues]) {
if ([item isKindOfClass:[NSDictionary class]]) {
if ([(NSDictionary *) item objectForKey:#"Iscaptain"]) {
[captains addObject:item];
}
}
}
}

how to parse this JSON in OBJ c

I receive this JSON string from a web process
{
"result":"ok",
"description":"",
"err_data":"",
"data":[
{
"id":"14D19A9B-3D65-4FE2-9ACE-4C2D708DAAD8"
},
{
"id":"8BFD10B8-F5FD-4CEE-A307-FE4382A0A7FD"
}
]
}
and when I use the following to get the data:
NSError *jsonError = nil;
NSData *objectData = [ret dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *json= [NSJSONSerialization JSONObjectWithData: objectData options:kNilOptions error: &jsonError];
NSLog(#"data: %#",[json objectForKey:#"data"]);
it gets logged as:
(
{
id = "14D19A9B-3D65-4FE2-9ACE-4C2D708DAAD8";
},
{
id = "8BFD10B8-F5FD-4CEE-A307-FE4382A0A7FD";
}
)
How can I parse the data as an NSDictionary with value and keys?
The web returns an object that has a property which is an array of objects, so...
NSDictionary *json= // your code
NSArray *array = json[#"data"];
for (NSDictionary *element in array) {
NSLog(#"%#", element);
// or, digging a little deeper
NSString *idString = element[#"id"];
NSLog(#"id=%#", idString);
}

Parse a nested Json to NSDictionary in iOS

I Have a nested Json :
[
{
"result":"1",
"roleId":4
},
{
"projectInfo":[
{
"result":true
},
{
"Project":[
{
"ProjectId":5378,
"ProjectName":"ASAG",
"CountryId":146,
"ProjectGroupId":743,
"Description":"Axel Spinger AG"
},
{
"ProjectId":5402,
"ProjectName":"BIZ",
"CountryId":146,
"ProjectGroupId":759,
"Description":"Bizerba Win 7 BAU"
},
{
"ProjectId":5404,
"ProjectName":"BOM",
"CountryId":146,
"ProjectGroupId":743,
"Description":"Bombardier Transportation ThinApp Migration"
},
{
"ProjectId":5394,
"ProjectName":"REDBULL",
"CountryId":149,
"ProjectGroupId":762,
"Description":"Red Bull Mac Packaging"
},
{
"ProjectId":5397,
"ProjectName":"VHV",
"CountryId":146,
"ProjectGroupId":743,
"Description":"VHV Win7 Migration"
}
]
}
]
}
]
What I need is to separate it into small pieces to get value of some specific key like this answer: How to parse JSON into Objective C - SBJSON
My code is :
SBJsonParser* jParser = [[SBJsonParser alloc] init];
NSDictionary* root = [jParser objectWithString:string];
NSDictionary* projectInfo = [root objectForKey:#"projectInfo"];
NSArray* projectList = [projectInfo objectForKey:#"Project"];
for (NSDictionary* project in projectList)
{
NSString *content = [project objectForKey:#"ProjectId"];
NSLog(#"%#", content);
}
But I got the error when trying to get projectInfo from root node. Is there anything wrong with my code ? Please provide me an example to split up my JSON. Any help would be great.
You JSON contains like nested array. Just spit each content into a dictionary to get the result.
Working Code:
SBJsonParser* jParser = [[SBJsonParser alloc] init];
NSArray* root = [jParser objectWithString:string];
NSDictionary* projectDictionary = [root objectAtIndex:1];
NSArray* projectInfo = [projectDictionary objectForKey:#"projectInfo"];
NSDictionary* projectData = [projectInfo objectAtIndex:1];
NSDictionary *projectList = [projectData objectForKey:#"Project"];
NSLog(#"\n\n Result = %#",projectList
);
for (NSDictionary* project in projectList)
{
NSString *content = [project objectForKey:#"ProjectId"];
NSLog(#"\n Project Id =%#", content);
}
According to your JSON structure, your top level structure is an array, not a dictionary.
Try this:
SBJsonParser* jParser = [[SBJsonParser alloc] init];
NSArray* root = [jParser objectWithString:string];
NSDictionary* projectDictionary = [root objectAtIndex:1];
NSArray* projectInfo = [projectDictionary objectForKey:#"projectInfo"];

Add objects to NSMutable array with grouping

I want my NSArray sampleData to receive actual data from parse.com database assuming like this:
self.sampleData = #[ #{ #"date": #"12/5/2014",
#"group": #[ #{ #"text": #"post1", #"location": #"x,y" },
#{ #"text": #"post2", #"location": #"x,y" },
#{ #"text": #"post3", #"location": #"x,y" },
#{ #"text": #"post4", #"location": #"x,y" },
#{ #"text": #"post5", #"location": #"x,y" }
]
},
#{ #"date": #"12/3/2014",
#"group": #[ #{ #"text": #"post6", #"location": #"x,y" },
#{ #"text": #"post7", #"location": #"x,y" },
#{ #"text": #"post8", #"location": #"x,y" },
#{ #"text": #"post9", #"location": #"x,y" },
#{ #"text": #"post10", #"location": #"x,y" }
]
}
];
As you can see, I want to group text and location by date, so that I can display them in a view with date as header and text/location as content.
Here below is what I'm capable doing so far:
PFQuery *postQuery = [PFQuery queryWithClassName:kPAWParsePostsClassKey];
[postQuery whereKey:kPAWParseUserKey equalTo:[PFUser currentUser]];
postQuery.cachePolicy = kPFCachePolicyNetworkElseCache;
postQuery.limit = 20;
[postQuery findObjectsInBackgroundWithBlock:^(NSArray *myPosts, NSError *error)
{
if( !error )
{
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MM/dd/yyyy"];
NSMutableArray *objectArray = [NSMutableArray new];
for (PFObject *object in myPosts) {
[objectArray addObject:#{#"createdAt": [formatter stringFromDate:object.createdAt], #"text": [object objectForKey:#"text"], #"location": [object objectForKey:#"location"]}];
}
self.sampleData = objectArray;
NSLog(#"My sampleData --> %#", self.sampleData);
}
}
];
The above code is obvious there's no grouping whatsoever, so really need help here.
Okay, so you have an array of items, and you want to group them into sections based on a particular key.
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MM/dd/yyyy"];
// Sparse dictionary, containing keys for "days with posts"
NSMutableDictionary *daysWithPosts = [NSMutableDictionary dictionary];
[myPosts enumerateObjectsUsingBlock:^(PFObject *object, NSUInteger idx, BOOL *stop) {
NSString *dateString = [formatter stringFromDate:[object createdAt]];
// Check to see if we have a day already.
NSMutableArray *posts = [daysWithPosts objectForKey: dateString];
// If not, create it
if (posts == nil || (id)posts == [NSNull null])
{
posts = [NSMutableArray arrayWithCapacity:1];
[daysWithPosts setObject:posts forKey: dateString];
}
// add post to day
[posts addObject:obj];
}];
// Sort Dictionary Keys by Date
NSArray *unsortedSectionTitles = [daysWithPosts allKeys];
NSArray *sortedSectionTitles = [unsortedSectionTitles sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
NSDate *date1 = [formatter dateFromString:obj1];
NSDate *date2 = [formatter dateFromString:obj2];
return [date2 compare:date1];
}];
NSMutableArray *sortedData = [NSMutableArray arrayWithCapacity:sortedSectionTitles.count];
// Put Data into correct format:
[sortedSectionTitles enumerateObjectsUsingBlock:^(NSString *dateString, NSUInteger idx, BOOL *stop) {
NSArray *group = daysWithPosts[dateString];
NSDictionary *dictionary = #{ #"date":dateString,
#"group":group };
[sortedData addObject:dictionary];
}];
self.sampleData = sortedData;
This code will not generate exactly what you asked for. It will generate something that looks like this:
sampleData = #[ #{ #"date": #"12/5/2014",
#"group": ##[ PFObject*,
PFObject*,
PFObject*,
PFObject*,
PFObject*,
]
},
#{ #"date": #"12/3/2014",
#"group": #[ PFObject*,
PFObject*,
PFObject*,
PFObject*,
PFObject
]
}
];
There's no need to convert your PFObject* in the myPosts array into #{ #"text": #"post5", #"location": #"x,y" } since you'll lose access to other pieces of information. Here is how you would use this sampleData array.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; {
return self.sampleData.count;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section; {
return self.sampleData[section][#"date"];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; {
return self.sampleData[section][#"group"].count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath; {
PFObject *post = self.sampleData[indexPath.section][#"group"][indexPath.row];
UITableViewCell *cell = // dequeue A reusable tableviewcell here
// configure the cell here
return cell;
}

How to convert data to JSON format, using SBJSON iPhone SDK?

I want to convert the given data to JSON format ... please help me to overcome this problem. Thanks in advance.
{
data = (
{
id = 1307983297;
name = "Aafaaq Mehdi";
},
{
id = 1350886273;
name = "Shah Asad";
},
{
id = 1636300537;
name = "Imran Baig";
},
{
id = 1640049813;
name = "Vinod Gowda";
}
);
}
UPDATE:
NSDictionary *dict = [[NSDictionary alloc] initWithDictionary:appDelegate.friendList];
results= (NSArray *)[dict valueForKey:#"data"];
NSMutableArray *arr = [[NSMutableArray alloc] init];
// loop over all the results objects and print their names
int ndx;
for (ndx = 0; ndx < results.count; ndx++)
{
[arr addObject:(NSDictionary *)[results objectAtIndex:ndx]];
}
FriendListModel *obj;
for (int x=0; x<[arr count]; x++)
{
obj = [[[FriendListModel alloc] initWithjsonResultDictionary:[arr objectAtIndex:x]] autorelease];
[arr replaceObjectAtIndex:x withObject:obj];
NSMutableArray *facebookJSON = [[[NSMutableArray alloc] init] autorelease];
for (obj in arr) {
NSDictionary *syedDict = [NSDictionary dictionaryWithObjectsAndKeys:obj.friendId,#"id", obj.friendName, #"name", nil];
NSString *facebookJSONFormat = [syedDict JSONRepresentation];
[facebookJSON addObject:facebookJSONFormat];
}
NSString *myArrayString = [facebookJSON description];
NSString *braceInArr = [NSString stringWithFormat:#"[%#]", myArrayString];
[self setFormDataRequest:[ASIFormDataRequest requestWithURL:url]];
[formDataRequest setDelegate:self];
[formDataRequest setPostValue:braceInArr forKey:#"friend_list"];
[formDataRequest setDidFailSelector:#selector(uploadFailed:)];
[formDataRequest setDidFinishSelector:#selector(uploadFinished:)];
[formDataRequest startAsynchronous];
I got the output in this format:-
[(
"{\"id\":\"1307983297\",\"name\":\"No Man\"}",
"{\"id\":\"1350886273\",\"name\":\"Shah Asad\"}",
"{\"id\":\"1636300537\",\"name\":\"Imran Baig\"}",
"{\"id\":\"1640049813\",\"name\":\"Vinod Gowda\"}"
)]
{
"data":[
{
"id": 1307983297,
"name": "Aafaaq Mehdi"
},
{
"id": 1350886273,
"name": "Shah Asad"
},
{
"id": 1636300537,
"name": "Imran Baig"
},
{
"id": 1640049813,
"name": "Vinod Gowda"
}
]
}
That's your dad in JSON format... as for converting it, do you have a parser for the original format?