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.15k stars 355 forks source link

[BUG] CommunityToolkit.Maui.Core.Platform.StatusBar causes app to fail on iOS Testflight #1374

Open needledrag opened 10 months ago

needledrag commented 10 months ago

Is there an existing issue for this?

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

Current Behavior

I've tested my .net Maui app in Android and iOS, debug, release and on device, Android now in Closed Testing on Google Play. Just uploaded to App Connect and testing on a device using TestFlight.

On both devices I get the error in appcenter as the app loads the splash screen and goes blank:

  "exception": {
    "type": "System.InvalidOperationException",
    "message": "RootViewController cannot be null",
    "stackTrace": "   at CommunityToolkit.Maui.Core.Platform.StatusBar.UpdateStatusBarAppearance(UIWindow window)\n   at CommunityToolkit.Maui.Core.Platform.StatusBar.PlatformSetColor(Color color)\n   at CommunityToolkit.Maui.Core.Platform.StatusBar.SetColor(Color color)\n   at CommunityToolkit.Maui.Behaviors.StatusBarBehavior.OnPropertyChanged(String propertyName)\n   at Microsoft.Maui.Controls.BindableObject.SetValueActual(BindableProperty property, BindablePropertyContext context, Object value, Boolean currentlyApplying, SetValueFlags attributes, Boolean silent)\n   at Microsoft.Maui.Controls.BindableObject.SetValueCore(BindableProperty property, Object value, SetValueFlags attributes, SetValuePrivateFlags privateAttributes)\n   at Microsoft.Maui.Controls.BindableObject.SetValue(BindableProperty property, Object value, Boolean fromStyle, Boolean checkAccess)\n   at Microsoft.Maui.Controls.BindableObject.SetValue(BindableProperty property, Object value)\n   at CommunityToolkit.Maui.Behaviors.StatusBarBehavior.set_StatusBarColor(Color value)\n   at InkflowApp.Views.Base.PageBase.InitializeComponent()\n   at InkflowApp.Views.Base.PageBase..ctor()\n   at InkflowApp.Views.Base.ViewBase`1[[InkflowApp.ViewModels.Home.IntroViewModel, InkflowApp, Version=1.1.0.0, Culture=neutral, PublicKeyToken=null]]..ctor()\n   at InkflowApp.Views.Home.IntroView..ctor()\n   at InkflowApp.ViewModels.Home.InitViewModel.OnNavigatedTo(Object parameters)",
    "wrapperSdkName": "appcenter.xamarin"
  }

I have the following code in my PageBase which every page is based off <Page.Behaviors> <mct:StatusBarBehavior StatusBarColor="{StaticResource AppPrimaryBGColour}" StatusBarStyle="DarkContent"/> </Page.Behaviors>

I've read in the MS docs that this should be set in Behaviors as putting it in the class constructor or OnNavigatedTo (or OnAppearing) can cause problems if platform specific components haven't been initialised.

As I mentioned, this works in debug, on device and in release mode for both Android an iOS and published in Android, it just seems to be on publishing the iOS app this occurs every time.

Expected Behavior

Statusbar colour is set and app proceeds as expected to load the page.

Steps To Reproduce

As everything works in dev and release you'd need to depoly an app to the App Connect and test in Test Flight as this seems to be the only place I can reproduce it.

Link to public reproduction project repository

Unable to reproduce except in Test Flight

Environment

- .NET MAUI CommunityToolkit: 5.3
- OS: iOS 14.4.2
- .NET MAUI: 7

Anything else?

Any help or known workaround would be greatly appreciated.

ghost commented 10 months ago

Hi @needledrag. We have added the "needs reproduction" label to this issue, which indicates that we cannot take further action. This issue will be closed automatically in 5 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

pictos commented 10 months ago

@needledrag can you reproduce this using release mode, with the same configurations that you use to build the test flight app?

needledrag commented 10 months ago

Unfortunately not, it all works in release mode and even on a connected device. It's only when I install a published build from App Connect that this occurs. I've even tried to install on the same device that it worked on when testing the release mode and it fails. If all else fails I guess I could change the info.plist and set the Status bar style there directly?

pictos commented 10 months ago

@needledrag is your app using TabPage or Shell?

needledrag commented 10 months ago

Shell

pictos commented 10 months ago

@needledrag for now, you can try to set the value on info.plist, probably it's caused by some issue around the initialization. This was working before?

needledrag commented 10 months ago

It works in all other environments and on an Android published app but this is the first time I've published the iOS app to App Connect.

evgenyKozlov1996 commented 5 months ago

Verified the issue. Visual Studio 2022 v17.8.5 .NET MAUI 8 CommunityToolkit v7.0.1 iOS 17.3 IPhone 13 Pro Max

Steps to reproduce:

P.S.: Maybe this issue is related to using ReactiveUI for MAUI

needledrag commented 5 months ago

I had to remove the toolkit StatusBarBehavior for iOS builds to get around this

bijington commented 5 months ago

Verified the issue.

Visual Studio 2022 v17.8.5

.NET MAUI 8

CommunityToolkit v7.0.1

iOS 17.3

IPhone 13 Pro Max

Steps to reproduce:

  • Build iOS Debug version and deploy it to the real device.

  • App will be opened successfully.

  • Close the app and detach the debugger.

  • Open the app from IPhone. App will show loading screen and crash when trying to open the first page.

P.S.: Maybe this issue is related to using ReactiveUI for MAUI

If you follow the same steps with the sample app do you see the same crash?

canmjp1 commented 3 months ago

I am experiencing the same thing. Has there been a fix for this yet?

AndrewMiller34 commented 2 months ago

Verified the issue. Visual Studio 2022 17.10.0 Preview 2.0 NET MAUI 8 CommunityToolkit v7.0.1 iOS 17.4.1 iPhone 12

Steps to reproduce:

When I try to add the behavior in the xaml.cs instead, it actually gives me a warning saying it's unsupported for iOS and Windows; but the docs are not agreeing.

I've included the required info.plist key according to the docs: `

UIViewControllerBasedStatusBarAppearance

`

Works fine for Android and while debugging. But whether it's a Release or Debug build it will not run on the physical iPhone without the debugger attached.

Blinchik91 commented 1 month ago

same here, still not fixed or working with .NET 8 and SimpleToolkit.SimpleShell in my case. If I remove the StatusbarBehavior it works like mentioned

I had to remove the toolkit StatusBarBehavior for iOS builds to get around this

thedee commented 1 month ago

I am also getting the error doing this on the constructor on a ContentPage:

this.Behaviors.Add(new StatusBarBehavior
{
    StatusBarColor = ColorResources.HeaderColor
});

Works fine when debugging but it errors when doing an Ad-Hoc build and installing it through iTunes on the device.

canmjp1 commented 1 month ago

My workaround for this was adding this to the App OnStart()

CommunityToolkit.Maui.Core.Platform.StatusBar.SetColor(Color.FromArgb("#1190ca")); CommunityToolkit.Maui.Core.Platform.StatusBar.SetStyle(CommunityToolkit.Maui.Core.StatusBarStyle.LightContent);

eddieyanez commented 5 days ago

I've had this issue when using the behaviour directly on AppShell.xaml rather than on the ContentPage. To fix that, I've applied the behaviour to the pages rather than shell.

lhughey commented 5 days ago

Experiencing this issue ONLY on the first startup page. Pages that are navigated to from that beginning page are working fine. Odd.

AmaluThomas commented 2 days ago

I've had this issue when using the behaviour directly on AppShell.xaml rather than on the ContentPage. To fix that, I've applied the behaviour to the pages rather than shell.

Even in contentpage on release mode it crashes that is in testflight.

Is there any other solution?

AmaluThomas commented 2 days ago

My workaround for this was adding this to the App OnStart()

CommunityToolkit.Maui.Core.Platform.StatusBar.SetColor(Color.FromArgb("#1190ca")); CommunityToolkit.Maui.Core.Platform.StatusBar.SetStyle(CommunityToolkit.Maui.Core.StatusBarStyle.LightContent);

Are you able to upload to testflight without any crash?

AmaluThomas commented 17 hours ago

Fixed the status bar issues and was successfully able to build app:

(https://learn.microsoft.com/en-us/answers/questions/1341985/net-maui-how-to-change-status-bar-and-navigation-b)

mackayn commented 11 hours ago

Noticed this as well in Release mode in iOS, the first page navigation will crash with the attached status bar behavior. Cobbled together this workaround as I only wanted to set the set the color once, it sets the status bar more than once but need something quick that was reliable, This is a MAUI app that doesn't use shell.

    public partial class AppNavigationPage
    {
        private bool _isRendered;

        public AppNavigationPage()
        {
            InitializeComponent();
        }

        protected override void OnHandlerChanged()
        {
            base.OnHandlerChanged();
            RepaintStatusBar();
        }

        protected override void OnAppearing()
        {
            base.OnAppearing();
            RepaintStatusBar();
            _isRendered = true;
        }

        protected override void OnSizeAllocated(double width, double height)
        {
            base.OnSizeAllocated(width, height);
            if (_isRendered)
            {
                RepaintStatusBar();
            }
        }

#if IOS
        private static void UpdateStatusBarAppearance(UIWindow? window)
        {
            var vc = window?.RootViewController ?? WindowStateManager.Default.GetCurrentUIViewController();
            if (vc != null)
            {
                while (vc.PresentedViewController is not null)
                {
                    vc = vc.PresentedViewController;
                }

                vc.SetNeedsStatusBarAppearanceUpdate();
            }
        }
#endif
        private void RepaintStatusBar()
        {
#if IOS
            var statusBarTag = new IntPtr(38482);
            if (GetParentWindow()?.Handler?.PlatformView is UIWindow window)
            {
                var topPadding = window?.SafeAreaInsets.Top ?? 0;

                var statusBar = new UIView(new CoreGraphics.CGRect(0, 0, UIScreen.MainScreen.Bounds.Size.Width, topPadding))
                {
                    BackgroundColor = ResourceHelper.GetNamedResourceColor("NavigationBarBackgroundColor").ToPlatform(),
                    Tag = statusBarTag,
                };

                var statusBarSubViews = window.Subviews.Where(x => x.Tag == statusBarTag).ToList();
                foreach (var statusBarSubView in statusBarSubViews)
                {
                    statusBarSubView.RemoveFromSuperview();
                }

                window.AddSubview(statusBar);

                UpdateStatusBarAppearance(window);
            }
#endif
        }
    }