I am trying to create a class that will handle contain all Facebook methods, and to call methods from other classes when required;
And this is how i am calling these methods (from a another viewController)
I have added a button and on its click event i add the following code;
FBClass *fb= [[FBClass alloc] init];
[fb fbLogin];
[fb accesstokenDetails];
This program works perfectly, i asks the user for the credentials and then ask the user to type something to share, and it also post to the FB wall. But the program crashes with the sharing screen;
What should i do to prevent this ?
Related
I'm trying to post an Open Graph Story, being logged to my app with Facebook test account. Story contnents: Name shared a link.
Facebook's instructions to get a permission is a vicious circle!
To post I need a permission, For permission I got to post something.
So when I'm trying to post a story from the app. App goes to Facebook app, creates a template for post. But when press "Publish" nothing's happen.
Please, help me to solve a problem.
Our company tried everything, changed code etc, but I think it's Facebooks problem. Please, help me to find out why posts do not publish to Facebook.
PS: We do not use share dialog in this case, we are using Open Graph with API 2
If you just want to share a link then use the following code:
FBSDKShareLinkContent *content = [[FBSDKShareLinkContent alloc] init];
content.contentURL = [NSURL URLWithString:#"http://developers.facebook.com"];
[FBSDKShareDialog shareFromViewController:self
withContent:content
delegate:nil];
In the composer leave 'Say something about this...' blank and the story will show up in the Timeline as "Name shared a link"
If it is a custom OG story, then use the Share Dialog; you do not need to explicitly get publish_actions permission.
If Share Dialog does not seem to post to Timeline, set the delegate for the dialog and you can use the delegate method to investigate the cause.
-(void)sharer:(id<FBSDKSharing>)sharer didFailWithError:(NSError *)error {
NSLog(#"Error: %#", error);
}
As for creating actions and objects, you can do so in your app dashboard:
https://developers.facebook.com/apps/<your-facebook-app-id>/open-graph/
If you need permissions to make Graph API calls then implement login with Facebook and it is here that you request the permissions that your app needs. For example:
FBSDKLoginButton *loginButton = [[FBSDKLoginButton alloc] init];
loginButton.readPermissions = #[#"public_profile", #"user_photos"];
loginButton.publishPermissions = #[#"publish_actions"];
Once you have the permissions in place you can make Graph API calls.
my question is very similar to this:
Facebook SDK Login dialog appears twice
" login dialog appears twice. How can I solve this problem?"
Except, I am using this singleton for communicating with the Facebook sdk:
http://matt-swain.com/post/21160566904/facebook-ios-sdk-singleton (thats the code I'm using)
http://barrycenter.com/BAM!coding/2011/07/simplifying-facebook-ios-sdk/ (old version including explanations)
The only difference between my code and the original singleton one is that I have a method:
-(void) postToWallWithDialog:(int)count2 {
NSMutableDictionary* params = [self buildPostParams:count2];
[self dialog:#"feed" andParams:params andDelegate:self]; //post
} //buildPostParams just makes a dictionary, nothing else.
I do not want to call my method from within fbDidLogin, because it needs to be called from the view controller.
how do i eliminate the second login dialog?
thanks!
I ended up using FBNotifications to check if user in fact flogged in and whether or not there was a valid session. Knowing that, I posted to the wall and it eliminated the second dialog.
I have seen a lot of questions here regarding the Facebook Graph API but I still haven't find a solution for simple 'login'/'logout' operations using it. Looks like the Single Sign-On style is causing more confusion than benefits.
I'd like to know if it is possible have the following situation:
Enter in the app (no accessToken/expirationDate created).
Perform a login using SSO by calling authorize:delegate: method (application goes background and the login is made in the 'global' scope (Facebook App/Mobile Safari), asking for the user credentials.
Enter back in the app (now logged in, both accessToken and expirationDate are saved to NSUserDefaults).
Perform a logout by calling the logout: method (now logged out, both accessToken and expirationDate are removed from NSUserDefaults)
Attempt to perform a login again, with exactly the same steps done in 2.
I realize that when I call logout:, I do really log out from Facebook (accessToken is invalidated) from my App scope, not from the global scope (Facebook App/Mobile Safari). In 5.) when I try to log in again, the application goes to background and the login attempt is made again in Facebook App/Mobile Safari as usual, however I'm getting a screen saying that I'm already logged in:
You have already authorized .... Press "Okay" to continue.
Logged in as ... (Not You?).
It's a strange behavior for the user that has just logged out in my App.
My question is:
"Can I really log out from facebook (I mean 'global' scope) from inside my App? This would affect other apps using the facebook credentials too. However, if I can't to do this, how can I avoid the 'strange behavior' describe above?
Thanks
Eduardo,
I feel your pain! I spent the better part of a day working on this issue. I have discovered that when you use SSO and the call:
Called from your code:
[facebook logout:self];
Facebook API method:
- (void)logout:(id<FBSessionDelegate>)delegate {
self.sessionDelegate = delegate;
[_accessToken release];
_accessToken = nil;
[_expirationDate release];
_expirationDate = nil;
NSHTTPCookieStorage* cookies = [NSHTTPCookieStorage sharedHTTPCookieStorage];
NSArray* facebookCookies = [cookies cookiesForURL:[NSURL URLWithString:#"http://login.facebook.com"]];
for (NSHTTPCookie* cookie in facebookCookies) {
[cookies deleteCookie:cookie];
}
if ([self.sessionDelegate respondsToSelector:#selector(fbDidLogout)]) {
[_sessionDelegate fbDidLogout];
}
}
The facebook API does invalidate the access token and expirationdate variables and attempts to delete the mobile Safari cookies, but for some reason, probably Apple's fault the cookies are not really deleted. So when you attempt to login in the next time your mobile Safari will see the cookie and it says:
"You have already authorized .... Press "Okay" to continue. Logged in as ... (Not You?)."
Until either Facebook finds a fix or Apple fixes their broken API we must bypass SSO through Safari. Below are the changes I made to Facebook.m in order to force the old login dialog. If you used these changes they may not work forever but it is my guess that they will work for a very long time. Also to be sure this worked with the most recent facebook API I updated to the latest as of this post (Nov 2011 build).
Called from your code:
[facebook authorize:permissions];
Facebook API method:
- (void)authorize:(NSArray *)permissions {
self.permissions = permissions;
// [self authorizeWithFBAppAuth:YES safariAuth:YES];
[self authorizeWithFBAppAuth:NO safariAuth:NO];
}
If this helps you please up rate this thread and my post to help others find it.
gadildafissh
I'm afraid the answer is no, you can't do this.
Your application is in a sandbox, and can't write outside, where global cookies are (for mobile safari) and Facebook app settings (in Facebook app preferences/cookies I think)
You can only warn your user to logout outside of your app...
...Or you can just not use facebook api SSO, but in app login webform, like I do for other reasons.
If you choose that option this pull request might save you some time ;)
Hii ,
its not possible , the reason is for Single Sign On (SSO) is not to make user login everytime, he logouts , instead if the user logs in anyone of FB enabled apps - it will use that to login again - This is because the device is mostly used by single person in this case only one user can login in Facebook.
you can't control any app outside of your app - for Example - if u login with Gmail & when you open google.com you can see your username there is currently logged In which has SSO,
In new SDK of Facebook, you can set login button loginBehaviour property
Below code in swift ...
let fbButton = FBSDKLoginButton()
fbButton.loginBehavior = .Web
Answer already done, but I just want to clarify it. May be it saved somebody's time.
Go to Facebook.m and change line
[self authorizeWithFBAppAuth:YES safariAuth:YES];
to
[self authorizeWithFBAppAuth:YES safariAuth:NO];
It will cause login window appear inside the app. Logout will work perfect. In other words, it will work as it used to in older versions of OS.
in addition to kishnan94 answer. the objective c version is ;
if you want a modal to open up and ask for facebook credentials seperately from Safari or Facebook app, just use the latest facebook sdk and set the login behaviour
FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
[login setLoginBehavior:FBSDKLoginBehaviorWeb];
this will make the logout process more convenient and less confusing for users without using safari or facebook app accounts.
It seems that this is a bug of Facebook SDK. In a case of the Facebook app is installed on device, access_token is renewed. In other hand, access_token and expirationDate could not be changed. :((
I would like to know what this code does exactly.
- (void)dialogDidSucceed:(FBDialog*)dialog {
//[self doSomethingExciting];
FBStreamDialog *dialog2 = [[[FBStreamDialog alloc] init] autorelease]; dialog.delegate = self;
dialog2.userMessagePrompt = #"Example prompt";
dialog2.attachment = #"{\"name\":\"Facebook iPhone SDK\","
"\"href\":\"http://developers.facebook.com/connect.php?tab=iphone\","
"\"caption\":\"Caption\",\"description\":\"Description\","
"\"media\":[{\"type\":\"image\","
"\"src\":\"http://img40.yfrog.com/img40/5914/iphoneconnectbtn.jpg\","
"\"href\":\"http://developers.facebook.com/connect.php?tab=iphone/\"}],"
"\"properties\":{\"another link\":{\"text\":\"Facebook home page\",\"href\":\"http://www.facebook.com\"}}}";
// replace this with a friend's UID
// dialog.targetId = #"999999";
[dialog2 show];
}
When I run it it asks me if I want to publish on my and my friends walls, but Im not sure how this will look on the walls. Also does it publish to the users walls and then show up in their friends incoming stream, like "most recent" or does it actually post on every friends wall?
Thanks
Yes. You are posting an image to their stream.
Attachment is an escaped sequence of JSON that Facebook will pick up on and attach an image (and it looks like a link as well).
What the user will see is the image/link preconfigured as a wall post, and they will have a text box to enter their own text referred so as User Message Prompt.
Whether or not it shows up on friends streams depends on their settings, but ultimately, this is a news stream post, and thus has the potential to appear on their home page.
An other answer already explained what the code does.
This is just a tip:
Create three fake FaceBook accounts, and connect them together.
Then use them to do your testings. So you will know exactly what happens, and do all the tests you need during development without loosing all your friends.
When you use facebook connect on the iPhone do you have to use the supplied login button and login screen built into the framework? The reason I ask is because I'm also using twitter and I would like to have the same user experience when they log in to user as they have when they log in to facebook. So I can either replicate the login screen facebook connect uses for twitter or just not use the facebook connect login screen all together.
Login button: no. Login screen: yes. I added FB Connect integration to my FriendFeed app for iPhone, Stir, and skipped the login button. Instead, a user can choose a "Share on Facebook" button on a UIActionSheet and the app either displays a login screen or automatically posts a link depending on whether the user is authenticated.
Here's a code snippet for you. If the session is successfully resumed, then a method on your FBSession object's delegate will be called.
if (![fbSession resume]) {
FBLoginDialog* dialog = [[[FBLoginDialog alloc] initWithSession:fbSession] autorelease];
[dialog show];
}
- (void)session:(FBSession*)session didLogin:(FBUID)uid {
NSLog(#"Hooray, I'm logged in to Facebook!");
}
Apologies for being a little vague in my example above. To be honest, I find FBConnect to be a bit of a mystery and tried my best to implement it and get away from it as quickly as possible in my app. Let me know if you need more information and I'll put together a more-concrete answer.
Per the request below:
You can get an FBSession object with FBSession's +sessionForApplication:secret:delegate class method. You call -resume on the session object. If it returns YES, it'll immediately call your delegate's -session:didLogin: method, which is where you should put your FB-dependent actions. If it does not successfully -resume, then you need to create an FBLoginDialog, as seen in the code snippet above. Make sense? Let me know if you need more info