I had a similar issue and I ended up using a MODIFIED version of the SDK which is actually quite dangerous because another developer may not know that it was modified.. So you'd need to leave a note..
Issue: After you log out, you are still logged in (in Safari).. but only if you use Native login or System login, and there's no way to log out of Safari from within the app itself.. Super annoying (You cannot clear Safari's cookies or data from within the app either).
Solution(s):
If you look through the documentation for the SDK, it shows:
// Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
//
// You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
// copy, modify, and distribute this software in source code or binary form for use
// in connection with the web services and APIs provided by Facebook.
//
// As with any software that integrates with the Facebook platform, your use of
// this software is subject to the Facebook Developer Principles and Policies
// [http://developers.facebook.com/policy/]. This copyright notice shall be
// included in all copies or substantial portions of the software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
typedef NS_ENUM(NSUInteger, FBSDKLoginBehavior)
{
/*!
@abstract This is the default behavior, and indicates logging in through the native
Facebook app may be used. The SDK may still use Safari instead.
*/
FBSDKLoginBehaviorNative = 0,
/*!
@abstract Attempts log in through the Safari or SFSafariViewController, if available.
*/
FBSDKLoginBehaviorBrowser,
/*!
@abstract Attempts log in through the Facebook account currently signed in through
the device Settings.
@note If the account is not available to the app (either not configured by user or
as determined by the SDK) this behavior falls back to c FBSDKLoginBehaviorNative.
*/
FBSDKLoginBehaviorSystemAccount,
/*!
@abstract Attemps log in through a modal c UIWebView pop up
@note This behavior is only available to certain types of apps. Please check the Facebook
Platform Policy to verify your app meets the restrictions.
*/
FBSDKLoginBehaviorWeb,
};
So if you use Native but it can't, it will fallback to Safari. If you use System but it can't, it falls back to Native which falls back to Safari..
Then there's FBSDKLoginBehaviorWeb which uses a modal web-view/popup! So if you don't absolutely have to use Native or System Login, then I suggest you choose this option as it does NOT fall-back to Safari.
Otherwise:
This is what I changed so that it NEVER uses Safari in the background:
FBLoginSDKManager.m:
- (void)logInWithBehavior:(FBSDKLoginBehavior)loginBehavior
{
NSDictionary *loginParams = [self logInParametersWithPermissions:_requestedPermissions];
void(^completion)(BOOL, NSString *, NSError *) = ^void(BOOL didPerformLogIn, NSString *authMethod, NSError *error) {
if (didPerformLogIn) {
[_logger startAuthMethod:authMethod];
_performingLogIn = YES;
} else {
if (!error) {
error = [NSError errorWithDomain:FBSDKLoginErrorDomain code:FBSDKLoginUnknownErrorCode userInfo:nil];
}
[self invokeHandler:nil error:error];
}
};
switch (loginBehavior) {
case FBSDKLoginBehaviorNative: {
if ([FBSDKInternalUtility isFacebookAppInstalled]) {
[FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:^(FBSDKServerConfiguration *serverConfiguration, NSError *loadError) {
BOOL useNativeDialog = [serverConfiguration useNativeDialogForDialogName:FBSDKDialogConfigurationNameLogin];
if (useNativeDialog && loadError == nil) {
[self performNativeLogInWithParameters:loginParams handler:^(BOOL openedURL, NSError *openedURLError) {
if (openedURLError) {
[FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors
formatString:@"FBSDKLoginBehaviorNative failed : %@
Trying FBSDKLoginBehaviorBrowser", openedURLError];
}
if (openedURL) {
completion(YES, FBSDKLoginManagerLoggerAuthMethod_Native, openedURLError);
} else {
[self logInWithBehavior:FBSDKLoginBehaviorWeb]; //-- CHANGED BY BRANDON T.
}
}];
} else {
[self logInWithBehavior:FBSDKLoginBehaviorWeb]; //-- CHANGED BY BRANDON T.
}
}];
break;
}
// intentional fall through. -- CHANGED BY BRANDON T.
[self logInWithBehavior:FBSDKLoginBehaviorWeb]; //-- CHANGED BY BRANDON T.
break;
}
case FBSDKLoginBehaviorBrowser: {
[self performBrowserLogInWithParameters:loginParams handler:^(BOOL openedURL,
NSString *authMethod,
NSError *openedURLError) {
if (openedURL) {
completion(YES, authMethod, openedURLError);
} else {
completion(NO, authMethod, openedURLError);
}
}];
break;
}
case FBSDKLoginBehaviorSystemAccount: {
[FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:^(FBSDKServerConfiguration *serverConfiguration, NSError *loadError) {
if (serverConfiguration.isSystemAuthenticationEnabled && loadError == nil) {
[self beginSystemLogIn];
} else {
[self logInWithBehavior:FBSDKLoginBehaviorNative];
}
}];
completion(YES, FBSDKLoginManagerLoggerAuthMethod_System, nil);
break;
}
case FBSDKLoginBehaviorWeb:
[self performWebLogInWithParameters:loginParams handler:^(BOOL openedURL, NSError *openedURLError) {
completion(openedURL, FBSDKLoginManagerLoggerAuthMethod_Webview, openedURLError);
}];
break;
}
}
This makes it so that all native login or system login will fall-back to the modal-in-app UIWebView
. Then you can clear the cookies when the log out and you'll be fine.. Delete All NSHTTPCookieStorage.sharedHTTPCookieStorage().cookies
and NSURLCache.sharedURLCache().removeAllCachedResponses()
after logging out.
The obviously safest option is to never use the System or Native Login and instead always use: FBSDKLoginBehaviorWeb
..