How to get elements from NSArray - objective-c

I have an NSArray built from json data from twitter REST API.
NSArray *dict = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&error];
NSLog (#"Element %#", [dict objectAtIndex: 1]);
How to get individual elements from the array, one of the array index item looks like:
Element 1 = {
contributors = "<null>";
coordinates = "<null>";
"created_at" = "Tue Feb 07 11:15:08 +0000 2012";
entities = {
hashtags = (
);
urls = (
);
"user_mentions" = (
);
};
favorited = 0;
geo = "<null>";
id = 166842424398848000;
"id_str" = 166842424398848000;
"in_reply_to_screen_name" = "<null>";
"in_reply_to_status_id" = "<null>";
"in_reply_to_status_id_str" = "<null>";
"in_reply_to_user_id" = "<null>";
"in_reply_to_user_id_str" = "<null>";
place = "<null>";
"retweet_count" = 0;
retweeted = 0;
source = web;
text = "another day is here so ready to be off from work already...";
....

You could try,
NSString *string = [[dict objectAtIndex: 1] objectForKey:#"keyName"];
There's a sub dictionary in your data if I look correctly ("entities")
NSDictionary *entitiesDict = [[dict objectAtIndex: 1] objectForKey:#"entities"];
Use NSDictionary as mentioned :)

Use NSDictionary instead of NSArray and set the values for elements in key. check this link for more idea.
http://www.touch-code-magazine.com/tutorial-fetch-and-parse-json/

Related

breaking up a single array object into many objects

Apologies if this is a novice question, but I've been struggling to figure this out with no luck. I'm trying to pull a users' twitter timeline using the AFOAuth2Manager framework. Everything makes sense except the returned JSON object is an array and the entire object is one giant object. I obviously want to break it up into different elements and store them in a dictionary, but have not been able to figure it out so far.
This is a VERY partial example of what the array object looks like. The complete object is this with about 20 or so more tweets with this format attached. I will post the entire json object if requested, but it seems pretty pointless to post the entire thing.
Heres my code:
[manager GET:#"/1.1/statuses/user_timeline.json?screen_name=jack"
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject ) {
self.object = responseObject;
NSLog(#"Success: %#", responseObject);
if ([responseObject isKindOfClass:[NSArray class]]) {
NSLog(#"object is a nsarray class");
} else if ([responseObject isKindOfClass:[NSDictionary class]]){
NSLog(#"object is a nsdictionary class");
} else {
NSLog(#"object is a different class");
}
NSArray *response = [NSArray arrayWithObject:responseObject];
NSLog(#"count %ld", [response count]);
NSData *dataFromTwitter = [NSKeyedArchiver archivedDataWithRootObject:self.object];
NSError *parseError = nil;
NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:dataFromTwitter
options:NSJSONReadingMutableLeaves | NSJSONReadingMutableContainers|NSJSONReadingAllowFragments
error:&parseError];
NSLog(#"response Dict: %#", responseDict);
NSError *e = nil;
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:dataFromTwitter
options:NSJSONReadingAllowFragments
error:&e];
NSLog(#"jsonArray: %#", jsonArray);
NSError *jsonError2 = nil;
id jsonObject = [NSJSONSerialization JSONObjectWithData:dataFromTwitter
options:NSJSONReadingAllowFragments
error:&jsonError2];
if ([jsonObject isKindOfClass:[NSArray class]]) {
NSLog(#"its an array!");
NSArray *jsonArray = (NSArray *)jsonObject;
NSLog(#"jsonArray2 - %#",jsonArray);
}
else {
NSLog(#"its probably a dictionary");
NSDictionary *jsonDictionary = (NSDictionary *)jsonObject;
NSLog(#"jsonDictionary - %#",jsonDictionary);
NSLog(#"error %#", jsonError2);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Failure: %#", error);
}];
{
contributors = "<null>";
coordinates = "<null>";
"created_at" = "Mon Feb 29 01:18:05 +0000 2016";
entities = {
hashtags = (
);
symbols = (
);
urls = (
);
"user_mentions" = (
{
id = 14616957;
"id_str" = 14616957;
indices = (
0,
7
);
name = "Jason Del Rey";
"screen_name" = DelRey;
},
{
id = 19040598;
"id_str" = 19040598;
indices = (
8,
18
);
name = "\U0ca0_\U0ca0";
"screen_name" = MikeIsaac;
},
{
id = 46063;
"id_str" = 46063;
indices = (
19,
30
);
name = "Hunter Walk";
"screen_name" = hunterwalk;
}
);
};
"favorite_count" = 12;
favorited = 0;
geo = "<null>";
id = 704113377920978944;
"id_str" = 704113377920978944;
"in_reply_to_screen_name" = DelRey;
"in_reply_to_status_id" = 704112911116013568;
"in_reply_to_status_id_str" = 704112911116013568;
"in_reply_to_user_id" = 14616957;
"in_reply_to_user_id_str" = 14616957;
"is_quote_status" = 0;
lang = en;
place = "<null>";
"retweet_count" = 0;
retweeted = 0;
source = "Twitter for iPhone";
text = "#DelRey #MikeIsaac #hunterwalk this changes everything";
truncated = 0;
user = {
"contributors_enabled" = 0;
"created_at" = "Tue Mar 21 20:50:14 +0000 2006";
"default_profile" = 0;
"default_profile_image" = 0;
description = "#withMalala!";
entities = {
description = {
urls = (
);
};
};
"favourites_count" = 11433;
"follow_request_sent" = "<null>";
"followers_count" = 3458722;
following = "<null>";
"friends_count" = 1859;
"geo_enabled" = 1;
"has_extended_profile" = 1;
id = 12;
"id_str" = 12;
"is_translation_enabled" = 0;
"is_translator" = 0;
lang = en;
"listed_count" = 25944;
location = "California, USA";
name = Jack;
notifications = "<null>";
"profile_background_color" = EBEBEB;
"profile_background_image_url" = "http://abs.twimg.com/images/themes/theme7/bg.gif";
"profile_background_image_url_https" = "https://abs.twimg.com/images/themes/theme7/bg.gif";
"profile_background_tile" = 0;
"profile_image_url" = "http://pbs.twimg.com/profile_images/668328458519384064/FSAIjKRl_normal.jpg";
"profile_image_url_https" = "https://pbs.twimg.com/profile_images/668328458519384064/FSAIjKRl_normal.jpg";
"profile_link_color" = 990000;
"profile_sidebar_border_color" = DFDFDF;
"profile_sidebar_fill_color" = F3F3F3;
"profile_text_color" = 333333;
"profile_use_background_image" = 1;
protected = 0;
"screen_name" = jack;
"statuses_count" = 19066;
"time_zone" = "Pacific Time (US & Canada)";
url = "<null>";
"utc_offset" = "-28800";
verified = 1;
};
},
You show no code in your question, in a comment you state you have a responseObject but not how you came by it.
The JSON you are getting from somewhere will be text, you may have it as an NSString, NSData, an NSArray whose elements are these, etc.
You need to obtain that text and then parse it as JSON, the NSJSONSerialization class will handle the parsing for you, the first line of its description states:
You use the NSJSONSerialization class to convert JSON to Foundation objects and convert Foundation objects to JSON.
Once you have those Foundation objects - arrays, dictionaries, strings, numbers, etc. you can extract the fields you are interested in.
Once you've written some code to do this if it doesn't work and you are stuck ask a new question showing your code and someone will probably be able to help you further.
HTH

How to read keys from jSON

how to print the key event_id on label.
"all_data" = (
{
"company_logo" = "http://mbdbtechnology.com/projects/officeapp/uploads/event/Voxev\U00e6rket_logo_stort.png";
"event_id" = 8;
"event_name" = "Dit nye kontor i Voxev\U00e6rket";
"event_sort_desc" = "Voxev\U00e6rket tilbyder landsd\U00e6kkende kontorer til ny opstartede";
},
{
"company_logo" = "http://mbdbtechnology.com/projects/officeapp/uploads/event/Image_jpg_2_288X200.jpg";
"event_id" = 7;
"event_name" = "Sunday Special only for women";
"event_sort_desc" = "Declarations of war At midnight on 31 July \U2013 1 Aug, French 2";
},
try this:
NSMutableDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
//responseData is an NSData object containing the jSON
NSMutableArray *allData = [jsonDict objectForKey:#"all_data"];
for (NSDictionary* dict in allData)
{
NSString *eventID = [dict objectForKey:#"event_id"];
NSLog(#"event ID : %#",eventID);
}

Sort an Array of Dictionaries issue

I have an array(seachResult) which contains dictionaries and I want to sort this array according to 'price' key in the dictionary that is a number in string format.
I tried this code but it doesn't work for sorting 'price' but it works for pid which is a number.
how can I sort it according 'price' (number in string format)?
NSSortDescriptor *sortByPrice = [NSSortDescriptor sortDescriptorWithKey:#"price" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortByPrice];
NSArray *sortedArray = [self.seachResult sortedArrayUsingDescriptors:sortDescriptors];
NSLog(#"%#",sortedArray );
here is sample data for self.searchResult:
2013-07-17 02:04:55.012 MyApp[57014:16a03] sorted array of dictionaries: (
{
cid = 2;
image = "http:///images/loginlogo.png";
latitude = "48.245565";
longitude = "16.342333";
manual = "";
movie = "http://jplayer.org/video/m4v/Big_Buck_Bunny_Trailer.m4v";
pcode = 023942435228;
pid = 1;
pname = "example product";
price = "12.00";
qrcode = "";
rid = 1;
rname = "Example Retailer Name";
sale = 0;
"sale_percent" = 0;
"sale_price" = "0.00";
text = "here is text about sample product number 1...\nasdasdasda\nsdfsdfsd\nSdfsdf\nSDfsdfs\ndfsdfsdf\n\n\n";
},
{
cid = 2;
image = "http:///testImage.png";
latitude = "48.245565";
longitude = "16.342333";
manual = "";
movie = "";
pcode = 1;
pid = 2;
pname = "sample product 2";
price = "126.00";
qrcode = "";
rid = 1;
rname = "Example Retailer Name";
sale = 1;
"sale_percent" = 20;
"sale_price" = "99.99";
text = "here is text about sample product number 2...\nblah blah blah\nasdasdasd\nASdasdas\nASdasdasd";
},
{
cid = 1;
image = "";
latitude = "";
longitude = "";
manual = "";
movie = "";
pcode = 1;
pid = 3;
pname = "test product";
price = "46.00";
qrcode = "";
rid = 2;
rname = "";
sale = 0;
"sale_percent" = 0;
"sale_price" = "35.00";
text = "some text here...
\nasdasd
\nasd
\na
\nsd
\nas
\nd";
}
)
I also tried this code :
NSSortDescriptor *hopProfileDescriptor =
[[NSSortDescriptor alloc] initWithKey:#"price"
ascending:YES];
NSArray *descriptors = [NSArray arrayWithObjects:hopProfileDescriptor, nil];
NSArray *sortedArrayOfDictionaries = [self.seachResult
sortedArrayUsingDescriptors:descriptors];
NSLog(#"sorted array of dictionaries: %#", sortedArrayOfDictionaries);
but still doesn't work.
I think the issue is that in your self.searchResult array the price data is differently formatted for the objects in the array.
The first object in the array it's formatted like price = 12; (probably a NSDecimalNumber)
The second object in the array it's formatted like price = "125.99"; (proably a NSString)
NSArray *testSorted = [test sortedArrayUsingComparator:^NSComparisonResult(NSDictionary *obj1, NSDictionary *obj2) {
NSString *price1 = obj1[#"price"];
NSString *price2 = obj2[#"price"];
NSNumber *n1 = [NSNumber numberWithFloat:[price1 floatValue]];
NSNumber *n2 = [NSNumber numberWithFloat:[price2 floatValue]];
return [n1 compare:n2];
}];
Since your price data seems to vary (NSString vs NSNumber) you might try instead using sortedArrayUsingComparator:. eg:
NSArray *sortedArray = [unsortedArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
id value1 = [obj1 objectForKey:#"price"];
float float1 = [value1 floatValue];
id value2 = [obj2 objectForKey:#"price"];
float float2 = [value2 floatValue];
if (float1 < float2) {
return NSOrderedAscending;
}
else if (float1 > float2) {
return NSOrderedDescending;
}
return NSOrderedSame;
}];
This is kinda ugly but should get you started. It's also fragile--if you get something other than NSNumber or NSString for the price it'll likely crash.

Writing a NSArray to file

I am trying to save/write an Array to the documents directory, and I am completely stuck. I have checked this code with multiple sources online. I switched from and NSArray to a NSMutableArray and that didn't work. From what I can tell is the file isn't being written, because test is coming back null. Thanks in advance
NSArray *results = [parser objectWithData:data1];
NSMutableArray *array2 = [[NSMutableArray alloc] initWithArray:results];
// Create a dictionary from the JSON string
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"EmployeeData.plist"];
//NSLog(#"the path is %#, the array is %#", path, array2);
/////write to file/////
[array2 writeToFile:path atomically:YES];
NSMutableArray *test = [[NSMutableArray alloc ]initWithContentsOfFile:path];
NSLog(#"the test is %#", test);
** update **
I added these lines of code
BOOL write = [results writeToFile:path atomically:YES];
NSLog(#"did it right? %#", write);
and write is null, what does that mean?
This is one of the many objects in my Array
{
0 = "<null>";
1 = "John Doe";
10 = 512;
11 = "<null>";
12 = 1;
13 = 1;
2 = Doe;
3 = Jon;
4 = "<null>";
5 = johndoe;
6 = "<null>";
7 = "<null>";
8 = "john#doe.com";
9 = "<null>";
Type = 1;
Active = 1;
Depart = "<null>";
Emp = "<null>";
Ext = "<null>";
FirstName = Jim;
Fl = 512;
Name = "John Doe";
Log = jd;
Mobile = "<null>";
Title = "<null>";
}
Do the null values have anything to do with it?
SOLVED!!
I realized that the null values may have been causing some issues, so i changed my query to take care of that and it saved instantly. The above code is 100% correct and it works!
thanks for the help
As per the documentation, writeToFile: only works if your array's contents are limited to a handful of types (NSString, NSData, NSArray, or NSDictionary objects). If you have any other type of object in your array, then it will not write to file correctly (or at all).
Note also that writeToFile: returns a boolean value indicating whether or not the operation succeeded.
If your array contains incompatible types, you will have to look at using something like NSKeyedArchiver to serialize your data instead.

NSDictionary Filtering and Sorting

I am working on a App that makes use of a JSON API and I am Using the JSON for Objective C Framework to get the Data into a NSDictionary. The dictionary loos like this:
({
admitted = "<null>";
agreed = "<null>";
"area_id" = 1;
"area_name" = "Digitales, Urheber-/Patentrecht, Datenschutz";
created = "2010-08-17 12:41:03";
"current_draft_content" = Bla Bla Bla";
"current_draft_created" = "2010-08-17 12:42:44";
"current_draft_formatting_engine" = compat;
"discussion_url" = "http://piratenpad.de/OpenSourceZwang";
id = 502;
"informed_supporter_count" = 11;
"issue_accepted" = "";
"issue_admission_time" = "8 days";
"issue_closed" = "";
"issue_created" = "2010-08-17 12:41:03";
"issue_discussion_time" = "15 days";
"issue_fully_frozen" = "";
"issue_half_frozen" = "";
"issue_id" = 242;
"issue_population" = 372;
"issue_ranks_available" = 0;
"issue_state" = new;
"issue_verification_time" = "8 days";
"issue_vote_later" = 0;
"issue_vote_now" = 0;
"issue_voter_count" = "<null>";
"issue_voting_time" = "8 days";
name = "Alte & unsupportete Software, muss Open Source werden";
"negative_votes" = "<null>";
"policy_initiative_quorum_den" = 100;
"policy_initiative_quorum_num" = 10;
"policy_issue_quorum_den" = 100;
"policy_issue_quorum_num" = 10;
"policy_majority_den" = 2;
"policy_majority_num" = 1;
"policy_majority_strict" = 1;
"positive_votes" = "<null>";
rank = "<null>";
revoked = "<null>";
"satisfied_informed_supporter_count" = 7;
"satisfied_supporter_count" = 7;
"suggested_initiative_id" = "<null>";
"supporter_count" = 11;
},
{
admitted = "<null>";
agreed = "<null>";
"area_id" = 1;
"area_name" = "Digitales, Urheber-/Patentrecht, Datenschutz";
created = "2010-08-17 14:09:14";
"current_draft_content" = "Bla Bla Bla";
"current_draft_created" = "2010-08-17 14:09:31";
"current_draft_formatting_engine" = compat;
"discussion_url" = "";
id = 508;
"informed_supporter_count" = 0;
"issue_accepted" = "2010-08-14 01:51:45";
"issue_admission_time" = "15 days";
"issue_closed" = "";
"issue_created" = "2010-08-14 01:34:26";
"issue_discussion_time" = "30 days";
"issue_fully_frozen" = "";
"issue_half_frozen" = "";
"issue_id" = 30;
"issue_population" = 603;
"issue_ranks_available" = 0;
"issue_state" = accepted;
"issue_verification_time" = "15 days";
"issue_vote_later" = 9;
"issue_vote_now" = 0;
"issue_voter_count" = "<null>";
"issue_voting_time" = "15 days";
name = "Grundrecht: Alternative Formulierung";
"negative_votes" = "<null>";
"policy_initiative_quorum_den" = 100;
"policy_initiative_quorum_num" = 10;
"policy_issue_quorum_den" = 100;
"policy_issue_quorum_num" = 10;
"policy_majority_den" = 3;
"policy_majority_num" = 2;
"policy_majority_strict" = 0;
"positive_votes" = "<null>";
rank = "<null>";
revoked = {
};
"satisfied_informed_supporter_count" = 0;
"satisfied_supporter_count" = 0;
"suggested_initiative_id" = "<null>";
"supporter_count" = 0;
}
)
What is a good way to get all object where the "issue_id" is 2 oder 6 or what ever to display a grouped UITabeView with all objects with the same "issue_id" in one group?
You can use NSSortDescriptor to sort:
NSSortDescriptor *dateSortDescriptor = [[[NSSortDescriptor alloc] initWithKey:#"issue_id" ascending:YES selector:#selector(compare:)] autorelease];
[youDictionaryArray sortUsingDescriptors:[NSArray arrayWithObjects:dateSortDescriptor, nil]];
And/or NSPredicate to get some ID only:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"(issue_id == %i)", 2];
NSArray *newArray = [youDictionaryArray filteredArrayUsingPredicate:predicate];
There are several ways. You can use NSPredicate and use the NSArray method -filteredArrayUsingPredicate:. Or on iOS 4 you use a filtering block: -indexesOfObjectsPassingTest: then use -objectsAtIndexes: to get the objects.
Otherwise the best is you just iterate through the array and filter the items you want into a new one:
// Given a NSArray *items
NSMutableArray *filteredItems = [NSMutableArray array];
for (NSDictionary *item in items) {
if (/* your condition */) {
[filteredItems addObject: item];
}
}