I'm using FQL to get the names of the nearest 5 places like so:
- (void)facebookPlaces {
NSString *query = #"SELECT name FROM place WHERE distance(latitude, longitude, \"39.750655\", \"-104.999127\") < 500 ORDER BY distance(latitude, longitude, \"23.750655\", \"-180.999127\") limit 5";
// 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 result,
NSError *error) {
if (error) {
NSLog(#"Error: %#", [error localizedDescription]);
} else {
NSLog(#"Result: %#", result);
// Store the result in an NSData object
NSData *nameData = [result data];
NSLog(#"Test data reads: %#", nameData);
}
}];
The result is neatly returned like this:
Result: {
data = (
{
name = "T|aco";
},
{
name = "ChoLon Bistro";
},
{
name = "Illegal Pete's Lodo";
}, etc...
I stored the data in an NSData object and it reads the exact same way. I would like to parse the result in a way that I can get all of the names in a simple way, and print them to the log. The only way that I could think of was manually parsing the NSData or the result, but I have no idea how to make it only take the stuff in the quotes next to name =. I'm very new to FQL and objective-c, does anyone know how I can do this?
When I researched this, I saw an awesome JSON example that took everything next to name = and stored it in an array. Although it was meant for android and I couldn't figure out how to make it work in iOS. That is ideally what I'm trying to do.
The result is being parsed as a JSON object into an NSDictionary. You can tell because the result object starts with {}. Inside the data key you see an array (denoted by ()).
So to get an array of names you can do this:
NSMutableArray *names = [NSMutableArray array];
for (NSDictionary *item in result[#"data"]) {
[names addObject:item[#"name"]];
}
Is this what you're after?
Related
I'm trying to check if NSString 'testing' (47) exists inside of my NSMutableArray 'self.checkfriendData'. I'm using the code below, though after logging my if statement it appears as though it's never executed (even though the statement is true - see console data below, uid = 47, and thus hiding my object should fire?) Any idea as to why this isn't working? Help is much appreciated!
ViewController.m
NSMutableDictionary *viewParams3 = [NSMutableDictionary new];
[viewParams3 setValue:#"accepted_friends" forKey:#"view_name"];
[DIOSView viewGet:viewParams3 success:^(AFHTTPRequestOperation *operation, id responseObject) {
self.checkfriendData = (NSMutableArray *)responseObject;
NSString *testing = #"47";
NSArray *friendorNo = self.checkfriendData;
if ([friendorNo containsObject:testing]) // YES
{
self.addFriend.hidden = YES;
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
}];
Here's what's inside self.checkfriendData:
2017-05-18 19:36:07.266529-0700 This is the friend data check (
{
body = "My name is Britt";
friendphoto = "/sites/default/files/stored/x.jpg";
"node_title" = "Britt";
uid = 47;
}
)
It appears that your NSArray contains NSDictionarys and you are asking if the array contains an NSString. The answer will always be no as the array doesn't directly contain any NSStrings.
If you want to search for the uid of 47 you will have to iterate over the array and check the uid key of each NSDictionary for the value 47.
The code for this would look something like:
for (NSDictionary *dict in friendorNo) {
if ([dict[#"uid"] isEqualToString:testing]) {
self.addFriend.hidden = YES;
}
}
This has got to be something obvious that I am doing wrong. I have been banging my head against a wall trying to figure out what is going on. I already have this json parsing done in the android version of my app, now trying to parse this simple json in xcode and can't get it done.
NSError *myError = nil;
NSDictionary *res = [NSJSONSerialization JSONObjectWithData:self.responseData options:kNilOptions error:&myError];
NSLog([res objectForKey:#"Date"]);
This code get me the "unrecognized selector sent to instance" error.
Here is the json data and you can see Date is one of the objects:
[{"Date":"2016-06-17T22:56:33.0811255-05:00"}]
Thanks in advance for any help on this issue. I've tried to simplify this post, but if more info is needed I will try and quickly provide.
http://i.stack.imgur.com/Y5fsT.png
JSONObjectWithData is returning an array of dictionaries and not a dictionary. Your print out of the raw JSON confirms this:
[{"Date":"2016-06-17T22:56:33.0811255-05:00"}] // This is an array
However you're attempting to treat that response object like a dictionary. In doing so you're calling a dictionary method (objectForKey:) on an array. This results in a crash. Try something like this:
NSError *error = nil;
id responseObject = [NSJSONSerialization JSONObjectWithData:self.responseData options:kNilOptions error:&error];
if (error)
{
// Handle error
return;
}
NSLog(#"%#", responseObject);
if ([responseObject isKindOfClass:[NSArray class]])
{
NSArray *responseArray = (NSArray *)responseObject;
for (id item in responseArray)
{
NSLog(#"%#", item);
if ([item isKindOfClass:[NSDictionary class]])
{
NSDictionary *dictionary = (NSDictionary *)item;
NSString *dateString = [dictionary objectForKey:#"Date"];
NSLog(#"%#", dateString);
}
}
}
else
{
// responseObject is not an array...
}
I'm pretty sure this is because you should first set res as [NSDictionary]. Then pick the first element in that array and then get objectForKey: "Date". Normal JSON Data starts with a {, this starts with a [. Which means it's an array.
You can see it for yourself in the screenshot when it says #: 1 Element . THEN it says 1 key/value pair. The NSDictionary is inside an array.NSError
Try this code:
*myError = nil;
[NSDictionary] *res = [NSJSONSerialization JSONObjectWithData:self.responseData options:kNilOptions error:&myError];
if (res.count > 0) {
NSLog([res[0] objectForKey:#"Date"]);
}
I am using facebook SDK4.0 in ios i am trying to retrieve logged in user's friendlist by using taggable_friends. I have been able to achieve that.The whole friend list is showing but the problem is with the names. In the returning dictionary some names are showing weird numbers. I've found the reason as well, because the names are of language other than english, most of them are of bengali.Is there any way to get the names in their respective languages?? I am adding the method and snippet of what weird names i am getting.Please help if u know something of this sort!!please!!
-(void) getMineFriends
{
NSDictionary *limitDictionary = [NSDictionary dictionaryWithObjectsAndKeys:#"600",#"limit", nil];
[[[FBSDKGraphRequest alloc]initWithGraphPath:#"me/taggable_friends" parameters:limitDictionary HTTPMethod:#"GET"]startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
NSLog(#"friends = %#",[result objectForKey:#"data"] );
}];
}
Here is an example of the weird name: name = "\U0995\U09be\U099c\U09c0 \U09a4\U09c1\U09b7\U09be\U09b0";
The problem is solved.The problem was that i was accessing the result with object key "data" but when i initialized an array of dictionary with result with object key "data" and then i accessed the name with object key "name" and it came out good.sorry for the inconvenience :P
-(void) getMineFriends
{
NSDictionary *limitDictionary = [NSDictionary dictionaryWithObjectsAndKeys:#"600",#"limit", nil];
[[[FBSDKGraphRequest alloc]initWithGraphPath:#"me/taggable_friends" parameters:limitDictionary HTTPMethod:#"GET"]startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
NSArray *friendsarray = [result objectForKey:#"data"];
for (NSDictionary *friend in friendsarray) {
NSLog(#"i have a friend named %#",[friend objectForKey:#"name"]);
}
}];
}
here is the changed code :D
I'm trying to get the data from a JSON response object in my iOS app after I log in. I keep getting this error though.
Error:
'NSInvalidArgumentException', reason: '-[__NSCFArray objectForKeyedSubscript:]: unrecognized selector sent to instance 0x8fc29b0'
Here is my code for the request, I'm using AFNetworking:
self.operation = [manager GET:urlString parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSDictionary *JSON = (NSDictionary *)responseObject;
NSDictionary *user = JSON[#"user"];
NSString *token = user[#"auth_token"];
NSString *userID = user[#"id"];
// NSString *avatarURL = user[#"avatar_url"];
// weakSelf.credentialStore.avatarURL = avatarURL;
weakSelf.credentialStore.authToken = token;
weakSelf.credentialStore.userId = userID;
weakSelf.credentialStore.username = self.usernameField.text;
weakSelf.credentialStore.password = self.passwordField.text;
[SVProgressHUD dismiss];
[self dismissViewControllerAnimated:YES completion:nil];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (operation.isCancelled) {
return;
}
[SVProgressHUD showErrorWithStatus:#"Login Failed"];
NSLog(#"%#", error);
}];
What the JSON response object looks like logged:
<__NSCFArray 0x8cac0b0>(
{
user = {
"auth_token" = b3a18e0fb278739649a23f0ae325fee1e29fe5d6;
email = "jack#jack.com";
id = 1;
username = jack;
};
}
)
I'm converting the array to a Dictionary using pointers like this:
EDIT: As pointed out in the comments incase anyone else stumbles across this with limited knowledge in iOS. I'm casting here not converting. See the answers for a full explanation.
NSDictionary *JSON = (NSDictionary *)responseObject;
I'm new to iOS, apologies if problem is obvious.
Thanks for any help.
The "conversion" you do is not doing any conversion, it's a cast. This simply tells the compiler to ignore the type it knows for this object and act as if it's the type you pass it.
Looking at the output you have, you don't get a dictionary back, but an array of dictionaries with a single dictionary. To get to the first dictionary you can use this instead of the cast:
NSDictionary *JSON = [responseObject objectAtIndex:0];
Note that since you get your data from a web service, you should probably also check if the contents you get are what you expect.
You say:
I'm converting the array to a Dictionary using pointers like this:
But that is not what you are doing. You are casting it, but the underlying object is still an array.
From the JSON response you can see that those JSON is constructed as an array with a single element which is a dictionary. You can get to the dictionary by calling [responseObject firstObject];. Of course, so that you don't get error going in the other direction, you should check how the input is constructed before calling any array or dictionary specific methods on the response object.
You have to convert your self but do not use casting.
Or, this is the code to detect if a json object is an array or dictionary
NSError *jsonError = nil;
id jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&jsonError];
if ([jsonObject isKindOfClass:[NSArray class]]) {
NSLog(#"its an array!");
NSArray *jsonArray = (NSArray *)jsonObject;
NSLog(#"jsonArray - %#",jsonArray);
}
else {
NSLog(#"its probably a dictionary");
NSDictionary *jsonDictionary = (NSDictionary *)jsonObject;
NSLog(#"jsonDictionary - %#",jsonDictionary);
}
I'm trying to implement Facebook iOS SDK 3.1.1 into my app and I'm having issues.
When I try to run
NSString *query =
#"SELECT uid, name, pic_square FROM user WHERE uid IN "
#"(SELECT uid2 FROM friend WHERE uid1 = me() LIMIT 25)";
// Set up the query parameter
NSDictionary *queryParam =
[NSDictionary dictionaryWithObjectsAndKeys:query, #"q", nil];
// Make the API request that uses FQL
[FBRequestConnection startWithGraphPath:#"/fql"
parameters:queryParam
HTTPMethod:#"GET"
completionHandler:^(FBRequestConnection *connection,
id result,
NSError *error) {
if (error) {
NSLog(#"Error: %#", [error localizedDescription]);
} else {
NSLog(#"Result: %#", result);
}
}];
My app crashes on NSLog(#"Result: %#", result); If someone could help me out that would be much appreciated. I'm trying to return the user's friends list with each friend's user data. Below is the Debug Navigation view.
Thanks,
Wes
The result you can expect here is a dictionary containing all the friend data you need. You can make sense of it like this:
NSDictionary *resultDict = (NSDictionary *)result;
NSArray *friendsArr = [resultDict objectForKey:#"data"];
NSMutableArray *resultArr = [NSMutableArray array];
for (FBGraphObject *friendObj in friendsArr) {
NSString *name = [friendObj objectForKey:#"name"];
NSString *imageUrl = [friendObj objectForKey:#"pic_square"];
long long uid = [[friendObj objectForKey:#"uid"] longLongValue];
}
I rebuild my project from scratch by adding each controller and library back into an empty project. It appears now everything is working correctly. Same code same spot.