maui icon indicating copy to clipboard operation
maui copied to clipboard

Better API for Native Embedding and MauiContext creation for it

Open Redth opened this issue 4 years ago • 8 comments

This is partially helped by #5218

Future design notes:

Make use of the extensions in MauiContextExtensions to capture and store the platform app and window for use in other places:

  • MakeApplicationScope
  • MakeWindowScope

For example, it could be possible to make a new extension method for MauiApp:

// this can be stored in a static location
var mauiEmbeddedApp = MauiApp
    .CreateBuilder()
    .UseMauiEmbedded()
    .Build()
    .ToEmbedded(); // new method

// this runs on each window or activity
var platformWindow = ... // Window on iOS, this on Android, this on WinUI
var mauiContext = mauiEmbeddedApp.CreateWindowContext(platformWindow);

// back to normal things
var page = new ContentPage {
    new Label { Text = "w00t!" }
};
var platformView = page.ToPlatform(mauiContext);

The new extension method just returns a wrapped MauiApp that holds the context:

static class EmbeddedExtensions {
    public static MauiEmbeddedApp ToEmbedded(this MauiApp mauiApp) {
        var platformApp = UIApplication.SharedApplication;
        var platformApp = Android.App.Application.Context as Android.App.Application;
        var platformApp = UI.Xaml.Application.Current;

        // create scopes to make sure the platform app is added (ie: UIAppDelegate is in the services)
        var mauiContext = new MauiContext(mauiApp.Services, platformApp);
        var appContext = mauiContext.MakeAppScope(platformApp);

        var embedded = new MauiEmbeddedApp(mauiApp, appContext);
        return embedded;
    }

    public static MauiContext CreateWindowContext(this MauiEmbeddedApp mauiApp, PlatformWindow platformWindow) {
        // create scopes to make sure the platform window is added (ie: UIWindow is in the services)
        var windowContext = mauiApp.MauiApplicationContext.MakeWindowScope(platformWindow);
        return windowContext;
    }
}

class MauiEmbeddedApp : IDisposable {
    internal MauiEmbeddedApp(MauiApp mauiApp, MauiContext appContext);
    public MauiApp { get; }
    public MauiContext MauiApplicationContext { get; }
    public IServiceProvider Services => MauiApp.Services;
    public IConfiguration Configuration => MauiApp.Configuration;
}

Related Issues:

  • [x] https://github.com/dotnet/maui/issues/17948
  • [ ] https://github.com/dotnet/maui/issues/18366
  • [ ] https://github.com/dotnet/maui/issues/18336
  • [ ] https://github.com/dotnet/maui/issues/11856
  • [ ] https://github.com/dotnet/maui/issues/11283
  • [ ] https://github.com/dotnet/maui/issues/9606
  • [ ] https://github.com/dotnet/maui/issues/7549
  • [x] https://github.com/dotnet/maui/issues/19340

Related PRs:

  • [ ] https://github.com/dotnet/maui/pull/19314

Redth avatar Jul 16 '21 16:07 Redth

Hello,

Assuming this issue is about embedding MAUI Pages in native Xamarin.iOS / Xamarin.Android applications then maybe it's worth having a look at this old Xamarin.Forms bug https://github.com/xamarin/Xamarin.Forms/issues/2396 as it had to do with how Android recreates the fragment when the activity is recreated (e.g. after a configuration change), to make sure that it won't reproduce in MAUI.

Regards, Cosmin

cosminstirbu avatar Jul 21 '21 14:07 cosminstirbu

I have a sample repo here showing embedding with multiple windows: https://github.com/mattleibow/EmbeddedMauiApps

mattleibow avatar Dec 11 '23 18:12 mattleibow

We have a large enterprise mobile application available to internal users, business partners, and customers that we are attempting to port to .NET7 and MAUI from Xamarin iOS\Xamarin Android and Xamarin Forms.

Our existing Xamarin approach is using embedded Xamarin Forms and was working very well. We have invested quite a bit of time building up various controls, styles, services, etc. to fairly seamlessly integrate between Xamarin Native and Xamarin Forms.

The attempt to migrate to an embedded MAUI use case has been disappointing and very painful. We tried moving to .NET8 once that was released to see if any issues were resolved but the regression (17948) blocked that and we're back on .NET 7.

I've commented on or filed a number of bugs that may or may not be resolved by the work proposed here. I'm sure we were not the only ones using embedded Xamarin Forms. With the end of support for Xamarin, we don't have a choice but to go to MAUI and we do not have the option at this time to convert our Xamarin Native apps to "pure" MAUI. Please consider prioritizing this open issue (and any related work) to provide a first class experience for embedded MAUI use cases.

Issues we're running into:

  • https://github.com/dotnet/maui/issues/19846
  • https://github.com/dotnet/maui/issues/19845
  • https://github.com/dotnet/maui/issues/19843
  • https://github.com/dotnet/maui/issues/11281

nau-dwb avatar Jan 16 '24 21:01 nau-dwb

I am in a very similar situation to @nau-dwb - the Blueye App is a large iOS and Android app, with a mix of Xamarin.iOS/Xamarin.Android and Xamarin.Forms embedding.

The development of the app started before Xamarin.Forms were released, and we gradually moved towards Xamarin.Forms by using embedding and building new functionality in Xamarin.Forms. Today, I would guess the app is ~60% Xamarin.Forms and 40% in Xamarin.iOS/Xamarin.Android.

Our goal is to move more towards Xamarin gradually.Forms as prep-work for MAUI migration, but I don't think there will be any way around some form of embedding.

I can share more details, examples, and screenshots of the architecture if it can help push the priority of this functionality/issue.

follesoe avatar Jan 17 '24 06:01 follesoe

It would be beneficial to include guidelines on setting up window and app contexts, and to make this API public somehow(maybe another package for embedding scenario which gives more API, idk). The reason being, creating window/application context scopes seems to enable hot reload functionality even in embedded scenarios, and it appears to support DynamicResource in embedding contexts (though I could be mistaken about what bare minimum is needed for HotReload exactly, but it does seem to enough to make it work in my experience).

Currently, our application is transitioning to MAUI but still relies on native activities/view controllers, alongside MvvmCross (we're planning to shift away from MvvmCross once we've implemented most of the views). We are in the process of rewriting our existing views using XAML and ContentPages.

I've set up IPlatformApplication and created application and window contexts (a single context on iOS and one per activity on Android), enabling HotReload. However, this required invoking some APIs through reflection and modifying WindowHandler.MapContent to be non-operative.

This approach has significantly expedited our migration, facilitating both HotReload and unload/load events. I believe making these details and functionalities publicly accessible and well-documented would greatly assist others who are considering migrating to MAUI from pure .NET iOS/Android applications. I am still a little bit afraid to include this HotReload/'window setting' code in RELEASE.

@nau-dwb, if you are interested, I can make some kind of article/guide on what I have done.

artemvalieiev avatar Jan 18 '24 19:01 artemvalieiev

@artemvalieiev Sure, if you have the time I'd be interested to see the approach you took. Like you, I'm not sure we'd be comfortable including it in an actual release, but it might be an option to keep us moving and workaround some of the other issues we're running into.

nau-dwb avatar Jan 19 '24 14:01 nau-dwb

I just want to bump this one. We are still holding off from our MAUI migration due to all the open issues around MAUI embedding. It would be great to get some feedback on priorities for this feature set and where it sits on the MAUI roadmap.

follesoe avatar Apr 03 '24 08:04 follesoe

Same as @follesoe, we have to pause our work until this is resolved. I only hope that we can limp along with Xamarin and the door isn't shut by Apple before embedding works reliably. The end of support date for Xamarin really should be extended.

pnumainville avatar Apr 17 '24 21:04 pnumainville

https://github.com/dotnet/maui/issues/19843 https://github.com/dotnet/maui/issues/1718 https://github.com/dotnet/maui/issues/19845 https://github.com/dotnet/maui/issues/19846 https://github.com/dotnet/maui/issues/11281 https://github.com/dotnet/maui/issues/20016 https://github.com/dotnet/maui/issues/19959 https://github.com/dotnet/maui/issues/18366 https://github.com/dotnet/maui/issues/11856 https://github.com/dotnet/maui/issues/11283 https://github.com/dotnet/maui/issues/9606 https://github.com/dotnet/maui/issues/7549

PureWeen avatar Jun 05 '24 14:06 PureWeen

@PureWeen if you don't mind me asking why was completed ? it was multiple open linked tasks and issues.

nll avatar Jul 31 '24 17:07 nll