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];
Related
I'm attempting to obtain elements extracted from a dictionary and convert them to doubles. The data is being pulled from JSON and seems to be extracted into a type of array (not sure which type). Is there a way to obtain the numbers listed below individually out of the array? Please let me know if you need more information.
NSDictionary *parameters = #{#"username":savedUser,#"password":savedPass};
NSURL *URL = [NSURL URLWithString:#"testwebsite"];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
[manager GET:URL.absoluteString parameters:parameters progress:nil success:^(NSURLSessionTask *task, id responseObject)
{
NSError *error = nil;
JSON = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingAllowFragments error:&error];
if (error) {
NSLog(#"Error serializing %#", error);
}
NSLog(#"%#",JSON);
NSString *price = [NSString stringWithFormat:#"%#",[JSON valueForKey:#"UnitPrice"]];
price= [price stringByReplacingOccurrencesOfString:#"\"" withString:#""];
NSLog(#"Price: %#",price);
[transactionTotals addObject:price];
[self createGraph:100];
}
failure:^(NSURLSessionTask *operation, NSError *error)
{
NSLog(#"Error1: %#", [error debugDescription]);
NSLog(#"Error2: %#", [error localizedDescription]);
}];
}
#catch (NSException *exception)
{
NSLog(#"%#",exception);
}
Log (UnitPrice values I need individually extracted):
Dictionary output:
2016-07-03 22:52:21.330 T2PApp[2272:658440] (
{
OrderDetailID = 3;
ProductName = Oranges;
UnitPrice = "399.99";
date = "2016-06-09T21:45:06";
},
{
OrderDetailID = 7;
ProductName = Oranges;
UnitPrice = 1000;
date = "2016-06-13T22:15:47.107";
}
)
Extracted UnitPrice output (still not completely extracted):
2016-07-03 22:52:21.330 T2PApp[2272:658440] Price: (
399.99,
1000
)
I think what you need is digging out the data from the objects in array. It not about the JSON.
There is many way to do it, but not one simply way to dig it out.
For example, create a new array, and traverse the target array, put the property you need into the new array.
It is basically like that.
In your code, maybe the code below will work.
NSLog(#"%#",JSON);
NSMutableArray *priceArr = [NSMutableArray array];
NSArray *arr = nil;
if ([JSON isKindOfClass:[NSArray class]]) {
arr = (NSArray *)JSON;
for (NSDictionary *dic in arr) {
NSString *price = [NSString stringWithFormat:#"%#",[dic valueForKey:#"UnitPrice"]];
price= [price stringByReplacingOccurrencesOfString:#"\"" withString:#""];
[priceArr addObject:price];
}
}
priceArr is what you need.
here is the JSON data that has multiple object i just want to parse "continueWatching" object so i just shared it:
{
"message": {
"continueWatching": [{
"id": "2",
"video": [{
"videoName": "fsfdsf",
"coverPicture": ""
}
],
"cursorPosition": "12:32:25",
"dateWatched": "2015-07-08 00:00:00",
"updated": "2015-07-15 12:12:34"
}, {
"id": "1",
"video": [{
"videoName": "Hello",
"coverPicture": ""
}
],
"cursorPosition": "15:42:41",
"dateWatched": "2015-07-02 00:00:00",
"updated": "2015-07-02 00:00:00"
}, {
"id": "3",
"video": [{
"videoName": "adfafadf",
"coverPicture": ""
}
],
"cursorPosition": "12:32:25",
"dateWatched": "2015-07-01 00:00:00",
"updated": "2015-07-02 00:00:00"
}]
}
My code right now, i printed the whole JSON data and the message object, i need to get all "videoName" in a single array arranged by their "id" numbers plus i also want to get all "cursorPosition" in a single array arranged by their "id"
NSString *myRequestString = [NSString stringWithFormat:#"getRecommendations=all&profileId=1"];
// Create Data from request
NSData *myRequestData = [NSData dataWithBytes: [myRequestString UTF8String] length: [myRequestString length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: url];
// set Request Type
[request setHTTPMethod: #"POST"];
// Set content-type
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"content-type"];
// Set Request Body
[request setHTTPBody: myRequestData];
// Now send a request and get Response
NSData *returnData = [NSURLConnection sendSynchronousRequest: request returningResponse: nil error: nil];
// Log Response
NSString *response = [[NSString alloc] initWithBytes:[returnData bytes] length:[returnData length] encoding:NSUTF8StringEncoding];
NSLog(#"Response: %#",response);
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:returnData options:NSJSONReadingMutableLeaves error:nil];
BOOL boolean=[[dict objectForKey:#"boolean"]boolValue];
NSArray *message=[dict objectForKey:#"message"];
NSLog(#"kajhsdahfohofhoaehfpihjfpejwfp%#",message);
I do not get any very elegant way of doing this but this will solve your problem
NSArray *continueWatching = [[dict objectForKey:#"message"] objectForKey:#"continueWatching"];
//sort all objects using id.
NSSortDescriptor *sortDesc = [NSSortDescriptor sortDescriptorWithKey:#"id" ascending:YES selector:#selector(localizedStandardCompare:)];
continueWatching = [continueWatching sortedArrayUsingDescriptors:#[sortDesc]];
NSMutableArray *cursorPosition = [NSMutableArray array];
NSMutableArray *videoNames = [NSMutableArray array];
[continueWatching enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
//find all videos array and then again enumerate it and extract all video names
NSArray *videos = [obj objectForKey:#"video"];
[videos enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[videoNames addObject:[obj objectForKey:#"videoName"]];
}];
//extract all curser positions and save them
[cursorPosition addObject:[obj objectForKey:#"cursorPosition"]];
}];
NSLog(#"%#",cursorPosition);
NSLog(#"%#",videoNames);
this solution uses valueForKeyPath to extract the requested objects without loops.
The array continueWatchingArray is sorted before getting the properties.
Therefore the resulting arrays videoNameArray and cursorPositionArray are sorted, too
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:returnData options:NSJSONReadingMutableLeaves error:nil];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"id" ascending:YES];
NSArray *continueWatchingArray = [[dict valueForKeyPath:#"message.continueWatching"] sortedArrayUsingDescriptors:#[sortDescriptor]];
NSArray *cursorPositionArray = [continueWatchingArray valueForKeyPath:#"cursorPosition"];
NSArray *videoNameArray = [continueWatchingArray valueForKeyPath:#"video.videoName"];
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
// repeat loop to flatten the array
for (NSArray *subArray in videoNameArray) {
[tempArray addObject:subArray[0]];
}
videoNameArray = tempArray;
NSLog(#"%#", videoNameArray);
NSLog(#"%#", cursorPositionArray);
Your code will be like this.
NSArray* continueWatching = [[dict objectForKey:#"message"] objectForKey:#"continueWatching"];
continueWatching = [continueWatching sortedArrayUsingDescriptors:#[[NSSortDescriptor sortDescriptorWithKey:#"id" ascending:YES]]];
NSMutableArray *arrayOfVideos = [[NSMutableArray alloc]init];
NSMutableArray *arrayOfCursors = [[NSMutableArray alloc]init];
for(NSDictionary *dicData in continueWatching){
NSArray *videoArray = [dicData objectForKey:#"video"];
[arrayOfVideos addObjectsFromArray:videoArray];
[arrayOfCursors addObject:[dicData valueForKey:#"cursorPosition"]];
}
//now in the two arrays you will have the required result.
JSON object "message" is a dictionary and not an array.
NSDictionary *messages = [dict objectForKey:#"message"];
NSArray *continue = [messages objectForKey:#"continueWatching"];
You now have an array of your videos's properties.
NSSortDescriptor *sortDesc = [NSSortDecriptor sortDescriptorWithKey:#"id" ascending:YES];
NSArray *sortedVideosById = [continue sortedArrayUsingDescriptors:#[sortDesc]];
You now have an array of your videos's properties, sorted by video's id.
Parse it to collect video names and cursorPosition in arrays, sorted by ids.
NSMutableArray *videoNames = [NSMutableArray array];
NSMutableArray *cursorPositions = [NSMutableArray array];
for( NSDictionary *v in sortedVideosById )
{
NSArray *videoArray = (NSArray *)(v[#"video"]);
NSDictionary *firstVideo = videoArray[0];
videoNames addObject:firstVideo[#"videoName"];
[cursorPositions addObject:v[#"cursorPosition"];
}
- The structure that I am trying to create is
[{'category_id': '3'}, {'category_id': '2'}, {'category_id': '1'}]
- I tried creating the same using NSMutableArray of NSMutableDictionary & the structure that i got back was:
<__NSArrayM 0x7c186080>(
{
"category_id" = 1;
},
{
"category_id" = 2;
},
{
"category_id" = 3;
}
)
- I am sending this to server over HTTPPost.
- But on the server the request is reaching as:
{(null)[][category_id]': ['1', '2', '3']}
Which is not in the desired format as i showed above in point 1.
- Can anyone please help me out create an JSONArray of JSONObjects, I would be really obliged.
The code that i used to create and send the request to server is:
-(void) getProductList:(NSString *)strToken andCatId:(NSArray *)arrCategory{
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager.requestSerializer setValue:strToken forHTTPHeaderField:#"Authorization"];
manager.responseSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];
NSString *strSuffix = #"unfollow/productList/";
NSString *strUrl = [NSString stringWithFormat:#"%#%#",BASE_URL,strSuffix];
api_categoryProductList *currentObj = self;
[manager POST:strUrl parameters:arrCategory success:^(AFHTTPRequestOperation *operation, id responseObject) {
[currentObj httpOperationDidSuccess:oper
ation responseObject:responseObject];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
[currentObj httpOperationDidFail:operation error:error];
}];
}
Try this:
NSMutableArray *array = [[NSMutableArray alloc] init];
NSNumber *id = [NSNumber numberWithInt:1];
for (int i = 0; i < 5; ++i) {
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:id forKey:#"category_id"];
[array addObject:dict];
}
Right now it has static id as 1. You can change it to whatever value you like.
I need to get Particular Object values ( A, B, C, D) and related key values (#"name" ). Here below I have posted my sample code and response. Please help me.
NSString *combined = URL;
NSURL *url = [[NSURL alloc] initWithString:combined];
NSData *responseData=[NSData dataWithContentsOfURL:url];
NSError *error;
NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
NSArray *responsData = [jsonDictionary objectForKey:#"response"];
// GET A,B,C Object values
NSDictionary *d1 = responsData.firstObject;
NSEnumerator *enum1 = d1.keyEnumerator;
NSArray *firstObject = [enum1 allObjects];
My JSON Response :
response : [ {
A = [ {
name : tango
}
{
name : ping
}
]
B = [ {
name : tango
}
{
name : ping
}
]
} ]
You can achieve the list of all names using this:
NSMutableArray *names = [[NSMutableArray alloc] init];
for (NSDictionary *dict in responsData) {
[dict enumerateKeysAndObjectsUsingBlock: ^(id key, id obj, BOOL *stop) {
NSArray *valueArray = (NSArray *)obj;
for (NSDictionary * namesDict in valueArray) {
[names addObject:namesDict[#"name"]];
}
}];
}
Output:
NSLog(#"Names %#",names);
tango, ping, tango, ping.
Hope that helps!
Simply
for(NSDictionary *dict in firstObject){
NSLog(#"%#",[dict objectForKey:#"name"]);
}
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.