CommunityToolkit / Maui

The .NET MAUI Community Toolkit is a community-created library that contains .NET MAUI Extensions, Advanced UI/UX Controls, and Behaviors to help make your life as a .NET MAUI developer easier
https://learn.microsoft.com/dotnet/communitytoolkit/maui
MIT License
2.26k stars 397 forks source link

[BUG][iOS] MediaElement crashes at startup when used in ContentPage as App.MainPage #959

Closed TimLariviere closed 1 year ago

TimLariviere commented 1 year ago

Is there an existing issue for this?

Did you read the "Reporting a bug" section on Contributing file?

Current Behavior

When adding a MediaElement to a ContentPage used as the MainPage of Application (no Shell), the app crashes on iOS at startup because of an InvalidOperationException. Android seems fine.

System.InvalidOperationException: ViewController can't be null.
   at CommunityToolkit.Maui.Core.Views.MauiMediaElement..ctor(AVPlayerViewController playerViewController)
   at CommunityToolkit.Maui.Core.Handlers.MediaElementHandler.CreatePlatformView()

I tracked it down to WindowStateManager.Default.GetCurrentUIViewController() returning null. https://github.com/CommunityToolkit/Maui/blob/e6f9e9180e8d6141c73752caaf19597b32c91492/src/CommunityToolkit.Maui.MediaElement/Views/MauiMediaElement.macios.cs#L24

This is not the case when using Shell, so I believe the creation of the MediaElement is somehow delayed when using Shell, giving time for WindowStateManager to be initialized, but not when using ContentPage directly.

Expected Behavior

The app should run fine on iOS, just like it works already on Android.

Steps To Reproduce

  1. Create a new Maui project (from the official template)
  2. Add .UseMauiCommunityToolkitMediaElement() to the MauiApp builder
  3. Replace the default App with this code
public class App : Application
{
    public App()
    {
        MainPage = new ContentPage
        {
            Content = new MediaElement
            {
                Source = MediaSource.FromUri("https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"),
                HeightRequest = 300,
                WidthRequest = 400,
                ShouldAutoPlay = true
            }
        };
    }
}
  1. Run the application on iOS

A workaround is available in the project below

Link to public reproduction project repository

https://github.com/TimLariviere/CommunityToolkit-Maui-MediaElement-Crash

Environment

- CommunityToolkit.Maui.MediaElement: 1.0.1
- OS: macOS Ventura 13.1 (22C65)
- .NET MAUI: 7.0.59

Anything else?

No response

derekpapworth commented 1 year ago

@TimLariviere - I was just about to post the same issue! :) It appears to be, as you say, iOS only related and I took the standard template project (with shell) and added MediaElement to MainPage and all works fine but I then replace the line in app "MainPage = new AppShell()" with "MainPage = new MainPage()" (or with NavigationPage) the expection occurs.

derekpapworth commented 1 year ago

p.s. Not sure that workaround works if the MediaElement is in XAML?

bijington commented 1 year ago

I wonder if we need to implement something similar to #934 where we check whether IsPlatformEnabled before trying to take action.

derekpapworth commented 1 year ago

This seems to be actually a bigger problem than first thought as having tried numerous scenarios it appears you can't use the MediaElement outside of a Shell based app (iOS at least) as trying to use it anywhere in a NavigationPage based app you get exceptions either on PushAsync to a page with a MediaElement or when PopAsync which cause issues with the page popped to. I suspect that there's an internal reliance or reference to Shell somewhere (perhaps main window?) and that it's just not possible to use it in a non-Shell app .. does anyone know if this is the case?

jfversluis commented 1 year ago

Closing this in favor of #985