I am attempting to determine who among my facebook friends are currently using my app. The general wisdom, as far as I can tell, is to use the graph api, and send the 'installed' parameter when getting your friends list. This does not seem to be working for me, and I am wondering where I am going wrong. This is my code:
First, the permissions in effect:
_facebookPermissions = #[#"publish_stream", #"read_stream", #"friends_photos", #"user_photos"];
Now the SLRequest and it's setup:
NSString *username = [[NSUserDefaults standardUserDefaults] objectForKey:#"fbUserID"];
NSString *urlString = [NSString stringWithFormat:#"https://graph.facebook.com/%#/friends", username];
NSURL *friendsList = [NSURL URLWithString:urlString];
NSDictionary *friendsListParameters = #{#"fields": #"id,name,picture,installed"};
SLRequest *getFriends = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodGET URL:friendsList parameters:friendsListParameters];
Now a sample result:
{
id = 10000123456911;
name = "Don Dobrian";
picture = {
data = {
"is_silhouette" = 0;
url = "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-ash3/41664_100001237218111_2269_q.jpg";
};
};
},
As you can see, the permissions will get me almost everything. But there is no indication at all that the 'installed' parameter was even noticed. So here are my questions, the answer to any one of which would solve my problem:
Is this how you do it? What permissions are you using to get the 'installed' status?
Is there a better way to get this information using the iOS Social Framework?
As it happens, Ming Li was dead on with his assessment. The parameter is returned only if the friend has the app installed. An example of each:
},
{
id = 12645478730;
installed = 1;
name = "Edwin Robertson";
picture = {
data = {
"is_silhouette" = 0;
url = "https://fbcdn-profile-a.akamaihd.net/...";
};
};
},
{
id = 12645478730;
name = "Greg Walker";
picture = {
data = {
"is_silhouette" = 0;
url = "https://fbcdn-profile-a.akamaihd.net...";
};
};
},
What is odd is that I was certain this did not work as expected a couple months ago when I last worked on it. Perhaps FB silently fixed something, perhaps my test user was having some issues, maybe I was just too tunnel visioned to see the fix in front of me. Who knows. But if you follow my method above, you should get this result. Good luck!
Related
Working on an iPhone App fetches newspaper articles from the web.
For performance purposes only the last 10 articles will be send per request.
All works as expected but how do I get the next 10 articles when user scrolls down and wants to read more?
Working: First request gives me articles: 1 - 10
NOT Working: Request send again should give me articles: 11 - 20 (by setting an offset)
(When I read the API documentation I am supposed to set an offset to get the next articles but it doesn't work, I always get the same first 10 articles based on my search query.)
Following request searches for the last 10 articles with the keyword frankfurt in it
and sets an offset of 10 which should send me the next 10 articles when I send the request again.
http://api.zeit.de/content?q=frankfurt&limit=10&offset=10&api_key=MY_API_KEY
From the API documentation:
Search results are limited to 10 matches by default. You can increase this value with the limit parameter. To iterate over the resultset, repeat your request with the offset parameter set to multiples of the limit.
UPDATE:
- (IBAction)runBtnTapped:(id)sender
{
NSError *error;
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://api.zeit.de/content?q=frankfurt&fields=teaser_title%20AND%20release_date&limit=5&offset=5&sort=release_date%20desc&api_key=123456789"]];
NSDictionary *dictFromData = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSArray *array = dictFromData[#"matches"];
NSLog(#"%#", array);
}
CONSOLE OUTPUT:
2013-01-10 17:21:39.261 ZEITreisen[94644:c07] (
{
"release_date" = "2013-01-03T06:00:00Z";
"teaser_title" = "Im Stich gelassen";
},
{
"release_date" = "2012-12-28T13:18:58Z";
"teaser_title" = "Serbiens Nachwuchs baut den Weg nach Europa";
},
{
"release_date" = "2012-12-27T10:18:07Z";
"teaser_title" = "Das Fu\U00dfballgott bestrafte Hoffenheim";
},
{
"release_date" = "2012-12-27T06:00:00Z";
"teaser_title" = "Sind Fitschen und Jain die Richtigen f\U00fcr 2013?";
},
{
"release_date" = "2012-12-27T06:00:00Z";
"teaser_title" = Sparen;
}
)
2013-01-10 17:21:43.447 ZEITreisen[94644:c07] (
{
"release_date" = "2013-01-03T06:00:00Z";
"teaser_title" = "Im Stich gelassen";
},
{
"release_date" = "2012-12-28T13:18:58Z";
"teaser_title" = "Serbiens Nachwuchs baut den Weg nach Europa";
},
{
"release_date" = "2012-12-27T10:18:07Z";
"teaser_title" = "Das Fu\U00dfballgott bestrafte Hoffenheim";
},
{
"release_date" = "2012-12-27T06:00:00Z";
"teaser_title" = "Sind Fitschen und Jain die Richtigen f\U00fcr 2013?";
},
{
"release_date" = "2012-12-27T06:00:00Z";
"teaser_title" = Sparen;
}
)
Found the solution. Offset must increase EVERY time you re-call it then it works.
Example:
First call: (NO OFFSET)
http://api.zeit.de/content?q=frankfurt&fields=teaser_title%20AND%20release_date&limit=5&sort=release_date%20desc&api_key=123456789
Next time you call the API just add 5 to the offset and it works.
http://api.zeit.de/content?q=frankfurt&fields=teaser_title%20AND%20release_date&limit=5&offset=5&sort=release_date%20desc&api_key=123456789
Note: Second request leaves the first 5 search results out and delivers the next 5.
You might running into an instance where the API incorrectly prioritizes some parameters over others to the point of ignoring your offset. Try removing your limit since you're using the default, or try using different numbers between limit and offset. There may be some poor comparisons being made that are preventing your offset from being accepted. Without API docs, it is hard to say though what could be going wrong. I would second #Geraud.ch's suggestion though if modifying your query string doesn't work: contact the API provider.
Edit just realized you posted the actual URL. I'm searching for docs now.
Without any code, it's hard to say. But what you have in mind seems good.
You might have an error in your request (have you logged them to see if the parameter is well set, without any typo? what about the response?) or the API might have an error. In that case, you should contact the provider directly.
Is it possible to download the documents from my gmail account to documents folder for iphone app. Actually i used Google Doc API and get Feed by using
-(GDataServiceGoogleDocs *)getdocservice
{
static GDataServiceGoogleDocs *docs = nil;
if(!docs)
{
docs = [[GDataServiceGoogleDocs alloc]init];
[docs setShouldCacheResponseData:YES];
[docs setServiceShouldFollowNextLinks:YES];
[docs setIsServiceRetryEnabled:YES];
[docs setUserCredentialsWithUsername:#"gmailaccount#gmail.com" password:#"password"];
}
return docs;
}
//##############
GDataServiceTicket *ticket;
#pragma mark docService
docsService = [self getdocservice];
NSURL *feedURL = [GDataServiceGoogleDocs docsFeedURL];
GDataQueryDocs *queryDocs = [GDataQueryDocs documentQueryWithFeedURL:feedURL];
[queryDocs setMaxResults:1000];
[queryDocs setShouldShowFolders:YES];
ticket = [docsService fetchFeedWithQuery:queryDocs delegate:self didFinishSelector:#selector(docsFetchTicket:finishedWithFeed:error:)];
// call back
-(void)docsFetchTicket:(GDataServiceTicket *)ticket finishedWithFeed:(GDataFeedDocList *)feed error:(NSError *)error
{
GDataFeedDocList *mDocListFeed = feed;
int numDocs = [[feed entries] count];
NSLog(#"NumDocs :%d\n Feed :%#",numDocs,mDocListFeed);
for (int i=0; i<numDocs; i++) {
GDataEntryDocBase *docEntry = [mDocListFeed entryAtIndex:i];
NSLog(#"\n############ DocTitle :%#\n\n",[[docEntry content] sourceURL] );
}
}
it is displaying all the documents from my account .
But i am not getting how to download those documents into my app document folder. If any one have idea please help me.
(Disclaimer: I am not proficient in Objective-C)
Each entries of the GDataFeedDocList should contain a link which points to the actual file's data. The link is contained in its "Content" attribute. In your code it seems that you have that URL (sourceURL) you need to download the content using an authenticated request to taht URL.
You should also now use the newer Drive API instead of the DocumentList API using the newer Objective-C client library:
http://code.google.com/p/google-api-objectivec-client/
I'm using the XMLReader plugin found here https://github.com/Insert-Witty-Name/XML-to-NSDictionary to convert my XML data into an NS-Dictionary, but I am confused by how the dictionary is being set up. Here is what I am given:
{
response = {
"#status" = ok;
authentication = {
"#description" = "The username you provided is valid.";
"#login" = USERNAME;
"#response" = success;
"#user_id" = USERID;
};
};
}
I am trying to take the response object and say if key is equal to success then do something, but I'm not sure if this dictionary is even set up correctly.
Despite the weirdness of the #names as keys, it seems valid.
You could easily ask for your element response ( [ objectForKey:#"response"] ), get the [ objectForKey:#"authentication"] and then [ objectForKey:#"#response"] to check [yourString isEqualToString:#"success"].
Edit: Adding example
I've recently noticed some ; where commas should have been, but let's hope that's just a typo or something like it.
In case you have a doubt, you can always NSLog(#"%#", [yourFirstDictionary allKeys]); to make sure those are valid keys.
Let's call your first object myDict for the sake of the example.
NSDictionary * response = [myDict objectForKey:#"response"]; // this should have #status and authentication as keys
NSDictionary * authentication = [response objectForKey:#"authentication"];
NSString * innerResponse = [authentication objectForKey:#"#response"];
if ([innerResponse isEqualToString:#"success"]) {
// your code
}
Hello Facebook gurus :)
I'd like some help on this one
This is a post I made on a picture and then I liked it:
{
"created_time" = "2011-06-07T23:23:19+0000";
from = {
id = xxxxxxxxxxxxxx;
name = "Adrien xxxxxxxx";
};
id = "107817942643477_24293";
likes = 1;
message = baar;
"user_likes" = 1;
}
I'm trying to get the userID's of friends/me who liked this comment I made on a picture
I made this :
https://graph.facebook.com/107817942643477_24293/likes?access_token=TOKEN
I tried too with Fql:
NSString *theQuery = [NSString stringWithFormat:#"SELECT likes FROM stream WHERE post_id=\"%#\"", postID];
id theResult = [[AppDelegate sharedFacebook]
sendSynchronousRequestWithMethodName:#"fql.query"
andParams:[NSMutableDictionary dictionaryWithObjectsAndKeys:
theQuery, #"query", nil]
andHttpMethod:#"GET"];
It doesn't work, maybe because this comment is liked to a picture and I should format the request differently ?
The only thing I'm receiving is an empty array
{
data = (
);
}
What am I doing wrong ?
Thanks in advance for any help on this one.
Ps: I'm using the iOS Facebook library, could it be broken ?
You need to include the user id. Taking the example from the Facebook documentation here:
http://developers.facebook.com/docs/reference/api/Comment/
Click on the link there and add '/likes' before the query string containing the access token:
https://graph.facebook.com/19292868552_475058873552_14173716/likes?access_token=2227470867|2.AQDprvRAYwU-6lHe.3600.1309028400.0-604597322|Z4r0uxTK5ctlAn5rbs2NUNYZr88
If you remove the user id from the id, however...
https://graph.facebook.com/475058873552_14173716/likes?access_token=2227470867|2.AQDprvRAYwU-6lHe.3600.1309028400.0-604597322|Z4r0uxTK5ctlAn5rbs2NUNYZr88
...it won't work.
So you need to manually add the user id to your comment id if it's not already present.
I'm quite new to iphone programming and I want to do the following stuff:
get data from a JSON REST web server
parse the received data using YAJL
Draw a graph with those data using core-plot
So, 1th item is fine, I use ASIHttpRequest which runs as espected
3rd is almost fine (I still have to learn how to tune core-plot).
The problem I have is regarding 2nd item.
I use YAJL as it seems to be the faster parser, so why not give it a try :)
Here is the part of code that gets the data from the server and parse them:
// Get server data
response_data = [request responseData];
// Parse JSON received
self.arrayFromData = [response_data yajl_JSON];
NSLog(#"Array from data: %#", self.arrayFromData);
The parsing works quite well in fact, the NSLog output is something like:
2010-06-14 17:56:35.375 TEST_APP[3733:207] Array from data :
{
data = (
{
val = 1317;
date = "2010-06-10T15:50:01+02:00";
},
{
val = 1573;
date = "2010-06-10T16:20:01+02:00";
},
........
{
val = 840;
date = "2010-06-11T14:50:01+02:00";
},
{
val = 1265;
date = "2010-06-11T15:20:01+02:00";
}
);
from = "2010-06-10T15:50:01+02:00";
to = "2010-06-11T15:20:01+02:00";
max = "2590";
}
According to th yajl-objc explanations http://github.com/gabriel/yajl-objc, the parsing returns a NSArray...
The thing is... I do not know how to get all the values from it as for me it looks more like a NSDictionary than a NSArray...
Could you please help ?
Thanks a lot,
Luc
edit1: it happens that this object is actually a NSCFDictionary (!), I am still not able to get value from it, when I try the objectFromKey method (that should work on a Dictionary, no ?) it fails.
It's returning an NSDictionary. NSCFDictionary is a private subclass and is immaterial to this discussion. So it looks like you'd retrieve stuff like:
NSDictionary * responseDictionary = ...;
NSArray * dataArray = [responseDictionary objectForKey:#"data"];
for (NSDictionary * dataPair in dataArray) {
NSLog(#"val: %#, date: %#", [dataPair objectForKey:#"val"], [dataPair objectForKey:#"date"]);
}