Access the Dictionary From Json URL - ios

I am Using URL For Access JSON file
I get this From Following code
NSData* data=[jsonString dataUsingEncoding: [NSString defaultCStringEncoding] ];
NSError *error; //where jsonString is string of URL
NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
if (jsonDictionary==nil) {
NSLog(#"Error::Loading");
}else
{
NSArray *array = [jsonDictionary objectForKey:#"categories"];
for (int i=0; i<[array count]; i++) {
NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
[dic setValue:[[array objectAtIndex:i] valueForKey:#"cat_id"] forKey:#"cat_id"];
[dic setValue:[[array objectAtIndex:i] valueForKey:#"cat_name"] forKey:#"cat_name"];
[dic setValue:[[array objectAtIndex:i] valueForKey:#"cat_image"] forKey:#"cat_image"];
[dic setValue:[[array objectAtIndex:i] valueForKey:#"cat_list"] forKey:#"cat_list"];
[newsArray addObject:dic];
[categoryArry addObject:[dic valueForKey:#"cat_name"]];
[categoryId addObject:[dic valueForKey:#"cat_id"]];
[categoryImage addObject:[dic valueForKey:#"cat_image"]];
[categoryList addObject:[dic valueForKey:#"cat_list"]];
[dic release];
}
}
and get json Structure Like This
{
"categories": [
{
"cat_id": "15",
"cat_name": "Shop",
"cat_image": null,
"cat_list": [
{
"sub_cat_name": "New Arrivals",
"Cat_Data": [
{
"prod_name": "Generals Coat Biege",
"prod_price": "215.0000",
"prod_image": "honey_beau_lookbook_winter13_febmarch-24.jpg"
}
]
}
]
}
]
}
categoryArry contain only ine value "Shop"
but i want to access "sub_cat_name" in categoryArry and skip the Shop Level....
In short I want to store "sub_cat_name" in to categoryArry.

Surely you just need to do:
NSArray *catlist = [dic valueForKey:#"cat_list"]
NSDictionary *firstcat = [catlist objectAtIndex:0];
NSString *subcatname = [firstcat valueForKey:#"sub_cat_name"];
This assumes of course that you have at least one item in the cat_list array.

I'm using 3rd party library called AFNetworking to make JSON requests and parse the response.
Here's an example:
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:#"http://yoursite.com"];
NSMutableURLRequest *request = [httpClient requestWithMethod:#"POST"
path:#"blah/path"
parameters:#{#"jsonKey":#"jsonValue"}];
AFJSONRequestOperation *operation = [AFJSONRequestOperation
JSONRequestOperationWithRequest:request
success:^(NSURLRequest *request, NSHTTPURLResponse *res, id json) {
// Use the json here
json[#"categories"][0][#"cat_list"];
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id json) {
//Handle Errors
}];
[operation start];

At your code replace:
[categoryArry addObject:[dic valueForKey:#"cat_name"]];
by
[categoryArry addObject:[[dic valueForKey:#"cat_list"][0]] valueForKey:#"sub_cat_name"];
Anyway you could use the jsonDictionary directly instead of creating another dict.

Related

Parsing JSON object and sub-elements

I just need to know proper method to parse the JSON string.
Here is my sample JSON response:
[
{
"my_response": [
{
"name": "XXX",
"Area": "XXX",
"Num": 123
}
]
},
{
"other_response": [
{
"message": "Hello",
"status": "Success",
"flag_value": "1"
}
]
}
]
I want to parse flag_value in a String
I tried this method
NSString *str1 = [json valueForKeyPath:#"other_response. flag_value"];
NSLog(#"str %#",str1);
And my output is some what like this
str (
"<null>",
(
1
)
)
But I want my output to be a string like this:
1
[{"my_response":[{"name":"XXX","Area":"XXX","Num":123}]},{"other_response":[{"message":"Hello","status":"Success","flag_value":"1"}]}]
actually your Json response Start in Array so follow this step
Step-1
NSArray *jsonDict = [NSJSONSerialization JSONObjectWithData:yourData options:Kniloptions error:nil];
Step-2
in here you are get 2 Dictionaries
NSString *FlagStr;
for (NSMutableDictionary *temp in jsonDict)
{
NSArray *secondOption=[temp objectForKey:#"other_response"];
for (NSMutableDictionary *second in secondOption)
{
FlagStr=[second objectForKey:#"flag_value"];
}
}
Choice no-2
I am not try this but May be it work for you , once check
Step-1
NSArray *jsonDict = [[[NSJSONSerialization JSONObjectWithData:yourData options:Kniloptions error:nil]objectAtIndex:1] objectForKey:#"other_response"];
Step-2
NSString *FlagStr;
for (NSMutableDictionary *second in secondOption)
{
FlagStr=[temp objectForKey:#"flag_value"];
}
Choice no-3
you can directly fetch the string value I am not try this but May be it work for you , once check
NSString *flage = [[[NSJSONSerialization JSONObjectWithData:yourData options:Kniloptions error:nil]objectAtIndex:1] objectForKey:#"other_response"]objectAtIndex:0] objectForKey:#"flag_value"];
First of all, I think your JSON would be better formatted like the following:
{
"my_response": {
"name": "XXX",
"area": "XXX",
"num": "XXX"
},
"other_response": {
"message": "Hello",
"status": "success",
"flag_value": "1"
}
}
Then you can use the following code to access your data:
NSString *jsonString = #"{\"my_response\": {\"name\": \"XXX\",\"area\": \"XXX\",\"num\": \"XXX\"},\"other_response\": {\"message\": \"Hello\",\"status\": \"success\",\"flag_value\": \"1\"}}";
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableLeaves error:nil];
NSLog(#"str: %#", [jsonDict valueForKeyPath:#"other_response.flag_value"]);
Format your Json array like this way.
{
"my_response": {"name": "XXX","area": "XXX","num": "XXX"
},
"other_response": {"message": "Hello","status": "success","flag_value": "1"
}
}
**Step : 2**
Use AFNetworking for HTTP Client
- (void)yourMethod{
NSString *urlString = [NSString stringWithFormat:#"%#", your_service_url];
NSURL *url = [NSURL URLWithString:urlString];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
[AFJSONRequestOperation addAcceptableContentTypes:[NSSet setWithObject:#"text/html"]];
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
your_parameters_list,
nil];
NSMutableURLRequest *jsonRequest = [httpClient requestWithMethod:#"POST"
path:urlString
parameters:params];
AFJSONRequestOperation *operation =
[AFJSONRequestOperation JSONRequestOperationWithRequest:jsonRequest success: ^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSLog(#" Success %#", JSON);
NSDictionary *jsonDictionary1 = [JSON valueForKey:#"my_response"];
NSDictionary *jsonDictionary2 = [JSON valueForKey:#"other_response"];
NSString* name = [jsonDictionary1 valueForKey:#“name”];
NSString* area = [jsonDictionary1 valueForKey:#"name"];
NSString* num = [jsonDictionary1 valueForKey:#"num"];
} failure: ^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
NSLog(#"Fail %#", [error userInfo]);
NSLog(#“Error %#", [error localizedRecoverySuggestion]);
}];
[operation start];
}
As accepted above brother Anbu.Karthick answer.But I want to give answer for this
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:yourResponseData options: NSJSONReadingMutableContainers error: &err];
for (int i =0; i<[jsonArray count]; i++)
{
NSMutableDictionary *dict = [[jsonArray objectAtIndex:i] mutableCopy];
NSString *strFlag = [NSString stringWithFormat:#"%#",[[[dict objectForKey:#"other_response"] objectAtIndex:0] valueForKey:#"flag_value"]];
NSLog(#"The strFlag is-%#",strFlag);
}

JSON to NSMutableArray iOS

As a response to a request I get JSON:
{
"letters": {
"A": 0,
"B": 1,
"C": 2,
"D": 3,
"E": 4,
...
}
}
That's my code to acquire this JSON:
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"%#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// Handle error
}];
I want to fill array with keys (not values) like this:
array[0] = "A"
array[1] = "B"
...?
NSMutableArray *parts = [NSMutableArray new];
NSDictionary *allletters = [responseObject objectForKey:#"letters"];
for (NSString *key in [allletters allKeys])
{
NSString *value = [allletters objectForKey: key];
[parts insertObject:key atIndex:[val intValue]];
}
I haven't tested the code. But it should be something similar to this:
NSDictionary *responseDictionary = (NSDictionary*)responseObject;
NSDictionary *letters = [responseDictionary objectForKey:"letters"];
NSMutableArray *lettersArray = [[NSMutableArray alloc]init];
if ( letters ){
for (NSInteger i = 0; i < letters; ++i)
{
[lettersArray addObject:[NSNull null]];
}
[letters enumerateKeysAndObjectsWithOptions:NSEnumerationConcurrent
usingBlock:^(id key, id object, BOOL *stop) {
[lettersArray replaceObjectAtIndex:[key integerValue] withObject:object]
}]
}
try the following code
NSDictionary *letters = [responseObject objectForKey:"letters"];
NSArray *lettersArray = [letters allKeys];
As you are already using the JSON response serializer, responseObject should be a dictionary.
To get all keys of the sub dictionary letters, do
NSArray *letters = [reponseObject[#"letters"] allKeys];
No need for a mutable array here. But if you want it mutable , do
NSMutableArray *letters = [[reponseObject[#"letters"] allKeys] mutableCopy];

Utilizing AFNetworking with YouTube UITableView

I'm hoping someone can help. I am able to list YouTube videos in a tableView without AFNetworking. The code looks something like this:
NSURL *url = [[NSURL alloc] initWithString:#"http://gdata.youtube.com/feeds/api/playlists/PLgw1uRYia2CRrFJW7WT4sKoQxvl_pD0c1?v=2&alt=json&max-results=50&key=AIzaSyA8cyh2w-oa5Z5Wzq6em-ir8YCVF8j1zw4&orderby=published"];
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
NSString *jsonString = [[NSString alloc] initWithData: data encoding:NSUTF8StringEncoding];
NSData *jsonData = [jsonString dataUsingEncoding:NSUnicodeStringEncoding];
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options: NSJSONReadingAllowFragments error:nil];
NSDictionary *feed = [[NSDictionary alloc] initWithDictionary:[jsonDict valueForKey:#"feed"]];
videoArray = [NSMutableArray arrayWithArray:[feed valueForKey:#"entry"]];
[self.videolist reloadData];
The images have to load so scrolling is really weird. Therefore, I would like to utilize AFNetworking. Here's the code I have tried:
AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request];
op.responseSerializer = [AFJSONResponseSerializer serializer];
[op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSDictionary *feed = [[NSDictionary alloc] initWithDictionary:[responseObject valueForKey:#"feed"]];
videoArray = [NSMutableArray arrayWithArray:[feed valueForKey:#"entry"]];
NSLog(#"radio==%#",videoArray);
[self.videolist reloadData];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
And over cellForRowAtIndexPath, it looks something like this:
NSDictionary *video = videoArray[indexPath.row];
NSString *title = [video valueForKeyPath:#"title.$t"];
cell.videotitle.text = title;
That doesn't work for some reason, even when there are no errors. Help?
The videolist wasn't linked to the table in the Storyboard. The issue is now resolved.

Sending JSON to Schematic Ipsum

I'trying to get some random JSON from http://schematic-ipsum.herokuapp.com/ but I'm getting a response code 400.
Here is the code I'm using
+ (NSArray *)postData:(NSDictionary *)arguments toServer:(NSString *)urlString
{
NSArray *dataToReturn;
// if urlString is nil, we default it to our server
if(!urlString) urlString = JSON_SERVER;
// of course we need to turn the string into a valid array
NSURL *url = [NSURL URLWithString:urlString];
/*
prepare the post
*/
// we need to catch possible errors
NSError *error;
// turn our arguments into NSData
NSData *postData = [NSJSONSerialization dataWithJSONObject:arguments options:0 error:&error];
// we need the post' length
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[postData length]];
// create the url request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded;charset=UTF-8" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
// here we'll check the server response
NSHTTPURLResponse *response = nil;
// here's our data from the server
NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if ([response statusCode] >=200 && [response statusCode] <300)
{
// all good, let's see what we've got
NSString *responseData = [[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
NSLog(#"Response ==> %#", responseData);
// parse the response into a friendly format
dataToReturn = [[NSArray alloc] initWithArray:[self returnJSONFromData:urlData]];
} else {
// somethin went wrong
NSLog(#"Response code: %ld", (long)[response statusCode]);
// check if it's our fault
if (error) {
NSLog(#"Server error: %#", [error localizedDescription]);
}
}
// return our formatted array or nil
return dataToReturn;
}
+ (NSArray *)returnJSONFromData:(NSData *)urlData
{
NSArray *dataToReturn;
NSError *e = nil;
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData: urlData options: NSJSONReadingMutableContainers error: &e];
if (!jsonArray) {
NSLog(#"Error parsing JSON: %#", [e localizedDescription]);
dataToReturn = #[e];
} else {
dataToReturn = [[NSArray alloc] initWithArray:jsonArray];
NSLog(#"data from json: %#", dataToReturn);
}
return dataToReturn;
}
and I'm calling it like this, using a demo JSON from their website:
NSDictionary *post = #{ #"type": #"object", #"properties": #{ #"id": #{ #"type": #"string", #"ipsum": #"id" }, #"name": #{ #"type": #"string", #"ipsum": #"name" }, #"email": #{ #"type": #"string", #"format": #"email" } }};
[RetrieveDataFromServer postData:post toServer:#"http://schematic-ipsum.herokuapp.com/"];
You need to respect the syntax of "Form Data" that the server takes. To obtain this, you can use Google Chrome "Inspect Element", choose "Network" tab then do a request and you'll see this:
Look at "Form Data" section and you'll find out your problem, it's because you didn't pass the right structure to server so that the server doesn't understand.
I took the defaults parameters of server which is:
{
"type": "object",
"properties": {
"id": {
"type": "string",
"ipsum": "id"
},
"name": {
"type": "string",
"ipsum": "name"
},
"email": {
"type": "string",
"format": "email"
},
"bio": {
"type": "string",
"ipsum": "sentence"
},
"age": {
"type": "integer"
},
"avatar": {
"type": "string",
"ipsum": "small image"
}
}
}
So the data must be structured like this:
type:object
properties[id][type]:string
properties[id][ipsum]:id
properties[name][type]:string
properties[name][ipsum]:name
properties[email][type]:string
properties[email][format]:email
properties[bio][type]:string
properties[bio][ipsum]:sentence
properties[age][type]:integer
properties[avatar][type]:string
properties[avatar][ipsum]:small image
And don't forget to encode with percentage before sending it to server or you will fail again.
I tried to implement a method that take your dictionary and return the formatted form data, it works fine for this case but I'm not sure in a more general context. I'll post it here for you as a reference, it's really a mess, sorry for that but I don't have enough time for commenting.
- (NSString *)formatFormData:(NSDictionary *)dictionary
{
NSMutableArray *arrayPrefix = [NSMutableArray array];
NSMutableArray *arrayResult = [NSMutableArray array];
[self structureString:dictionary arrayPrefix:arrayPrefix arrayResult:arrayResult];
return [arrayResult componentsJoinedByString:#"&"];;
}
- (void)structureString:(NSDictionary *)dictionay arrayPrefix:(NSMutableArray *)arrayPrefix arrayResult:(NSMutableArray *)arrayResult
{
for(NSString *key in dictionay.allKeys)
{
NSObject *obj = [dictionay objectForKey:key];
if([obj isKindOfClass:[NSDictionary class]])
{
[arrayPrefix addObject:key];
[self structureString:(NSDictionary *)obj arrayPrefix:arrayPrefix arrayResult:arrayResult];
}
else
{
NSMutableString *string = [[NSMutableString alloc] initWithString:#""];
for(int i = 0; i < arrayPrefix.count; i++)
{
NSString *eachPrefix = arrayPrefix[i];
if(i == 0)
{
[string appendString:eachPrefix];
}
else
{
[string appendString:[NSString stringWithFormat:#"[%#]", eachPrefix]];
}
}
if(arrayResult.count == 0)
{
[string appendString:[NSString stringWithFormat:#"%#=%#", key, obj]];
}
else
{
[string appendString:[NSString stringWithFormat:#"[%#]=%#", key, obj]];
}
[arrayResult addObject:string];
}
}
}
And in your current method, add these lines:
- (NSArray *)postData:(NSDictionary *)arguments toServer:(NSString *)urlString
{
// omitted
// turn our arguments into NSData
NSData *postData = [NSJSONSerialization dataWithJSONObject:arguments options:0 error:&error];
NSString *stringTemp = [[NSString alloc] initWithData:postData encoding:NSUTF8StringEncoding];
stringTemp = [self formatFormData:arguments];
// encode form date before sending to server
stringTemp = [stringTemp stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
postData = [stringTemp dataUsingEncoding:NSUTF8StringEncoding];
// omitted
}

how to send array as a parameter in Afnetwoking post method?

hi i need to send a array as a one of the parameter in Afnetworking Query String
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:#"http://192.008.0.28/aaa/a/"]];
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys: #"20", #"Miles", [NSArray arrayWithObjects:#"1",#"2",#"3",nil], #"Interval", nil];
[httpClient postPath:iUpdateNotificationMethod parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSString *responseStr = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
NSLog(#"Request Successful, response '%#'", responseStr);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"[HTTPClient Error]: %#", error.localizedDescription);
}];
But server side we got "Miles":20,"Intervals":null how to fix it
Thanks,
Try This
AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:OAuthBaseURL];
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] initWithCapacity:0];
for (int i =0; i < [userIDs count]; i++) {
NSString *userID = [[userIDs objectAtIndex:i] objectForKey:#"id"];
NSDictionary *tmpDict = [NSDictionary dictionaryWithObjectsAndKeys:userID , [NSString stringWithFormat:#"ids[%i]",i], nil];
[parameters addEntriesFromDictionary:tmpDict];
}
[client postPath:#"/user"
parameters:parameters
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSData *data = (NSData *)responseObject;
NSString *jsonStr = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
NSLog(#"jsonStr %#",jsonStr);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
[self showError];
}
];
Since you're submitting an array, AFNetworking is generating a different parameter name and overloads it with the values you supply. For example, your request generates the following querystring:
Interval[]=1&Interval[]=2&Interval[]=3&Miles=20
This is defined in AFHTTPClient.m in the AFQueryStringPairsFromKeyAndValue function.
If you want to keep the original parameter, you should decide how to convert your NSArray to NSString by yourself. For example, you can do something like [myArray componentsJoinedByString:#","] and then split it back to elements on the server. If you choose this method, beware of using characters that might appear in your actual data.
I believe this will work:
params = #{ #"Miles": #"20", #"Interval": #[#"1",#"2",#"3"] };

Resources