Facebook Connect SSO not working on some iPhones - iphone

I have implemented FBConnect SSO in my iphone application according to this tutorial. I have tested it on two phones so far, one of which lets me use the function just fine, whereas the other phone simply opens up the Facebook app and closes it right away. I am able to establish a valid session, yet the dialog seems to just close on me on one of the ones.
What could be the problem? Any help is much appreciated.

I think that your problem is that you dont have the proper configuration, either in the client side (your app) or in the server side (the FB app configuration). Please, check both things as follows:
Client app:
Make sure that you have introduced the correct FBAppId into your Info.plist as a URL handler. Facebook will try to open the app by using this handler, and if it doesn't work, your app will not be opened.
(replace the XXXXXXXXXX with your FB appID)
Check whether your app (in the appDelegate) handles the custom URL added above:
- (BOOL)handleOpenURL:(NSURL*)url
{
NSString* scheme = [url scheme];
NSString* prefix = [NSString stringWithFormat:#"fb%#", facebookAppId];
if ([scheme hasPrefix:prefix]) {
return [fb handleOpenURL:url];
}
return YES;
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
return [self handleOpenURL:url];
}
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
return [self handleOpenURL:url];
}
Server side
Check that you have correctly configured your bundleId in the FB config page. You can check this in https://developers.facebook.com/apps, selecting you app, and then in the edition panel:
If you have both things correctly configured it should work in any case (with the FBapp installed or Safari based).

I have seen this with the 3.0 SDK. The reason it occurs is because of the way facebook caches access tokens. Access tokens are cached both in your app, and in the facebook app on the device (at least conceptually).
If it's the first time you started your app on the device, facebook won't have a valid access token cached in your app. However, it may still have a valid access token in the facebook app for your app. If it finds one on the facebook side, then it doesn't have to ask the user again, so the dialog appears, then disappears, and it sends back the access token. The access token is then cached in your app.
If you restart your app (without deleting it), you won't see the login dialog at all since the access token is now cached in your app. If you delete your app on the device and login again, you'll see the same behavior, as long as facebook can find a cached token on it's side.
I have found a solution to this problem. Here is some sample code:
if (![FBSession activeSession].isOpen) {
FBSession *session = [[FBSession alloc] initWithAppID:nil permissions:permissions defaultAudience:FBSessionDefaultAudienceEveryone urlSchemeSuffix:nil tokenCacheStrategy:nil];
[FBSession setActiveSession:session];
[session openWithBehavior:FBSessionLoginBehaviorUseSystemAccountIfPresent completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
// NOTE openActiveSessionWithPermissions causes the facebook app to hang with a blank dialog if my app is installed, authed, and then reinstalled. openWithBehavior
// does not. I think it has something to do with the FBSession activeSession.
// [FBSession openActiveSessionWithPermissions:self.permissions allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
switch (status) {
case FBSessionStateOpen:
[self getFacebookUser];
break;
case FBSessionStateClosed:
[self fbSessionClosed];
break;
case FBSessionStateCreated:
[self fbSessionCreated];
break;
case FBSessionStateCreatedOpening:
[self fbSessionOpening];
break;
case FBSessionStateClosedLoginFailed:
[self fbSessionClosedLoginFailed];
break;
case FBSessionStateOpenTokenExtended:
[self fbSessionOpenTokenExtended];
break;
case FBSessionStateCreatedTokenLoaded:
[self fbSessionCreatedTokenLoaded];
break;
}
}];
}
}
openActiveSessionWithPermissions causes problems, but openWithBehavior does not. openActiveSession makes the same openWithBehavior call, but I think the timing of setting the active session is different, and hence does not work. If I set the active session before calling openWithBehavior, everything seems to work fine. As far as your app and the end user are concerned, everything is identical.

You need to insert suitable logging throughout your code, post the code, and post what logs are being made in the working and the failure cases.
To make a log (see here for more advanced techniques):
NSLog(#"My log text");
At a minimum you need to add logs in all the callbacks from the Facebook API (even the ones you aren't using), and in your handleOpenURL and openUrl methods in the application delegate.
Your logs will appear in the Console in the Xcode Organizer when you connect the device you are testing with - that should show you what is happening.
FYI, the Facebook SDK code will first attempt to use the native app if it is installed, otherwise it will launch the Safari browser to ask for authorization through the web version of Facebook.
You should double check your Facebook URL scheme configuration, as described in the answer by Angel GarcĂ­a Olloqui.

Related

facebook login works on iphone simulator but not on iphone device

In my app, I want to take photos from the facebook. so i used facebook ios sdk. i can be able to authorize from the below code:
if (appDelegate.session.isOpen) {
//[appDelegate.session closeAndClearTokenInformation];
[self retrieveAlbums];
} else {
if (appDelegate.session.state != FBSessionStateCreated) {
// Create a new, logged out session.
appDelegate.session = [[FBSession alloc] init];
}
// if the session isn't open, let's open it now and present the login UX to the user
[appDelegate.session openWithCompletionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
// and here we make sure to update our UX according to the new session state
//NSLog(#"%#",session.accessTokenData.accessToken);
[self retrieveAlbums];
}];
It works fine on iphone simulator. But I can't able to login on my iphone 4 device.
When I tried to login it will open a safari and then shows the message Updating.
Then it will redirect without authorization. access token retrieved as nil. So I cant able to retreive images.
Please help me.
EDIT
Thanks for everyone .Finally I solved my problem. It is because i enabled sandbox mode in facebook developer account settings. When i disabled the sandbox mode, it works normally.
Try clearing the cookies and cache of your safari, going to Settings.
Also if you do not want the app to redirect to Safari, just dont provide the URL Scheme in your info.plist that is something like "fb-AppId-" and it will open a popup for login
I was having the similar problem and solved it by composing couple of solutions in this website. First of all I got rid of the url scheme at my info plist. So now my app opens up the facebook login dialog inside my registration page. Which is a good thing because it doesn't go back and forth to safari for facebook authentication and you stay inside the app. The second thing I made is, putting an error handling mechanism inside my code for facebook login. So if login with facebook fails, it uses another strategy for logging in.
Here is my code.
- (void)loginView:(FBLoginView *)loginView handleError:(NSError *)error {
NSArray *permissions = [[NSArray alloc] initWithObjects:
#"public_profile", #"user_friends", #"email",
nil];
FBSession *session = [[FBSession alloc] initWithPermissions:permissions];
[FBSession setActiveSession:session];
[self openSessionWithAllowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
if (!error && status == FBSessionStateOpen) {
NSString *token = session.accessTokenData.accessToken;
NSLog(#"Logged in! - Token -- %#", token);
} else {
NSLog(#"Something wrong happened");//you can check the error code here
}
}];
}

Facebook iOS SDK Logout

I'm using the official and updated Facebook iOS SDK.
We're developing an application on an iPad that is used inside a physical store using an in-house distribution profile. Where customers can login to their Facebook account on an iPad that's publicly available to improve their shopping experience.
The problem I came across is that when a user logs into their Facebook account, the next user (customer) will still be logged in with the previous users' credentials (You have already authorized xxx, Press "Okay" to continue). Ofcourse this is not okay.
Is there a way to actually logout (sign off, clear credentials, or what ever) the previous (or current) user so the next user can fill in its own username and password.
Unfortunately [[FBSession activeSession] closeAndClearTokenInformation] doesn't quite do the trick.
This is a part of the code so far:
// ....
[[FBSession activeSession] closeAndClearTokenInformation];
[FBSession.activeSession openWithCompletionHandler:^(FBSession *session,
FBSessionState state,
NSError *error) {
// More code ...
}];
// ...
PS. The cookie 'workaround' doesn't work for me (obviously)
From your context, I'm assuming your device(s) does not have the Facebook app installed nor do you expect to use iOS 6 system authentication which would leave the default login behavior to use Safari. If you were to clear the Safari cookies, that should work but for a smoother experience in your scenario you should use the FBSession openWithBehavior:completionHandler: method and specify a behavior of FBSessionLoginBehaviorForcingWebview so that it uses the inline webview dialog for authentication.
See the SwitchUserSample in the Facebook iOS SDK for an example since that sample demonstrates an app that can toggle between multiple accounts.
Try with this code. I think it will help you.
FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
[login logOut];
If you are using facebook sdk 4.1.0 just call bellow method
if ([FBSDKAccessToken currentAccessToken]) {
[FBSDKAccessToken setCurrentAccessToken:nil];
[FBSDKProfile setCurrentProfile:nil];
}

FBRequest requestForMe startWithCompletionHandler method not working on device

I have followed all the directions from the Facebook Developer website about integrating Facebook SDK 3.1 into iOS 6. My code runs perfectly on the iPhone 6.0 Simulator (user can log into Facebook), but when I run the app on my iPhone, the function [FBRequest requestForMe] startWithCompletionHandler] doesn't generate a response. According to the Facebook Developer website, it should either be successful or return an error, but it does neither. The app just sits there waiting for a response that never comes. My code is below:
- (void)populateUserDetails {
if (FBSession.activeSession.isOpen) {
[[FBRequest requestForMe] startWithCompletionHandler:
^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
if (!error) {
NSLog(#"logged in");
} else {
NSLog(#"error: %#", error);
}
}];
} else {
NSLog(#"no active session");
}
}
Using breakpoints, I determined that the activeSession is always open, so the startWithCompletionHandler: method is actually called. Maybe it's a build problem since it runs fine on the Simulator? Any ideas?
make sure that a "0" value hasn't been inserted automatically for your App Store
ID
App Store ID is different than Bundle ID. Like it says on Facebook: "For security reasons, we check the bundle ID before authorizing your app". So you should set that exactly as the same as it is in Xcode which you did.
But App Store ID ("iPhone App Store ID that we can link to on Facebook") you set them when you already submitted you app and it's accepted. Therefore, for developing purpose you should set iPhone and iPad(if any) to 0 which I did and it's working fine on both Simulator and iPhone iOS 6.0.
It wasn't because of that 0, maybe you fixed something else?
Answered my own question: go to your Facebook app page and make sure that a "0" value hasn't been inserted automatically for your App Store ID. I had already set my bundle ID to the correct value (which you also have to do), but overnight, Facebook automatically set the App Store ID value to 0. Everything worked as soon as I removed that value.

post image on Facebook wall and facebook friends wall

I am very tired with the problems of API, like Facebook Graph API, weather API etc.
I've used both API in my project. Graph API for Facebook and Google weather API for weather, but now on time of project completion, both API are not working. Google weather API depreciated in November,
And the Facebook features I've been using (post image on wall and post image on friend wall) were working last day, but now they don't.
The problem is that when I log in, I get the message The page you requested is not Found and below a link to go back to the previous page.
And when i click the link "back to previous page" it shows message:
An error has occurred with AppName, please try again
API error code : 100
API error Description : Invalid Parameter
Error_message : cancel_URL URL is not properly formatted
I wants to know solution of Facebook API. Is this problem is with every developer? if API modified or changed what we can do regarding?
How long ago did you update your facebook API? About two weeks ago I had to remove my entire API, redownload, and change all the posting code my app was using. It stopped working entirely and had no idea until app users complained. Some necessary changes for the new facebook API:
Facebook recommends putting these in your appDelegate if you look at the newest sample apps.
#import <FacebookSDK/FacebookSDK.h>
- (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI {
NSArray *permissions = [NSArray arrayWithObjects:#"publish_actions", nil];
return [FBSession openActiveSessionWithPermissions:permissions
allowLoginUI:allowLoginUI
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
if(state==513){
//facebook usage has been approved
}
}];
}
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
// We need to handle URLs by passing them to FBSession in order for SSO authentication
// to work.
return [FBSession.activeSession handleOpenURL:url];
}
And whereever you want to make your post put something like this:
if(facebookEnabled==YES)
{
NSString *fbText=[NSString stringWithFormat:#"whatever text you want to post";
[FBRequestConnection startForPostStatusUpdate:fbText
completionHandler:^(FBRequestConnection *connection, id result, NSError *error)
{
}];
}
Let me know if you have questions. Hope it helps!
Well I'm not sure it's your code's fault but Facebook is having issues right now.
My FB app in iOS doesn't work anymore. You can try again by enabling sandbox mode (in FB app settings) with a developer account. It works for me.
http://developers.facebook.com/bugs/463219573709230?browse=search_504fc79a6ea272d92740759
look on my solution, but it's only for posting on user wall
http://www.developers-life.com/facebook-compose-view.html

Reading cookies using xcode on the iphone [duplicate]

Can an iPhone application read cookies previously stored by Safari Mobile?
To actually answer your question:
No.
Mobile Safari's cookies are not accessible from SDK apps. And each SDK app is given its own WebKit cache and cookie stores, so while cookies will persist within the same app, they aren't accessible betweeen apps.
As of iOS 9 this is possible!
Use a sfSafariViewController.
You will need to setup:
A custom URL scheme in your app to receive cookie data.
The website you are getting cookies from will need to implement an API specific your app's custom URL scheme, to redirect back to your app.
You can clone this repo which has a fully working demo of this.
Hope this helps,
Liam
There is actually an interesting way if you have access to a server url.
In your app launch the server url with mobile safari.
The target server url reads the cookie and redirects back to an app specific url (myapp://cookie=123)
The app is then switched back and you can read that value from the url handler
It's a little hacky as the app would switch mobile safari and then immediately switch back to the app. But, it is possible.
Note that on iOS 8, you're probably better using Safari Password Sharing to solve some of the use cases that give rise to this problem.
This is not directly possible, but with the cooperation of the web site it is possible.
To clarify, the user case is that an Objective C application wants to read the value of a cookie that has been set by a website in mobile safari. (ie. in particular, a UIWebView was not involved in setting the cookie)
Your app should do this:
Launch mobile safari, using [[UIApplication sharedApplication] openURL:url];
The URL should be a special one, eg. http://yourwebsite.com/give-ios-app-the-cookie
On your website, when that url is launched, issue a redirect to your-app-url-scheme:cookievalue= (eg. angrybirds:cookievalue=hh4523523sapdfa )
when your app delegate receives - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation process the url to get the cookie value
Note that you should not do this automatically when the application starts - the user will see the transfer to Mobile Safari and back, which is not a good user experience and Apple will reject your app (Apple also consider this to be "uploading user's personal data to server without their prior consent"). It would be better to do it in response to the user, paying attention to the user experience - eg. wait for the user to hit a "login" button, then do it, and if the user is not logged into your website, http://yourwebsite.com/give-ios-app-the-cookie should show the user the login screen within safari. If the user is logged in you could briefly show a "Automatically logging you in..." screen for a second or two in Safari before redirecting the user back.
There's no way to get this to work with hotmail/gmail/etc of course - it needs to be your own website.
Credit goes to Unique Identifier for both mobile safari and in app in iOS for suggesting this kind of approach.
Because of sandboxing on the iPhone you don't have access to Safari's cookies. You can only access cookies created within your application - by an UIWebView for example.
Although you have asked the same question twice before, here's one approach not yet mentioned...
This may be a little convoluted, but you can do Greasemonkey-esque things with a UIWebView. Something like this:
Load your target page
craft some javascript which will read the document.cookie and return the data you need
In the webViewDidFinishLoad delegate, inject this javascript into the UIWebView with the stringByEvaluatingJavaScriptFromString message
I've used this technique to enhance 3rd party pages in an iPhone app, but I'm not sure if it will read cookies from the same place as Safari mobile.
Worth a shot though?
Here's my utils get/set cookie methods.
+(void)setCookie:(NSString *)key withValue:(NSString *)value {
NSArray *keys = [NSArray arrayWithObjects:
NSHTTPCookieDomain,
NSHTTPCookieExpires,
NSHTTPCookieName,
NSHTTPCookiePath,
NSHTTPCookieValue, nil];
NSArray *objects = [NSArray arrayWithObjects:
#"YOURDOMAIN",
[NSDate distantFuture],
key,
#"/",
value, nil];
NSDictionary *dict = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:dict];
NSHTTPCookieStorage *sharedHTTPCookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
[sharedHTTPCookieStorage setCookie:cookie];
}
+(NSString *)getCookie:(NSString *)key {
NSHTTPCookieStorage *sharedHTTPCookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
NSArray *cookies = [sharedHTTPCookieStorage cookiesForURL:[NSURL URLWithString:#"YOURDOMAIN"]];
NSEnumerator *enumerator = [cookies objectEnumerator];
NSHTTPCookie *cookie;
while (cookie = [enumerator nextObject])
{
if ([[cookie name] isEqualToString:key])
{
return [cookie value];
}
}
return nil;
}
You might want to check
if ([[NSHTTPCookieStorage sharedHTTPCookieStorage] cookieAcceptPolicy] != NSHTTPCookieAcceptPolicyAlways) {
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];
}
But apparently NSHTTPCookieStorage does not even hold cookies from the last request in the current application on iOS (rdar://8190706)