I have a deep link registered, and where iOS is 13 or greater, although clicking on the link opens the app, the OpenUrlContexts
override does not fire, hence I am unable to filter then navigate, based upon the URL.
This is a Xamarin Forms app, however I've asked the question here in the iOS forum, because it involves the new iOS Version 13+ SceneDelegate with modified AppDelegate.
I've included the following code files:
1. SceneDelegate
2. AppDelegate
3. apple-app-site-association
4. Entitlements.plist
5. Info.plist extract
6. App.xaml.cs
Does anyone know why the OpenUrlContexts method is not being called?
SceneDelegate file
[Register("SceneDelegate")] public class SceneDelegate : UIWindowSceneDelegate { [Export("scene:openURLContexts:")] public override void OpenUrlContexts(UIScene scene, NSSet<UIOpenUrlContext> urlContexts) { Debug.WriteLine("*** URL property =====" + urlContexts.AnyObject.Url); var urlString = urlContexts.AnyObject.Url; if (urlString.Equals("https://REDACTED")) { // Run code } } public override UIWindow Window { get; set; } public override void WillConnect(UIScene scene, UISceneSession session, UISceneConnectionOptions connectionOptions) { var windowScene = scene as UIWindowScene; if (windowScene != null) { Window = new UIWindow(windowScene.CoordinateSpace.Bounds); if (Window != null) { // This just creates a new App instance without creating a new AppDelegate // In iether case I still see issues with navigation events going to the wrong window, // i.e. I tap Add Item in one window, but the new item page launches in another window // Or use the menu to go to the ABout page, and the About page opens in the other window // This is in keeping with what I have seen in reagrds to embedding forms pages into native // projects. In this case, you need to use the platforms navigation APIs, not Xamarin.Forms // navigation APIs var fApp = new App(); try { // Set the scene's RootViewController from the one X.Forms created Window.RootViewController = fApp.MainPage.CreateViewController(); //// This creates the Xamarin.Forms UI with a new app delegate var ad = new AppDelegate(); ad.GetUI(); // //// Set the scene's RootViewController from the one X.Forms created Window.RootViewController = ad.Window.RootViewController; // Set the WindowScene Window.WindowScene = windowScene; } catch(Exception ex) { } } } } }
AppDelegate file
[Register("AppDelegate")] public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate { public UIApplication application; public NSDictionary options; // // This method is invoked when the application has loaded and is ready to run. In this // method you should instantiate the window, load the UI into it and then make the window // visible. // // You have 17 seconds to return from this method, or iOS will terminate your application. // [Export("application:didFinishLaunchingWithOptions:")] public override bool FinishedLaunching(UIApplication app, NSDictionary options) { global::Xamarin.Forms.Forms.Init(); if (UIDevice.CurrentDevice.CheckSystemVersion(13, 0)) { // only used when creating a new app delegate in the scene delegate in order to be able to call // LoadApplication in GetUI method this.application = app; this.options = options; return true; } else { LoadApplication(new App()); return base.FinishedLaunching(app, options); } } // only used when creating a new app delegate in the scene delegate public void GetUI() { LoadApplication(new App()); // This call populates the Window property so it needs to be called after LoadApplication for every scene base.FinishedLaunching(application, options); } }
apple-app-site-association file:
{ "applinks": { "apps": [], "details": [ { "appID": "REDACTED", "paths": [ "/", "/REDACTED/*"] } ] } }
Entitlements.plist file
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.developer.associated-domains</key> <array> <string>applinks:REDACTED</string> </array> </dict> </plist>
Registration of SceneDelegate in info.plist
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <!-- other stuff not shown here --> <key>UIApplicationSceneManifest</key> <dict> <key>UIApplicationSupportsMultipleScenes</key> <true/> <key>UISceneConfigurations</key> <dict> <key>UIWindowSceneSessionRoleApplication</key> <array> <dict> <key>UISceneConfigurationName</key> <string>Default Configuration</string> <key>UISceneDelegateClassName</key> <string>SceneDelegate</string> <key>UISceneStoryboardFile</key> <string>EmptyStoryboard</string> </dict> </array> </dict> </dict> </dict>
Xamarin.Forms App.xaml.cs
public partial class App : Application { public App() { InitializeComponent(); DependencyService.Register<MockDataStore>(); MainPage = new MainPage(); } protected override void OnStart() { } protected override void OnSleep() { } protected override void OnResume() { } protected override void OnAppLinkRequestReceived(Uri uri) { // DOES NOT FIRE EITHER base.OnAppLinkRequestReceived(uri); } }