Manipulating Facebook/JSON data - objective-c

I'm trying to handle Facebook JSON data and transform it into a NSMutable Dictionary, but I'm getting (null) when I try to print the data. Although when I try to do a count, I get a number.
User_likes is NSMutableDictionary which is globally defined. I'm getting (null) on this line:
NSLog(#"User likes: %#", user_likes);
This is my code:
NSString *query =
#"SELECT page_id, type FROM page_fan WHERE uid = me() ";
// Set up the query parameter
NSDictionary *queryParam = #{ #"q": query };
// Make the API request that uses FQL
[FBRequestConnection startWithGraphPath:#"/fql"
parameters:queryParam
HTTPMethod:#"GET"
completionHandler:^(FBRequestConnection *connection,
id results,
NSError *error) {
if (error) {
NSLog(#"Error: %#", [error localizedDescription]);
} else {
user_likes = [NSJSONSerialization JSONObjectWithData:results options:kNilOptions error:&error];
NSLog(#"User likes: %#", user_likes);
NSInteger* n_user_likes = [results count];
NSInteger* n_user_likes2 = [user_likes count];
NSLog(#"n user likes %qi", n_user_likes);
NSLog(#"n user likes2 %qi", n_user_likes2);
id val = nil;
id values = [[user_likes allKeys] objectAtIndex:0 ];
NSLog(#"values id %#", values);
When I print results, I get a lot of data from Facebook, this is a sample of it:
data = (
{
"page_id" = 253370381511811;
type = "PUBLIC FIGURE";
},
{
"page_id" = 148389618201;
type = "LOCAL BUSINESS";
},
{
"page_id" = 213631462169238;
type = COMMUNITY;
},
{
"page_id" = 162297750451425;
type = "NON-PROFIT ORGANIZATION";
},
{
"page_id" = 503620106320217;
type = "MEDIA/NEWS/PUBLISHING";
},

you can't do directly
user_likes = [NSJSONSerialization JSONObjectWithData:results options:kNilOptions error:&error];
you need first create a dictionary with the data in results like this:
NSDictionary *dictionary = [NSDictionary dictionaryWithJSONData:results];
user_likes = [NSString stringWithFormat:#"%d",[[dictionary objectForKey:#"value_of_the_likes"] intValue]];
NSLog(#"%#",user_likes);
NSLog(#"%#",dictionary);
EDIT:
Please, create this class to your project and import in the class where you need use this.
#import <Foundation/Foundation.h>
#interface NSDictionary (JSONExtensions)
+(NSDictionary*)dictionaryWithJSONData:(NSData*)data;
-(NSData*)JSONValue;
-(NSString*)JSONString;
#end
#implementation NSDictionary(JSONExtensions)
+(NSDictionary*)dictionaryWithJSONData:(NSData*)data{
NSError *error = nil;
NSDictionary *result = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
if(error){
NSLog(#"%#",error);
return nil;
};
return result;
}
-(NSData*)JSONValue{
NSError *error = nil;
NSData *result = [NSJSONSerialization dataWithJSONObject:self options:kNilOptions error:&error];
if(error){
NSLog(#"%#",error);
return nil;
};
return result;
}
-(NSString*)JSONString{
return [[NSString alloc] initWithData:self.JSONValue encoding:NSUTF8StringEncoding];
}
#end
Hope it can help you.

maybe you forget set up options:
NSJSONReadingOptions options = NSJSONReadingAllowFragments | NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves;
user_likes = [NSJSONSerialization JSONObjectWithData:results options:options error:&error];
i hope this be useful for you!
UPDATE:
Check this :
NSJsonSerialzation not parsing results from Facebook - Cocoa error 3840
Let me know if that helps you!

Related

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 multiple JSON in Objective C

Long story, short. I need to access just the parent in the JSON file.
How to parse multiple json in objective-c? )
I need to access the author > NAME from this JSON. (*removed link)
The code is:
NSURL *blogURL = [NSURL URLWithString:#"*removed link"];
NSData *jsonData = [NSData dataWithContentsOfURL:blogURL];
NSError *error = nil;
NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
// NSLog(#"%#",dataDictionary);
self.blogPosts = [NSMutableArray array];
NSArray *blogPostsArray = [dataDictionary objectForKey:#"posts"];
for (NSDictionary *bpDictionary in blogPostsArray) {
BlogPost *blogPost = [BlogPost blogPostWithTitle:[bpDictionary objectForKey:#"title"]];
blogPost.author = [bpDictionary objectForKey:#"author"];
blogPost.thumbnail = [bpDictionary objectForKey:#"thumbnail"];
blogPost.date = [bpDictionary objectForKey:#"date"];
blogPost.url = [NSURL URLWithString:[bpDictionary objectForKey:#"url"]];
[self.blogPosts addObject:blogPost];
}
How can i make it access that value ?
You should be able to use the dot notation
JSON
{
"author": {
"name" : "mckeejm"
}
}
Objective C:
blogPost.author = [bpDictionary valueForKeyPath:#"author.name"];
updated Thanks #Martin

NSCFString objectAtIndex: unrecognized selector sent to instance Objective C [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I am trying to get some json data and show it as text in a UILabel but I keep on getting a app crash with the following error -[__NSCFString objectAtIndex:]: unrecognized selector sent to instance 0x1f8cfff0?
Here is my code and the json response. I see in my log that I am getting the Name from the call but the app bombs out the that error. I have 2 UILabel blocks, one of which shows a text format of the json response and the other the actual json response in text.
I'm trying to pull the name of the person, I can see Bilbo Baggins in the log when the json comes back.
Here is my json output:
{"ProfileID":34,"ProfilePictureID":20,"Name":"Bilbo Baggins","Clients":[{"ClientID":91,"Name":"Fnurky"},{"ClientID":92,"Name":"A different client"},{"ClientID":95,"Name":"Second Community"},{"ClientID":96,"Name":"Britehouse"}]}
and my code to try show it as a uilabel as text.
#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) //1
#define kLatestKivaLoansURL [NSURL URLWithString: #"http://www.ddproam.co.za/Central/Profile/JSONGetProfileForUser"] //2
#import "JsonViewController.h"
#interface NSDictionary(JSONCategories)
+(NSDictionary*)dictionaryWithContentsOfJSONURLString:(NSString*)urlAddress;
-(NSData*)toJSON;
#end
#implementation NSDictionary(JSONCategories)
+(NSDictionary*)dictionaryWithContentsOfJSONURLString:(NSString*)urlAddress
{
NSData* data = [NSData dataWithContentsOfURL: [NSURL URLWithString: urlAddress] ];
__autoreleasing NSError* error = nil;
id result = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
if (error != nil) return nil;
return result;
}
-(NSData*)toJSON
{
NSError* error = nil;
id result = [NSJSONSerialization dataWithJSONObject:self options:kNilOptions error:&error];
if (error != nil) return nil;
return result;
}
#end
#implementation JsonViewController
- (void)viewDidLoad
{
[super viewDidLoad];
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL: kLatestKivaLoansURL];
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
});
}
- (void)fetchedData:(NSData *)responseData {
//parse out the json data
NSError* error;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData //1
options:kNilOptions
error:&error];
NSArray* defineJsonData = [json objectForKey:#"Name"]; //2
NSLog(#"Name: %#", defineJsonData); //3
// 1) Get the latest loan
NSDictionary* loan = [defineJsonData objectAtIndex:0];
// 3) Set the label appropriately
humanReadble.text = [NSString stringWithFormat:#"Hello: %#",
[(NSDictionary*)[loan objectForKey:#"Name"] objectForKey:#"Name"]];
//build an info object and convert to json
NSDictionary* info = [NSDictionary dictionaryWithObjectsAndKeys:
[loan objectForKey:#"Name"],
nil];
//convert object to data
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:info
options:NSJSONWritingPrettyPrinted
error:&error];
//print out the data contents
jsonSummary.text = [[NSString alloc] initWithData:jsonData
encoding:NSUTF8StringEncoding];
}
#end
A combination of – sorry – poor var names and lost in a complex structure.
First:
Here you get the complete JSON as Dictionary:
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData //1
options:kNilOptions
error:&error];
According to your Q, this has this structure:
{
"ProfileID":34,
"ProfilePictureID":20,
"Name":"Bilbo Baggins",
"Clients":
[
{
"ClientID":91,
"Name":"Fnurky"
},
{
"ClientID":92,
"Name":"A different client"
},
{
"ClientID":95,
"Name":"Second Community"
},
{
"ClientID":96,
"Name":"Britehouse"
}
]
}
Second:
With the next statement, you simply get the name of obviously something like a person:
NSArray* defineJsonData = [json objectForKey:#"Name"]; //2
There is the root:
what you get – look at your JSON – is:
"Name":"Bilbo Baggins",
You get the object for the key Name. The var, holding the reference to the result should be called expressing this. Let's change this:
NSArray* name = [json objectForKey:#"Name"]; //2
Next – look at your JSON – the object behind that key is an instance of NSString, not NSArray. Let's repair this:
NSString* name = [json objectForKey:#"Name"]; //2
Third:
Doing so will the compiler make throwing out an error. This is because of this statement:
NSDictionary* loan = [defineJsonData objectAtIndex:0];
Changed to the new var name:
NSDictionary* loan = [name objectAtIndex:0];
The compiler is right: You do not have an array, so you cannot send objectAtIndex:.

Strange NSData Output

I have some unexpected results coming from the following code:
- (NSData *)postDataWithDict:(NSDictionary *)postDict
{
// Assume key is urlValid
NSUInteger postCount = [postDict count];
NSMutableArray *buildArray = [[NSMutableArray alloc] initWithCapacity:postCount];
for (NSString *key in postDict) {
//post data is key=value&key=value&key=value...
// start with key
NSMutableString *arrayLine = [NSMutableString stringWithString:key];
[arrayLine appendString:#"="];
// analyze and then append value
id postValue = [postDict objectForKey:key];
if ([postValue isKindOfClass:[NSNumber class]]) {
NSString *valueString = [NSString stringWithFormat:#"%#",postValue];
[arrayLine appendString:valueString];
}
else if ([postValue isKindOfClass:[NSString class]]) {
NSString *urlEncodedString = [self urlEncodeValue:postValue];
[arrayLine appendString:urlEncodedString];
}
else {
NSLog(#"postKey: %#, postValue class:%#", key, [postValue class]);
NSError *jsonError = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:postValue
options:0
error:&jsonError];
if (jsonError != nil) {
NSLog(#"JSON serialization failed: %# - %#", [jsonError localizedDescription], [jsonError userInfo]);
NSLog(#"value: %#", postValue);
}
else {
// need to urlencode
NSString *stringifyJSON = [NSString stringWithUTF8String:[jsonData bytes]];
NSString *urlJSONstring = [self urlEncodeValue:stringifyJSON];
[arrayLine appendString:urlJSONstring];
}
}
[buildArray addObject:arrayLine];
}
NSString *postString = [buildArray componentsJoinedByString:#"&"];
NSData *postData = [postString dataUsingEncoding:NSUTF8StringEncoding];
//testing
NSLog(#"Post Dict: %#", postDict);
NSLog(#"Post Array: %#", buildArray);
NSLog(#"Post String: %#", postString);
NSLog(#"Post Data: %#", [NSString stringWithUTF8String:[postData bytes]]);
return postData;
}
My //testing log results:
Post Dict: {
authenticationString = b3210c0bc6d2c47f4c2f7eeea12e063d;
dataMode = updateSingle;
dateCreated = "374300293.81108";
dateModified = "374609294.313093";
dateSynced = "374610683.588062";
entityName = CommodityTypes;
myName = 21;
sortKey = 21;
username = iPhoneAdamek;
usernameString = iPhoneAdamek;
uuidKey = "53403EAE-DD4F-4226-A979-316EF7F43991";
}
Post Dict looks good. Just what I wanted.
2012-11-14 13:31:23.640 FoodyU[11393:907] Post Array: (
"myName=21",
"dataMode=updateSingle",
"dateSynced=374610683.588062",
"uuidKey=53403EAE-DD4F-4226-A979-316EF7F43991",
"sortKey=21",
"dateModified=374609294.313093",
"entityName=CommodityTypes",
"dateCreated=374300293.81108",
"authenticationString=b3210c0bc6d2c47f4c2f7eeea12e063d",
"usernameString=iPhoneAdamek",
"username=iPhoneAdamek"
)
Post Array looks good. Strings are all set to be concatenated for a HTTP POST string.
2012-11-14 13:31:23.641 FoodyU[11393:907] Post String: myName=21&dataMode=updateSingle&dateSynced=374610683.588062&uuidKey=53403EAE-DD4F-4226-A979-316EF7F43991&sortKey=21&dateModified=374609294.313093&entityName=CommodityTypes&dateCreated=374300293.81108&authenticationString=b3210c0bc6d2c47f4c2f7eeea12e063d&usernameString=iPhoneAdamek&username=iPhoneAdamek
Post String looks good. I'm ready to convert it to data to use in [NSMutableURLRequest setHTTPBody:postData].
2012-11-14 13:31:23.643 FoodyU[11393:907] Post Data: myName=21&dataMode=updateSingle&dateSynced=374610683.588062&uuidKey=53403EAE-DD4F-4226-A979-316EF7F43991&sortKey=21&dateModified=374609294.313093&entityName=CommodityTypes&dateCreated=374300293.81108&authenticationString=b3210c0bc6d2c47f4c2f7eeea12e063d&usernameString=iPhoneAdamek&username=iPhoneAdamekoneAdamek;
usernameString = iPhoneAdamek;
uuidKey = "53403EAE-DD4F-4226-A
WTF??? How did &username=iPhoneAdamek become &username=iPhoneAdamekoneAdamek;
usernameString = iPhoneAdamek;
uuidKey = "53403EAE-DD4F-4226-A?
I'm fairly new to Cocoa. Is there something wrong with:
NSData *postData = [postString dataUsingEncoding:NSUTF8StringEncoding];
or
NSLog(#"Post Data: %#", [NSString stringWithUTF8String:[postData bytes]]);
You shouldn't be using NSLog of NSData as,
NSLog(#"Post Data: %#", [NSString stringWithUTF8String:[postData bytes]]);
Instead use it as,
NSLog(#"Post Data: %#", [[NSString alloc] initWithData:postData encoding:NSUTF8StringEncoding]);
[NSString stringWithUTF8String:[postData bytes]] always returns unexpected results.
As per documentation for bytes,
bytes: Returns a pointer to the receiver’s contents.
And as per Apple documentation for stringWithUTF8String,
stringWithUTF8String:
Returns a string created by copying the data from a given C array of UTF8-encoded bytes.
Parameters: bytes - A NULL-terminated C array of bytes in UTF8 encoding.
So when you are using [postData bytes], it is not NULL-terminated and hence when you are using with stringWithUTF8String returns the data written in memory till it encounters a NULL-termination.

JSON and 2D array

The following is encoded JSON data from a PHP webpage.
{
{
"news_date" = "2011-11-09";
"news_id" = 5;
"news_imageName" = "newsImage_111110_7633.jpg";
"news_thread" = "test1";
"news_title" = "test1 Title";
},
{
"news_date" = "2011-11-10";
"news_id" = 12;
"news_imageName" = "newsImage_111110_2060.jpg";
"news_thread" = "thread2";
"news_title" = "title2";
},
// and so on...
}
I'd like to grab one buch of info (date/id/image/thread/title), and store it as an instance of a class. However, I have no clue on how to access each object in 2D arrays.
The following is the code I've written to test if I can access them, but it doesn't work.
What would be the problem?
NSURL *jsonURL = [NSURL URLWithString:#"http://www.sangminkim.com/UBCKISS/category/news/jsonNews.php"];
NSString *jsonData = [[NSString alloc] initWithContentsOfURL:jsonURL];
SBJsonParser *parser = [[SBJsonParser alloc] init];
contentArray = [parser objectWithString:jsonData];
NSLog(#"array: %#", [[contentArray objectAtIndex:0] objectAtIndex:0]); // CRASH!!
In JSON terminology, that’s not a two-dimensional array: it’s an array whose elements are objects. In Cocoa terminology, it’s an array whose elements are dictionaries.
You can read them like this:
NSArray *newsArray = [parser objectWithString:jsonData];
for (NSDictionary *newsItem in newsArray) {
NSString *newsDate = [newsItem objectForKey:#"news_date"];
NSUInteger newsId = [[newsItem objectForKey:#"news_id"] integerValue];
NSString *newsImageName = [newsItem objectForKey:#"news_imageName"];
NSString *newsThread = [newsItem objectForKey:#"news_thread"];
NSString *newsTitle = [newsItem objectForKey:#"news_title"];
// Do something with the data above
}
You gave me a chance to checkout iOS 5 Native JSON parser, so no external libraries needed, try this :
-(void)testJson
{
NSURL *jsonURL = [NSURL URLWithString:#"http://www.sangminkim.com/UBCKISS/category/news/jsonNews.php"];
NSData *jsonData = [NSData dataWithContentsOfURL:jsonURL];
NSError* error;
NSArray* json = [NSJSONSerialization
JSONObjectWithData:jsonData //1
options:kNilOptions
error:&error];
NSLog(#"First Dictionary: %#", [json objectAtIndex:0]);
//Log output:
// First Dictionary: {
// "news_date" = "2011-11-09";
// "news_id" = 5;
// "news_imageName" = "newsImage_111110_7633.jpg";
// "news_thread" = " \Uc774\Uc81c \Uc571 \Uac1c\Ubc1c \Uc2dc\Uc791\Ud574\Ub3c4 \Ub420\Uac70 \Uac19\Uc740\Ub370? ";
// "news_title" = "\Ub418\Ub294\Uac70 \Uac19\Uc9c0?";
// }
//Each item parsed is an NSDictionary
NSDictionary* item1 = [json objectAtIndex:0];
NSLog(#"Item1.news_date= %#", [item1 objectForKey:#"news_date"]);
//Log output: Item1.news_date= 2011-11-09
}