Facebook login using iOS SDK

I’ve been doing some work with the Facebook SDK recently. Getting login to work properly has been quite difficult. Here are my findings which others might find helpful.

There are 4 ways the FB SDK lets you authenticate a user:

  • Use the native FB login (available since iOS 6)
  • Use single sign on (SSO) which means that the SDK will try to use the credentials of the Facebook app if it is installed on your device
  • Use Safari. Your app will switch to Safari, where you log in and then switch back after authentication
  • Use an embedded web view

There are various flavours of APIs for handling login. I am using [session openWithBehavior:completionHandler:].

  • If you want native FB login, you have to pass FBSessionLoginBehaviorUseSystemAccountIfPresent into the behavior parameter. Native login has several advantages:
    • Only native login seems to accept “public” posting as default. Other login methods will always revert to “friends” posting, no matter how you configure your session
    • Only native login  allows granting read and write Facebook permissions with one single “accept” click.
      Since FB SDK 3.5 read and write permissions have to be granted separately
    • One disadvantage: The user can withdraw your app’s FB permission in the device’s Facebook settings. So you have to handle the case on each app wakeup (not only startup), that your permissions could suddenly be gone (ie. your access token has expired).
  • If you request native login and the user hasn’t setup his account in the iOS settings, the fallback will be SSO. If you want SSO per default instead of native (Candy Crush Saga does this) then you have to use behavior FBSessionLoginBehaviorWithFallbackToWebView. What SSO does is the following: instead of asking the user for his credentials it will app switch to the FB app, if it is installed. It will use the FB app’s credentials and only ask the user if he grants your app access. Read and write permissions will be split into two separate dialogs. Public sharing as default did not work for me.
    To get SSO to work properly requires:

    • In your app delegate, in application:openURL: sourceApplication:annotation: call [FBAppCall handleOpenURL:sourceApplication:] and return its value.
    • In you app’s info.plist CFBundleURLTypes->CFBundleURLSchemes make sure entry 0 is fb138063766382361 (the number is your FB app ID)
    • Make sure FacebookAppID is correct in info.plist
    • Since SDK 3.5 make sure FacebookDisplayName is your FB App display name (from the FB app settings)
    • Make sure SSO for iOS is enabled in FB app settings (in the FB web settings form)
    • SSO has the advantage that the user cannot revoke your access token as easily as with native login
    • Its disadvantages are:
      • app switch doesn’t look as good and breaks UI flow
      • no public posting per default
      • user can deny write access after allowing read access. You need to check later when you want to post, if write has been granted.
      • you have to handle the app switch. In case you are doing stuff like reloading resources, connections etc. you might not want to do this for login only
  • Safari is the fallback if both native and SSO fail. Again it is an app switch and the user will have to enter his FB credentials. This method is not very convenient and should be avoided.
  • Webview. This can be enforced using FBSessionLoginBehaviorForcingWebView. It is similar to Safari but without the app switch, using an overlay UIWebView instead. The user has to enter his credentials, read and write permissions are split. There is one big advantage of using the webview though: Since all apps are sandboxed your app’s web views don’t have access to Safari’s or FB app cookies/caches. So if you for some reason need to access some FB features using embedded UIViews, then this login type will make sure the user doesn’t have to authenticate twice (once for the app and once for the web views). E.g. the FB Like plugin is only available as embedded iframe from Facebook.
    (I am not 100% sure on this one since during testing I had weird occurences like webview credentials working for some time if using a different login method but expiring earlier, etc.)

So yeah, FB login is that complicated 🙂 Also working with the FB SDK is not an easy thing since it changes quite frequently and you’ll run into a lot of tutorials and tips (e.g. on Stackoverflow) that are outdated and don’t apply to the latest version anymore.

Share this:
  • Gutte

    Hi Gottfried. Great post. I’m also using loginWithBehavior in my app. recently upgraded to v3.14. ever since, only native login works for me. when using sso or safari, i always get FBSessiosnClosedLoginFailed with no error. Did you stumble upon this behavior?

    • GottfriedChen

      I’m still on 3.10. Thanks for the info, looks like I’ll postpone updating then.

  • Jainam

    Hi, Could you post the code which you have used in which case FB login falls to SSO if native login is not available.