I have problem with facebook Login..I integrated Facebook into my app.First time when user wants to login it is showing login page,but from next time it is going to page "You have already authorised APP_NAME".
I checked for Scrumptious tutorial which is the sample which I got from Facebook SDK.and it is also working like same.
I want to login from different user,I dont want that page "You have already authorised APP_NAME" every time.
How to solve this.
Try this code in your app delegate class.
It checks whether the session is open or not and clears your login credentials from the device cache when you close the connection.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
LoginVC *loginScreen=[[LoginVC alloc]initWithNibName:#"LoginVC" bundle:nil];
navigationController=[[UINavigationController alloc]initWithRootViewController:loginScreen];
self.navigationController.navigationBar.tintColor = [UIColor blackColor];
self.window.rootViewController=self.navigationController;
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
// See if we have a valid token for the current state.
if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) {
[self openSession];
// To-do, show logged in view
} else {
// No, display the login page.
[self showLoginView];
}
return YES;
}
- (void)sessionStateChanged:(FBSession *)session
state:(FBSessionState) state
error:(NSError *)error
{
switch (state) {
case FBSessionStateOpen: {
UIViewController *topViewController =
[self.navigationController topViewController];
if ([[topViewController presentedViewController]
isKindOfClass:[LoginVC class]]) {
[topViewController dismissViewControllerAnimated:YES completion:nil];
}
}
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
// Once the user has logged in, we want them to
// be looking at the root view.
[self.navigationController popToRootViewControllerAnimated:NO];
[FBSession.activeSession closeAndClearTokenInformation];
[self showLoginView];
break;
default:
break;
}
if (error) {
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:#"Error"
message:error.localizedDescription
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
}
- (void)openSession
{
[FBSession openActiveSessionWithReadPermissions:nil
allowLoginUI:YES
completionHandler:
^(FBSession *session,
FBSessionState state, NSError *error) {
[self sessionStateChanged:session state:state error:error];
}];
}
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
return [FBSession.activeSession handleOpenURL:url];
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
// We need to properly handle activation of the application with regards to Facebook Login
// (e.g., returning from iOS 6.0 Login Dialog or from fast app switching).
[FBSession.activeSession handleDidBecomeActive];
}
I hope this code will be helpful.
Related
appdelegate.m
if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) {
// Yes, so just open the session (this won't display any UX).
NSLog(#"token loaded");
[self openSession];
} else {
// No, display the login page.
//[self showLoginView];
NSLog(#"token not loaded");
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
// We need to properly handle activation of the application with regards to Facebook Login
// (e.g., returning from iOS 6.0 Login Dialog or from fast app switching).
[FBSession.activeSession handleDidBecomeActive];
}
pragma mark -
- (void)sessionStateChanged:(FBSession *)session
state:(FBSessionState) state
error:(NSError *)error
{
switch (state) {
case FBSessionStateOpen: {
NSLog(#"session state open");
}
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
[FBSession.activeSession closeAndClearTokenInformation];
NSLog(#"session state closed");
break;
default:
break;
}
if (error) {
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:#"Error"
message:error.localizedDescription
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
}
- (void)openSession
{
[FBSession openActiveSessionWithReadPermissions:#[#"public_profile, email, user_friends"] allowLoginUI:YES completionHandler:^(FBSession *session,
FBSessionState state, NSError *error) {
NSLog(#"It is never called");
[self sessionStateChanged:session state:state error:error];
}];
}
- (void)obatinUserInfo {
}
pragma mark -
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
NSLog(#"it is never called");
return [FBSession.activeSession handleOpenURL:url];
}
view controller.m
===========
button action
- (IBAction)performLogin:(id)sender {
AppDelegate* appDelegate = [UIApplication sharedApplication].delegate;
[appDelegate openSession];
}
This is my code when call Facebook login goes to opensession, but not called within completion handler and open url.
Many links i refered but not working.
The same code working indivitual project but integrated into my project means not working.
Please assist me
Thanks in advance
S.Arul
I am new to IOS and I created a Facebook custom login and logout buttons for my app using Facebook SDK. Login button works as I expected, but when I clicked my logout button, it gives the login page as I redirected to it. Then, when I try to login again, it doesn't show the Facebook login UI. But when I logged out my Facebook app and try to login to my app, the login UI works well. Here is my logout button.
- (IBAction)btnClicked:(id)sender {
[FBSession.activeSession closeAndClearTokenInformation];
NSLog(#"log out");
LoginUIViewController *loginController1= [[LoginUIViewController alloc] initWithNibName:#"LoginUIViewController" bundle:nil];
[self presentViewController:loginController1 animated:YES completion:nil];
}
Do I need to implement a logout button in my view controller or does FB SDK provides the logout facility it self?
# Vinod Jat,,
I made following changes in my appDelegate..
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[SplashViewController alloc] initWithNibName:#"SplashViewController" bundle:nil];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
// Whenever a person opens the app, check for a cached session
if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) {
// If there's one, just open the session silently, without showing the user the login UI
[FBSession openActiveSessionWithReadPermissions:#[#"public_profile"]
allowLoginUI:NO
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
[self sessionStateChanged:session state:state error:error];
}];
}
return YES;
}
//This method will handle ALL the session state changes in the app
- (void)sessionStateChanged:(FBSession *)session state:(FBSessionState) state error:(NSError *)error
{
// If the session was opened successfully
if (!error && state == FBSessionStateOpen){
NSLog(#"Session opened");
return;
}
if (state == FBSessionStateClosed || state == FBSessionStateClosedLoginFailed){
// If the session is closed
NSLog(#"Session closed");
}
.........
}
**In my loginUIViewController I have added following method..**
- (IBAction)FbloginButton:(id)sender {
NSLog(#"inside login button");
[FBSession openActiveSessionWithReadPermissions:#[#"public_profile"]
allowLoginUI:YES
completionHandler:
^(FBSession *session, FBSessionState state, NSError *error) {
NSLog(#"inside login button2");
// Retrieve the app delegate
TNLAppDelegate* appDelegate = [UIApplication sharedApplication].delegate;
// Call the app delegate's sessionStateChanged:state:error method to handle session state changes
[appDelegate sessionStateChanged:session state:state error:error];
NSLog(#"inside login button3");
}];
//redirect to now playing page
NowPlayingViewController *nowPlaying= [[NowPlayingViewController alloc] initWithNibName:#"NowPlayingViewController" bundle:nil];
[self presentViewController:nowPlaying animated:YES completion:nil];
}
I am using login with facebook in my app and getting username and profile pic from facebook. I have tested and it is working fine at my end, but apple has rejected it two times. I dont find any error at my end .
This is error by apple team:-
" We still found that your app exhibited one or more bugs, when reviewed on iPad Air running iOS 7.1 and an iPhone 5s running iOS 7.1, on both Wi-Fi and cellular networks, which is not in compliance with the App Store Review Guidelines.
Specifically, when we tap login to Facebook we get message say it wants to connect and when we tap ok it does not advance and connect with Facebook. "
Here is my Code
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window = window;
self.login=[[ViewController alloc]init];
_nav = [[UINavigationController alloc] initWithRootViewController:self.login];
self.window.rootViewController = _nav;
[self.window makeKeyAndVisible];
// Override point for customization after application launch.
// Whenever a person opens the app, check for a cached session
if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) {
NSLog(#"Found a cached session");
// If there's one, just open the session silently, without showing the user the login UI
[FBSession openActiveSessionWithReadPermissions:#[#"basic_info", #"email", #"user_likes"]
allowLoginUI:NO
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
// Handler for session state changes
// This method will be called EACH time the session state changes,
// also for intermediate states and NOT just when the session open
[self sessionStateChanged:session state:state error:error];
switch (state) {
case FBSessionStateOpen:
[[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
if (error) {
NSLog(#"error:%#",error);
}
else
{
// retrive user's details at here as shown below
NSUserDefaults *storeData=[NSUserDefaults standardUserDefaults];
[storeData setObject:user.id forKey:#"user_id"];
[storeData setObject:user.name forKey:#"name"];
}
}];
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
[FBSession.activeSession closeAndClearTokenInformation];
break;
default:
break;
}
}];
// If there's no cached session, we will show a login button
} else {
//UIButton *loginButton = [self.login loginButton];
//[loginButton setTitle:#"Log in with Facebook" forState:UIControlStateNormal];
}
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
// This method will handle ALL the session state changes in the app
- (void)sessionStateChanged:(FBSession *)session state:(FBSessionState) state error:(NSError *)error
{
// If the session was opened successfully
if (!error && state == FBSessionStateOpen){
NSLog(#"Session opened");
// Show the user the logged-in UI
[self userLoggedIn];
return;
}
if (state == FBSessionStateClosed || state == FBSessionStateClosedLoginFailed){
// If the session is closed
NSLog(#"Session closed");
// Show the user the logged-out UI
[self userLoggedOut];
}
// Handle errors
if (error){
NSLog(#"Error");
NSString *alertText;
NSString *alertTitle;
// If the error requires people using an app to make an action outside of the app in order to recover
if ([FBErrorUtility shouldNotifyUserForError:error] == YES){
alertTitle = #"Something went wrong";
alertText = [FBErrorUtility userMessageForError:error];
[self showMessage:alertText withTitle:alertTitle];
} else {
// If the user cancelled login, do nothing
if ([FBErrorUtility errorCategoryForError:error] == FBErrorCategoryUserCancelled) {
NSLog(#"User cancelled login");
// Handle session closures that happen outside of the app
} else if ([FBErrorUtility errorCategoryForError:error] == FBErrorCategoryAuthenticationReopenSession){
alertTitle = #"Session Error";
alertText = #"Your current session is no longer valid. Please log in again.";
[self showMessage:alertText withTitle:alertTitle];
// For simplicity, here we just show a generic message for all other errors
// You can learn how to handle other errors using our guide: https://developers.facebook.com/docs/ios/errors
} else {
//Get more error information from the error
NSDictionary *errorInformation = [[[error.userInfo objectForKey:#"com.facebook.sdk:ParsedJSONResponseKey"] objectForKey:#"body"] objectForKey:#"error"];
// Show the user an error message
alertTitle = #"Something went wrong";
alertText = [NSString stringWithFormat:#"Please retry. \n\n If the problem persists contact us and mention this error code: %#", [errorInformation objectForKey:#"message"]];
[self showMessage:alertText withTitle:alertTitle];
}
}
// Clear this token
[FBSession.activeSession closeAndClearTokenInformation];
// Show the user the logged-out UI
[self userLoggedOut];
}
}
// Show the user the logged-out UI
- (void)userLoggedOut
{
// Set the button title as "Log in with Facebook"
// UIButton *loginButton = [self.login loginButton];
//[loginButton setTitle:#"Log in with Facebook" forState:UIControlStateNormal];
// Confirm logout message
//[self showMessage:#"You're now logged out" withTitle:#""];
}
// Show the user the logged-in UI
- (void)userLoggedIn
{
// Set the button title as "Log out"
// UIButton *loginButton = self.login.loginButton;
//[loginButton setTitle:#"Log out" forState:UIControlStateNormal];
FrontViewController *v=[[FrontViewController alloc]init];
RearViewController *rearViewController = [[RearViewController alloc] init];
UINavigationController *frontNavigationController = [[UINavigationController alloc] initWithRootViewController:v];
UINavigationController *rearNavigationController = [[UINavigationController alloc] initWithRootViewController:rearViewController];
SWRevealViewController *revealController = [[SWRevealViewController alloc] initWithRearViewController:rearNavigationController frontViewController:frontNavigationController];
revealController.delegate = self;
[self.nav pushViewController:revealController animated:YES];
[self showMessage:#"You're now logged in" withTitle:#"Welcome!"];
}
// Show an alert message
- (void)showMessage:(NSString *)text withTitle:(NSString *)title
{
[[[UIAlertView alloc] initWithTitle:title
message:text
delegate:self
cancelButtonTitle:#"OK!"
otherButtonTitles:nil] show];
}
// During the Facebook login flow, your app passes control to the Facebook iOS app or Facebook in a mobile browser.
// After authentication, your app will be called back with the session information.
// Override application:openURL:sourceApplication:annotation to call the FBsession object that handles the incoming URL
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
return [FBSession.activeSession handleOpenURL:url];
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Handle the user leaving the app while the Facebook login dialog is being shown
// For example: when the user presses the iOS "home" button while the login dialog is active
[FBAppCall handleDidBecomeActive];
}
In My View Controller
- (IBAction)buttonTouched:(id)sender
{
// 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) {
// Close the session and remove the access token from the cache
// The session state handler (in the app delegate) will be called automatically
[FBSession.activeSession closeAndClearTokenInformation];
// 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 basic_info permissions when opening a session
[FBSession openActiveSessionWithReadPermissions:#[#"basic_info", #"email", #"user_likes"]
allowLoginUI:YES
completionHandler:
^(FBSession *session, FBSessionState state, NSError *error) {
// Retrieve the app delegate
AppDelegate* appDelegate = [UIApplication sharedApplication].delegate;
// Call the app delegate's sessionStateChanged:state:error method to handle session state changes
[appDelegate sessionStateChanged:session state:state error:error];
switch (state) {
case FBSessionStateOpen:
[[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
if (error) {
NSLog(#"error:%#",error);
}
else
{
// retrive user's details at here as shown below
NSLog(#"FB user first name:%#",user.first_name);
NSUserDefaults *storeData=[NSUserDefaults standardUserDefaults];
[storeData setObject:user.id forKey:#"user_id"];
[storeData setObject:user.name forKey:#"name"];
}
}];
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
[FBSession.activeSession closeAndClearTokenInformation];
break;
default:
break;
}
}];
}
}
Is your app on developer.facebook.com public and available for all users?
Status should look like this:
In other case if your app has status Developer Mode then other users can't authorise by Facebook.
I have exactly the same issue. Although it's a Flutter app, but the use-case is the same.
On my end, everything works as expected
Fb app has iOS and Bundle ID set correctly
FB app is public
But the Apple review team still rejects it. I asked for more Screenshots, which they provided, AND the screenshots clearly show the "continue" dialog of the FB-popup. So I don't understand why they rejected it.
I have an app with facebook integrations und sometimes everything works fine, but now I got some mails that some people cannot login with Facebook.
Now I now what is the problem.
If I am not logged in through the setting in my facebook account everything works fine, but when I logged in through setting I always get in the sessionStateChanged funciton the case FBSessionStateClosedLoginFailed:
What can I do against it?
Here is my code:
First when I click on login with Facebook I use this function:
- (void)facebookLoginFunction {
if ([self checkInternet]==TRUE) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(sessionStateChanged:) name:FBSessionStateChangedNotification object:nil];
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication]delegate];
// The person using the app has initiated a login, so call the openSession method
// and show the login UX if necessary.
[appDelegate openSessionWithAllowLoginUI:YES];
}
}
and the function sessionStateChanged: in the Delegate
- (void)sessionStateChanged:(FBSession *)session state:(FBSessionState) state error:(NSError *)error{
switch (state) {
case FBSessionStateOpen:
if (!error) {
// We have a valid session
NSLog(#"User session found");
}
break;
case FBSessionStateClosed: NSLog(#"User session closed");
case FBSessionStateClosedLoginFailed:{ NSLog(#"Login failed");
[FBSession.activeSession closeAndClearTokenInformation];}
break;
default:
break;
}
[[NSNotificationCenter defaultCenter] postNotificationName:FBSessionStateChangedNotification object:session];
if (error) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error" message:error.localizedDescription delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
}
}
I realy hope that you can help me, cause I dont understand this crazy problem.
thanks
Adding both
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
return [FBSession.activeSession handleOpenURL:url];
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
[FBSession.activeSession handleDidBecomeActive];
}
Worked!
All credits go to Skrew for this answer.
I'm using the FB iOS SDK to get the user's credentials and access token and save them. With the previous version I managed to properly do this, but my solution broke with the upgrade to iOS 6, so I downloaded the new version from Github, and compiled and added the framework to my project according to the instructions.
I properly authenticate my user with FB, but when the browser (the modal view controller presented for auth) is dismissed my user reverts to the initial view of my app instead of the view that the process was launched from.
Right now I have code in my app delegate and my SocialNetworksViewController to do this.
In AppDelegate:
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [FBSession.activeSession handleOpenURL:url];
}
- (void)sessionStateChanged:(FBSession *)session
presentingViewController:(UIViewController *)presentingViewController
state:(FBSessionState) state
error:(NSError *)error
{
switch (state) {
case FBSessionStateOpen: {
[presentingViewController dismissModalViewControllerAnimated:YES];
}
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
// Once the user has logged in, we want them to
// be looking at the root view.
[FBSession.activeSession closeAndClearTokenInformation];
break;
default:
break;
}
[[NSNotificationCenter defaultCenter] postNotificationName:FBSessionStateChangedNotification
object:session];
if (error) {
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:#"Error"
message:error.localizedDescription
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
}
- (void)openSessionFromViewController:(UIViewController *)viewController
{
NSArray *permissions = [NSArray arrayWithObjects:#"publish_stream", #"email", #"user_birthday", nil];
[FBSession openActiveSessionWithPermissions:permissions
allowLoginUI:YES
completionHandler:
^(FBSession *session,
FBSessionState state, NSError *error) {
[self sessionStateChanged:session presentingViewController:viewController state:state error:error];
}];
}
In SocialNetworksViewController:
- (IBAction)connectToFacebook:(UIButton *)sender {
if (!self.facebookConnected) {
AppDelegate <UIApplicationDelegate> *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
[appDelegate openSessionFromViewController:self];
}
}
- (void)sessionStateChanged:(NSNotification*)notification {
NSLog(#"%#", FBSession.activeSession.accessToken);
}
- (void)facebookLoginFailed {
}
This is in viewDidLoad as well:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(sessionStateChanged:)
name:FBSessionStateChangedNotification
object:nil];
In the sessionStateChanged method, the NSLog outputs and then I get send to my initial view.