iOS - Can't send Facebook requests - ios

I currently have a problem with my iOS application because I don't seem to be able to send requests to people...
Here is the code that I have:
NSMutableDictionary* params = [NSMutableDictionary dictionaryWithObjectsAndKeys:nil];
if([FBSession activeSession].isOpen) {
[FBWebDialogs presentRequestsDialogModallyWithSession:[FBSession activeSession] message:#"Join me." title:#"Invite" parameters:params handler:^(FBWebDialogResult result, NSURL *resultURL, NSError *error) {
NSLog(#"%#", [FBSession activeSession]);
if (error)
NSLog(#"Error sending request.");
else {
if (result == FBWebDialogResultDialogNotCompleted)
NSLog(#"User canceled request.");
else if(result == FBWebDialogResultDialogCompleted)
NSLog(#"Request: %#", resultURL);
else
NSLog(#"Error unknown.");
}
}];
}
else {
[FBSession openActiveSessionWithReadPermissions:#[#"email"] allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
if(session.isOpen) {
[FBSession openActiveSessionWithPublishPermissions:#[#"publish_actions"] defaultAudience:FBSessionDefaultAudienceEveryone allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
if(session.isOpen) {
[self showRequestForFacebook];
}
}];
}
}];
}
Every time I get a Request: (null). I get a request ID but nothing on the account. I looked at the sample in the Facebook SDK and I seem to have exactly the same. However, it works with the sample and not with my code.
Is there anything to change somewhere? Is it something on developers.facebook.com?
Edit: I forgot to say that in the same application I use a SLComposeViewController to share on Facebook and it works perfectly.
Thanks a lot! :)

NSString *query2 = [NSString stringWithFormat:#"SELECT uid, name, pic_square,is_app_user FROM user WHERE is_app_user = 1 AND uid IN " #"(SELECT uid2 FROM friend WHERE uid1 = me())"];
// Set up the query parameter
NSDictionary *queryParam2 = #{ #"q": query2 };
// Make the API request that uses FQL
[FBRequestConnection startWithGraphPath:#"/fql" parameters:queryParam2 HTTPMethod:#"GET"
completionHandler:^(FBRequestConnection *connection,
id result,
NSError *error)
{
if (error) {
} else {
// NSLog(#"Result: %#", result);
// Get the friend data to display
NSArray *friendInfo = (NSArray *) result[#"data"];
NSLog(#"%#",friendInfo);
self.data=friendInfo;
[self constructDictionaryOfNumbers];
// Show the friend details display
}
}];
}

Related

Facebook iOS SDK - fetching user albums

I am using Facebook SDK in my iPhone app. I want to find the user's Facebook profile photos, for that I am using the below code:
-(IBAction)FacebookLogin:(id)sender{
if (FBSession.activeSession.isOpen) {
[self findAlbums];
} else {
NSArray *permissions = [[NSArray alloc] initWithObjects:#"user_photos",
nil];
[FBSession openActiveSessionWithPermissions:permissions
allowLoginUI:YES
completionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
// if login fails for any reason, we alert
if (error) {
} else if (FB_ISSESSIONOPENWITHSTATE(status)) {
[[FBRequest requestForMe] startWithCompletionHandler:
^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
if (!error) {
[self findAlbums];
}
}];
}
}];
}
}
-(void)findAlbums {
[FBRequestConnection startWithGraphPath:#"/me/albums"
parameters:nil
HTTPMethod:#"GET"
completionHandler:^(
FBRequestConnection *connection,
id result,
NSError *error
) {
/* handle the result */
NSLog(#"result::%#",result);
}];
}
Out put ---- data = ( );
This does not give any albums in data. The Facebook user logged in have many albums and photos in his profile. Why this happens?
just change the code in find albums to :
[FBRequestConnection startWithGraphPath:#"me/albums"
completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
// Success! Include your code to handle the results here
NSLog(#"user events: %#", result);
NSArray *feed =[result objectForKey:#"data"];
for (NSDictionary *dict in feed) {
NSLog(#"first %#",dict);
}
} else {
// An error occurred, we need to handle the error
// Check out our error handling guide: https://developers.facebook.com/docs/ios/errors/
NSLog(#"error %#", error.description);
}
}];
you have to add the Facebook credentials(i.e facebook account) you're using to the Facebook developer account settings(i.e as admin or developer) , only then you can access the album's photos through your code

iOS - Facebook SDK allowLoginUI not working

I am trying to get basic user information from facebook, using the following code
- (void)viewDidLoad
{
[super viewDidLoad];
if(![[FBSession activeSession] isOpen]){
NSLog(#"Creating new session");
[FBSession openActiveSessionWithPermissions:nil
allowLoginUI:NO
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
[self makeRequestForUserData];
}];
}else{
}
}
- (void) makeRequestForUserData
{
[FBRequestConnection startForMeWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
NSLog(#"user info: %#", result);
[self.txtDetails setText: [result string]];
//[[FBSession activeSession] closeAndClearTokenInformation];
} else {
NSLog(#"error %#", error.description);
}
}];
}
When closeAndClearToken is commented and allowLoginUI is set to NO or YES no error occurs and I get the data, problem is whether or not somebody is logged into fb, I get the data of last user who logged in. Where as when I uncomment closeAndClearToken I get following error:
error = {
code = 2500;
message = "An active access token must be used to query information about the current user.";
type = OAuthException;
};
this is a class method, with a completionHandler, where you will get the user. Just call this method anywhere and it should work, if you setup you app on facebook.
+ (void)requestFacebookDataWithCompletionHandler:(void (^)(NSDictionary *))handler {
// If the session state is any of the two "open" states when the button is clicked
if (FBSession.activeSession.state == FBSessionStateOpen
|| FBSession.activeSession.state == FBSessionStateOpenTokenExtended) {
[FBSession.activeSession closeAndClearTokenInformation];
if (handler) {
handler(nil);
}
// If the session state is not any of the two "open" states when the button is clicked
} else {
// Open a session showing the user the login UI
// You must ALWAYS ask for public_profile permissions when opening a session
[FBSession openActiveSessionWithReadPermissions:#[#"public_profile",#"email"]
allowLoginUI:YES
completionHandler:
^(FBSession *session, FBSessionState state, NSError *error) {
[[FBRequest requestForMe] startWithCompletionHandler: ^(FBRequestConnection *connection,
NSDictionary<FBGraphUser> *user,
NSError *error) {
if (!error) {
if (handler) {
handler(user);
}
}
}];
DAppDelegate* appDelegate = [UIApplication sharedApplication].delegate;
[appDelegate sessionStateChanged:session state:state error:error];
}];
}
}
you will also have to add some methods in AppDelegate; but you will find those methods there:
https://developers.facebook.com/docs/facebook-login/ios/v2.0 . Hope it will work

FBRequestConnection no respond

I'm making a "FBRequestConnection" to get all the friends that play the game...
When I update the SDK of Facebook to the last one, this stop working. Because It was working before.
I have no respond, no success, no error. Any ideas?
NSString *query = #"SELECT uid FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1 = me()) AND is_app_user = 1";
// 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) {
[self debug:[NSString stringWithFormat:#"Error: %#", [error localizedDescription]]];
} else {
[self debug:[NSString stringWithFormat:#"Result: %#", [result objectForKey:#"data"]]];
}
}];
-(void)fbLogin {
if (!_session.isOpen) {
// create a fresh session object
_session = [[FBSession alloc] init];
// if we don't have a cached token, a call to open here would cause UX for login to
// occur; we don't want that to happen unless the user clicks the login button, and so
// we check here to make sure we have a token before calling open
if (_session.state == FBSessionStateCreatedTokenLoaded) {
// even though we had a cached token, we need to login to make the session usable
[_session openWithCompletionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
// we recurse here, in order to update buttons and labels
[[NSNotificationCenter defaultCenter] postNotificationName:#"fbConnected" object:nil];
}];
}
[self populateUserDetails];
}
}
Thanks
Open the session with:
[FBSession.activeSession openWithCompletionHandler:^(FBSession * session, FBSessionState state, NSError * error){
if (!error){
}
}];

Facebook SDK and iOS

I am trying to post a status using Facebook SDK.
Some of the users are already signed in using Facebook.
So I have this code:
if (FBSession.activeSession.isOpen) {
NSLog(#"Already Open%#",[[FBSession activeSession] accessTokenData].accessToken);
// NSString *tok = [[FBSession activeSession] accessTokenData].accessToken;
NSArray *permissions = [NSArray arrayWithObjects:#"publish_actions", nil];
[[FBSession activeSession] requestNewPublishPermissions:permissions defaultAudience:FBSessionDefaultAudienceFriends
completionHandler:^(FBSession *session,NSError *error) {
if(!error){
NSLog(#"Publish Permission Granted");
}
else
{
NSLog(#"Publish to get Read Permission");
} }];
//Remove indicator
[_activityView removeFromSuperview];
} else {
// OPEN Session!
[FBSession openActiveSessionWithReadPermissions:nil
allowLoginUI:YES
completionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
// if login fails for any reason, we alert
if (error) {
// show error to user.
} else if (FB_ISSESSIONOPENWITHSTATE(status)) {
// no error, so we proceed with requesting user details of current facebook session.
NSLog(#"----%#",[session accessTokenData].accessToken);
//NSString *tok = [session accessTokenData].accessToken;
NSArray *permissions = [NSArray arrayWithObjects:#"publish_actions", nil];
[[FBSession activeSession] requestNewPublishPermissions:permissions defaultAudience:FBSessionDefaultAudienceFriends
completionHandler:^(FBSession *session,NSError *error) {
if(!error){
NSLog(#"Publish Permission Granted");
}
else
{
NSLog(#"Publish to get Read Permission");
} }];
[_activityView removeFromSuperview];
// [self promptUserWithAccountName]; // a custom method - see below:
}
}];
}
So lets focus on the first part which is suppose that the user has open session( the second one is just opening a new one in case that is no session available). How I am going to post a status with a url and a picture after granting publish permissions? Facebook examples are not helping at all. I found some other examples but most of them are outdated.
I managed to post a simple post with:
FBRequest *postRequest = [FBRequest requestForPostStatusUpdate:#"hi" ];
[postRequest startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
// TODO: Check for success / failure here
}];
after granding publish permission. I want something similar with url description imgurl and title.
This is how I did it, in my ibaction method:
Sharing Image:
UIImage *img = myImage;
FBLoginView *loginview = [[FBLoginView alloc] init];
loginview.delegate = self;
[self performPublishAction:^{
[FBRequestConnection startForUploadPhoto:img
completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
[self showAlert:#"Photo Post" result:result error:error];
}];
}];
Sharing URL:
NSURL *urlToShare = [NSURL URLWithString:#"http://developers.facebook.com/ios"];
FBAppCall *appCall = [FBDialogs presentShareDialogWithLink:urlToShare
name:#"Hello Facebook"
caption:nil
description:#"The 'Hello Facebook' sample application showcases simple Facebook integration."
picture:nil
clientState:nil
handler:^(FBAppCall *call, NSDictionary *results, NSError *error) {
if (error) {
NSLog(#"Error: %#", error.description);
} else {
NSLog(#"Success!");
}
}];
Add these as well:
- (void) performPublishAction:(void (^)(void)) action
{
if([[FBSession activeSession]isOpen])
{
if ([FBSession.activeSession.permissions indexOfObject:#"publish_actions"] == NSNotFound) {
// if we don't already have the permission, then we request it now
[FBSession.activeSession requestNewPublishPermissions:#[#"publish_actions"]
defaultAudience:FBSessionDefaultAudienceFriends
completionHandler:^(FBSession *session, NSError *error) {
if (!error) {
action();
}
//For this example, ignore errors (such as if user cancels).
}];
} else {
action();
}
}
else
{
[FBSession openActiveSessionWithPublishPermissions:[NSArray arrayWithObject:#"publish_actions"]
defaultAudience:FBSessionDefaultAudienceFriends
allowLoginUI:YES
completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
if (!error && status == FBSessionStateOpen) {
}else{
NSLog(#"Session error");
[self fbResync];
[NSThread sleepForTimeInterval:0.5]; //half a second
[FBSession openActiveSessionWithPublishPermissions:[NSArray arrayWithObject:#"publish_actions"]
defaultAudience:FBSessionDefaultAudienceFriends
allowLoginUI:YES
completionHandler:^(FBSession *session, FBSessionState status, NSError *error){
}];
}
}];
}
}
- (void)loginViewShowingLoggedInUser:(FBLoginView *)loginView
{
}
- (void)loginViewFetchedUserInfo:(FBLoginView *)loginView
user:(id<FBGraphUser>)user
{
self.loggedInUser = user;
}
- (void)loginViewShowingLoggedOutUser:(FBLoginView *)loginView
{
self.loggedInUser = nil;
}
-(void)fbResync
{
ACAccountStore *accountStore;
ACAccountType *accountTypeFB;
if ((accountStore = [[ACAccountStore alloc] init]) && (accountTypeFB = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook] ) ){
NSArray *fbAccounts = [accountStore accountsWithAccountType:accountTypeFB];
id account;
if (fbAccounts && [fbAccounts count] > 0 && (account = [fbAccounts objectAtIndex:0])){
[accountStore renewCredentialsForAccount:account completion:^(ACAccountCredentialRenewResult renewResult, NSError *error) {
//we don't actually need to inspect renewResult or error.
if (error){
}
}];
}
}
}
Hope this helps... Look at HelloFacebookSample in Facebook SDK Samples.
Try this:
[self performPublishAction:^{
NSString *message = [NSString stringWithFormat:#"Updating status for %# at %#", self.loggedInUser.first_name, [NSDate date]];
[FBRequestConnection startForPostStatusUpdate:message
completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
[self showAlert:message result:result error:error];
self.buttonPostStatus.enabled = YES;
}];
self.buttonPostStatus.enabled = NO;
}];

Facebook iOS SDK 3.5.1: openActiveSessionWithReadPermissions - completion handler called twice

I have a button to share a link. I'm using basically two calls:
openActiveSessionWithReadPermissions and requestNewPublishPermissions.
So this is the button action:
- (IBAction) shareFacebookButtonAction:(id)sender
if (![[FBSession activeSession] isOpen])
{
NSArray *permissions = #[#"read_friendlists", #"email"];
[FBSession openActiveSessionWithReadPermissions:permissions
allowLoginUI:YES
completionHandler:^(FBSession *session,
FBSessionState state,
NSError *error)
{
if (FB_ISSESSIONOPENWITHSTATE([session state]))
{
[self _prepareShare];
}
else
{
// show alert view with error
}
}];
}
else
{
[self _prepareShare];
}
}
and with this I'm asking for publish permission, if no permissione are found in session
-(void) _prepareShare;
{
if ([FBSession.activeSession.permissions
indexOfObject:#"publish_actions"] == NSNotFound)
{
[FBSession.activeSession
requestNewPublishPermissions:
[NSArray arrayWithObject:#"publish_actions"]
defaultAudience:FBSessionDefaultAudienceFriends
completionHandler:^(FBSession *session, NSError *error)
{
if (!error)
{
[self _share];
}
else
{
//error
}
}];
} else
{
[self _share];
}
}
_share just posts something
-(void) _share;
{
NSMutableDictionary *params_dict = [NSMutableDictionary dictionary];
// setting some params
[FBRequestConnection startWithGraphPath:#"me/feed" parameters:params_dict HTTPMethod:#"POST" completionHandler:^(FBRequestConnection *connection, id result, NSError *error)
{
if (result)
{
// sharing succedeed, do something
}
else if (error)
{
//sharing failed, do something else
}
}];
}
First time I try to share (already logged on FB in iOS6 and app already authorized) completion handler of openActiveSessionWithReadPermissions is being called twice:
once with FBSessionStateOpen and once with FBSessionStateOpenTokenExtended (from the openSessionForPublishPermissions call).
As a consequence, _share is also called twice, first time in the else part of _prepareShare (if I already have publish permissions) and the second time in the completion handler of openSessionForPublishPermissions.
So I have a double post on Facebook wall, just the first time I ever share in the app. I also had a crash report for FBSession: It is not valid to reauthorize while a previous reauthorize call has not yet completed (I couldn't be able to make it happen again).
What is the proper way to handle this situation?
It appears that by design, Facebook SDK retains references to block handlers, even after they have been called. Thus, in your call to openActiveSessionWithReadPermissions the completion handler may be called numerous times, in case the session state changes. See Facebooks comment on this issue here.
As a work around, you might want to implement your own mechanism that ensures the handler is fired only once:
__block FBSessionStateHandler runOnceHandler = ^(FBSession *session,
FBSessionState status,
NSError *error) { /* YOUR CODE HERE */ };
...
[FBSession openActiveSessionWithReadPermissions:YOUR_PERMISSIONS
allowLoginUI:YES
completionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
if (runOnceHandler) {
runOnceHandler(session, status, error);
runOnceHandler = nil;
}
}
];
You Can use this
- (IBAction)facebookBasti:(id)sender {
if(FBSession.activeSession.isOpen){
[[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
if (!error) {
NSLog(#" Email = %#",[user objectForKey:#"email"]);
}
}];
NSLog(#"POST TO WALL -- %#",FBSession.activeSession.accessToken);
[self publishFacebook];
}
else {
// try to open session with existing valid token
NSArray *permissions = [[NSArray alloc] initWithObjects:
#"publish_actions",#"email",
nil];
FBSession *session = [[FBSession alloc] initWithPermissions:permissions];
[FBSession setActiveSession:session];
if([FBSession openActiveSessionWithAllowLoginUI:NO]) {
// post to wall
[[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
if (!error) {
NSLog(#" Email = %#",[user objectForKey:#"email"]);
}
}];
NSLog(#"POST TO WALL -- %#",FBSession.activeSession.accessToken);
[self publishFacebook];
} else {
// you need to log the user
NSLog(#"login");
[FBSession openActiveSessionWithPermissions:permissions
allowLoginUI:YES
completionHandler:^(FBSession *session,
FBSessionState state,
NSError *error) {
NSLog(#"POST TO WALL -- %#",FBSession.activeSession.accessToken);
[self publishFacebook];
}];
}
}
}
and publishFacebook method
-(void)publishFacebook
{
NSMutableDictionary *postParams2= [[NSMutableDictionary alloc] initWithObjectsAndKeys:
haberLink, #"link",
#"abc.com", #"name",
title, #"caption",
desc, #"description",
nil];
[FBRequestConnection
startWithGraphPath:#"me/feed"
parameters:postParams2
HTTPMethod:#"POST"
completionHandler:^(FBRequestConnection *connection,
id result,
NSError *error) {
NSString *alertText;
if (error) {
alertText = [NSString stringWithFormat:
#"error: domain = %#, code = %d",
error.domain, error.code];
} else {
alertText = [NSString stringWithFormat: #"Shared Facebook"];
[[[UIAlertView alloc] initWithTitle:#"Shared Facebook"
message:alertText
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil]
show];
}
}];
}
Please read Upgrading from 3.0 to 3.1, in particular the paragraph Asking for Read & Write Permissions Separately. It seems like Facebook SDK is not meant to be used this way.
You are now required to request read and publish permission separately (and in that order). Most likely, you will request the read permissions for personalization when the app starts and the user first logs in. Later, if appropriate, your app can request publish permissions when it intends to post data to Facebook.
and
It is important that you do not simply attempt to call the two individual methods back-to-back to replace either of the deprecated functions.
I wonder how you managed to solve this issue. BTW, I get the same crash report (FBSession: It is not valid to reauthorize while a previous reauthorize call has not yet completed).

Resources