Search code examples
c#xamarinpaypalsfsafariviewcontrollerdelegate

SFSafariViewController notification when token received


Converting the code in the following swift sample to C# (Xamarin) to notify the App when Paypal Token is received inside SFSafariViewController but it does not fire the method.

https://github.com/paypal/paypal-here-sdk-ios-distribution/blob/master/SampleApp/PPHSDKSampleApp/InitializeViewController.swift

Converted the swift to C# as following but after user login to PayPal and receives the token, Safari is not closing to fire SetupMerchant()

UrlSchemes is also set to retailsdksampleapp to match the sample swift app from PayPal.

SafariDelegate safariDelegate = new SafariDelegate(this);
NSNotificationCenter.DefaultCenter.AddObserver(new NSString("kCloseSafariViewControllerNotification"), safariDelegate.SetupMerchant);
void loadBrowser()
{
    var url = new NSUrl("https://paypalauth.herokuapp.com/toPayPal/" + Application.paypalEnvironment + "?returnTokenOnQueryString=true");
    var svc = new SFSafariViewController(url);
    svc.Delegate = safariDelegate;
    this.PresentViewController(svc, true, null);
}
public class SafariDelegate : SFSafariViewControllerDelegate
{
    ViewController _controller = null;
    public SafariDelegate(ViewController controller)
    {
        _controller = controller;
    }

    public void SetupMerchant(NSNotification notification)
    {
        // Dismiss the SFSafariViewController when the notification of token has been received.
            this._controller.PresentedViewController?.DismissViewController(true, () => { });

        // Grab the token(s) from the notification and pass it into the merchant initialize call to set up
        // the merchant.  Upon successful initialization, the 'Connect Card Reader' button will be
        // enabled for use.
        var accessToken = notification.Object.ToString();
    }
}

When running the swift sample app from Paypal, it closes the browser (SFSafariViewController) after login and fires the SetupMerchant() but not in the C# code. There is possibly a missing step or invalid code conversion.


Solution

  • If the Safari controller is not closing and you have the proper UrlScheme set (), then you are missing the OpenUrl override in your AppDelegate class that listening for your app's url schemes and posts the notification that your view controller is listening for.

    Example:

    [Export("application:openURL:sourceApplication:annotation:")]
    public bool OpenUrl(UIApplication application, NSUrl url, string sourceApplication, NSObject annotation)
    {
        if (sourceApplication == "com.apple.SafariViewService")
        {
            var dict = HttpUtility.ParseQueryString(url.Query);
            var token = dict["access_token"];
            NSNotificationCenter.DefaultCenter.PostNotificationName("kCloseSafariViewControllerNotification", new NSString(token));
        };
        return true;
    }