I am working with an mobile application using cross-platform Xamarin.Forms along with Shell feature for navigation. I integrated a third party payment gateway using its SDK in my project on both platforms(Android and iOS). I am using dependency service to initiate the payment process in both platforms. For iOS app, payment screen didn't load inside the app. Instead it opens in new window outside the app. All other screens are working fine. For Android, there is no problem. After searching a lot of articles, I found out that in iOS, root view controller is not available when using Xamarin.Forms. I didn't use any storyboard except default LaunchScreen.storyboard.
Xamarin.Forms version: 5.0.0.2478, Mac OS version: 15, Visual Studio for Mac: 2019
My AppDelegate will be like this,
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.SetFlags("CollectionView_Experimental");
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App());
return base.FinishedLaunching(app, options);
}
}
Here my AppDelegate is inherited by Xamarin.Forms.Platform.iOS.FormsApplicationDelegate instead of UIApplicationDelegate. Due to this, the value for UIApplication.SharedApplication.KeyWindow.RootViewController is NULL.
I tried to initialize an empty view controller during the app initialization, My AppDelegate will be like below ... ...
UIWindow window;
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.SetFlags("CollectionView_Experimental");
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App());
window = new UIWindow(UIScreen.MainScreen.Bounds);
window.RootViewController = new UIViewController();
window.MakeKeyAndVisible();
return base.FinishedLaunching(app, options);
}
But still the payment screen loads outside the app.
I also added a view controller in the dependency injection class in iOS project where I required to call the payment gateway, as follows
public void PaymentRequest(PaymentData paymentData)
{
Payment payment = new Payment(); // From payment SDK
payment.RefNo = paymentData.ReferenceNumber;
…
…
PayObject payObj = new PayObject(); // From payment SDK
…
…
UIViewController responseVC = new UIViewController();
UIView responseView = new UIView();
responseView.Frame = UIScreen.MainScreen.Bounds;
responseView = payObj.Checkout(payment);
responseVC.View = responseView;
UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(responseVC, true, null);
}
With this too, payment screen loads outside the app. PresentViewController loads the view modally as per the documentation. We have to push a view controller into UINavigationController in iOS under native method. But here as we know that Xamarin.Forms dynamically handle those things. So, I don't know how to access the iOS root view controller in order to load the payment screen inside the iOS app.