Xamarin iOS: Using Facebook SDK login button

Viewed 600

We are trying to implement a simple (or so I thought) Facebook login button in a Xamarin iOS mobile app. I have installed the Xamarin.Facebook.iOS package, and then performed the following steps:

  1. Dropped a UIButton into my storyboard's view, and changed its class to FBSDKLoginButton
  2. Updated my View Controller to set btnLogin.Permissions = new string[] { "email" }
  3. Copied the settings from https://developers.facebook.com/docs/app-events/getting-started-app-events-ios/ into Info.plist (this includes App ID, etc)
  4. Added keychain-access-groups string to Entitlements.plist (I do not remember offhand why I needed this, but this fixed a separate issue)
        <dict>
            <key>keychain-access-groups</key>
            <array>
                <string>$(AppIdentifierPrefix)[appname]</string>
            </array>
        </dict>

This was enough to get everything working in the simulator, however when I deployed this to TestFlight and installed into a physical device, the facebook button opens the modal, redirects to the native application where I can approve the login, closes the Facebook app, and returns to the modal. In the simulator, the modal closes and I am logged in, however on the physical device (iPhone 11 on iOS 13.5), the modal just sits there, and I am not logged in. Manually closing the modal windows doesn't trigger the btnLogin.Completed event.

If I look through the official Facebook SDK documentation for iOS native (in swift), there are some specific mentions for SceneDelegate updates needed for iOS 13: https://developers.facebook.com/docs/app-events/getting-started-app-events-ios/. I have a feeling that this is related, however I have had no luck finding ANY examples of how I can accomplish this in Xamarin iOS/C#. I am not familiar enough with the swift language to translate this into something I can use in my app.

If you are using iOS 13 or above please add the following method to your SceneDelegate:

// SceneDelegate.swift

func scene(_ scene: UIScene, openURLContexts URLContexts:
Set<UIOpenURLContext>) {
guard let url = URLContexts.first?.url else {
    return
}

ApplicationDelegate.shared.application(
    UIApplication.shared,
    open: url,
    sourceApplication: nil,
    annotation: [UIApplication.OpenURLOptionsKey.annotation]
) }

Has anyone had any luck getting the Facebook SDK Login Button working on an iOS 13+ device, and care to share how you accomplished that?

UPDATE:

After some more digging, I am feeling like this has LESS to do with being on a physical device and MORE to do with Safari login vs. Native Facebook app login. Unfortunately, there's no way to test native FB login on the simulator, and I am using a Cloud mac, so there's no way to debug directly on my device. Looks like I'll need to keep pushing builds out to testflight in order to troubleshoot and test this issue.

1 Answers

So it took a few tries, but I finally got it working. Code updates below:

AppDelegate.cs

Update the FinishedLaunching method:

    [Export ("application:didFinishLaunchingWithOptions:")]
    public bool FinishedLaunching (UIApplication application, NSDictionary launchOptions)
    {
        // Override point for customization after application launch.
        // If not required for your application you can safely delete this method
        Facebook.CoreKit.ApplicationDelegate.SharedInstance.FinishedLaunching(application, launchOptions);
        return true;
    }

SceneDelegate.cs

Add the following method (not included by default in a new Xamarin iOS project at time of writing):

    [Export("scene:openURLContexts:")]
    public void OpenUrlContexts(UIScene scene, NSSet<UIOpenUrlContext> urlContexts)
    {
        var urlString = urlContexts.AnyObject.Url;
        Facebook.CoreKit.ApplicationDelegate.SharedInstance.OpenUrl(
            UIApplication.SharedApplication,
            urlString,
            null,
            UIApplication.LaunchOptionsUrlKey
        );
    }
Related