Tek Mun
Tek Mun

Reputation: 99

Xamarin.Forms for iOS using SceneDelegate.cs

In iOS 13, UIScene is used. Codes in AppDelegate.cs must be moved into SceneDelegate.cs to support multiple windows of the same app in Split View.

For Xamarin.Forms, AppDelegate.cs uses LoadApplication (new App()) to launch an instance of App.cs in the Xamarin.Forms. LoadApplication is found in Xamarin.Forms.Platform.iOS.FormsApplicationDelegate.

What is the equivalent in SceneDelegate.cs to launch an instance of App.cs in the Xamarin.Forms?

Upvotes: 2

Views: 2261

Answers (2)

CVStrydom
CVStrydom

Reputation: 301

It seems this issue has been resolved in MAUI. Just inherit from MauiUISceneDelegate for your SceneDelegate class and the framework will take car of the rest:

[Register("SceneDelegate")]
public class SceneDelegate : MauiUISceneDelegate
{
}

And then in your info.plist file:

<key>UIApplicationSceneManifest</key>
<dict>
    <key>UIApplicationSupportsMultipleScenes</key>
    <true/>
    <key>UISceneConfigurations</key>
    <dict>
        <key>UIWindowSceneSessionRoleApplication</key>
        <array>
            <dict>
                <key>UISceneConfigurationName</key>
                <string>__MAUI_DEFAULT_SCENE_CONFIGURATION__</string>
                <key>UISceneDelegateClassName</key>
                <string>SceneDelegate</string>
            </dict>
        </array>
    </dict>
</dict>

I wish there was an equally clean solution for Xamarin.Forms as we have not migrated our app to MAUI yet.

Hope this helps!

*Update:

Junior Jiang's solution did work for me, but I had to make a few changes to get it to work:

  1. Uncomment the following lines in SceneDelegate.cs:

    //var ad = new AppDelegate();

    //ad.GetUI();

    ...

    //Window.RootViewController = ad.Window.RootViewController;

  2. Then add the following line after the uncommented code in SceneDelegate.cs

    Window.MakeKeyAndVisible();

I made a few additional changes that are not specifically required, but probably a bit better in terms of resource usage, such as rather resolving appDeleggate as follows:

var appDelegate = (AppDelegate)UIApplication.SharedApplication.Delegate;

And instead returning the created Xamarin.Forms app in GetUI method (in AppDelegate) to be used in SceneDelegate, instead of creating another one in SceneDelegate.

One limitation that I did notice is that I could no longer see iOS alert messages, so I used a custom syncfusion popup instead.

Upvotes: 0

Junior Jiang
Junior Jiang

Reputation: 12723

From the app lifecycle of xamrin forms :

  • iOSMain method > AppDelegate > App > ContentPage .
  • AndroidMainActivity > App > ContentPage

We will see that Main method invoke App class before , if need a instance of App from iOS , generally will try as follow :

public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
    global::Xamarin.Forms.Forms.Init();
    LoadApplication(new App(app)); // pass app to Forms 

    return base.FinishedLaunching(app, options);
}

However ,Forms can not using UIKit (error screenshot).

enter image description here

In xamarin forms , there is DependencyService to load navtive method . Therefore, suggest that using DependecyService to call app from iOS native AppDelegate.cs .

About using SceneDelegate.cs in Xamarin Forms , there is no SceneDelegate.cs file in iOS solution now . I will check that whether be possible in Xamarin Forms .

==================================Update==============================

If want to deal with a universal link in AppDelegate.cs , you need to do something in continueUserActivity method as follow :

public override bool ContinueUserActivity(UIApplication application, NSUserActivity userActivity, UIApplicationRestorationHandler completionHandler)
{
   //return base.ContinueUserActivity(application, userActivity, completionHandler);
    if(userActivity.ActivityType == NSUserActivityType.BrowsingWeb)
    {
        NSUrl url = userActivity.WebPageUrl;
        // other code
    }
    return true;
}

==================================Update===============================

Finally , found that it is possible to add SceneDelegate to a Xamarin Forms project. A new Xamarin Forms project does not come with the necessary SceneDelegate.cs or .storyboard files, so these need to be added. After adding these files, the info.plist needs to be updated with the UIApplicationSceneManifest key, which will contain more needed keys.

The additions to info.plist are shown here: https://learn.microsoft.com/en-us/xamarin/ios/platform/ios13/multi-window-ipad#project-configuration (just UIApplicationSceneManifest and everything under)

The two things to note are that:

    1. The sample has issues with navigation working properly when having multiple windows of the app running.
    1. This is not an official sample, as Xamarin.Forms does not currently offer official support for using mutiple Scenes with an iOS application.

The unofficial Xamarin.Forms sample is here:https://www.dropbox.com/s/sdxq5me7vcdmuf9/XamFormsiOSMultiWindow.rar?dl=0

Upvotes: 2

Related Questions