Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x:Array as resource with key crashes app on device launch #9422

Closed
davidortinau opened this issue Aug 14, 2022 · 18 comments · Fixed by #14546
Closed

x:Array as resource with key crashes app on device launch #9422

davidortinau opened this issue Aug 14, 2022 · 18 comments · Fixed by #14546
Assignees
Labels
area-xaml XAML, CSS, Triggers, Behaviors fixed-in-8.0.0-preview.4.8333 Look for this fix in 8.0.0-preview.4.8333! p/1 Work that is important, and has been scheduled for release in this or an upcoming sprint partner/cat 😻 this is an issue that impacts one of our partners or a customer our advisory team is engaged with platform/iOS 🍎 t/bug Something isn't working

Comments

@davidortinau
Copy link
Contributor

Description

This works in the iOS simulator and on desktop. The goal is to have an array of data I can reuse by key.

<?xml version="1.0" encoding="UTF-8" ?>
<?xaml-comp compile="true" ?>
<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">

    <x:Array Type="{x:Type x:String}" x:Key="CategoriesArray">
        <x:String>Noodles</x:String>
        <x:String>Rice</x:String>
        <x:String>Appetizers</x:String>
        <x:String>Desserts</x:String>
        <x:String>Beverages</x:String>
    </x:Array>

</ResourceDictionary>

This initially was in the Styles.xaml which I split apart for troubleshooting and used merged dictionaries.

That doesn't work on an iOS device. I get an error about the type converter failing.

The below however does work on the ContentPages:

<BindableLayout.ItemsSource>
    <x:Array Type="{x:Type x:String}" >
        <x:String>Noodles</x:String>
        <x:String>Rice</x:String>
        <x:String>Appetizers</x:String>
        <x:String>Desserts</x:String>
        <x:String>Beverages</x:String>
    </x:Array>
</BindableLayout.ItemsSource>

Steps to Reproduce

Add an array with key to your styles, bind to a BindableLayout, and then run on an iOS device.

Version with bug

6.0.486 (current)

Last version that worked well

Unknown/Other

Affected platforms

iOS

Affected platform versions

iOS 15

Did you find any workaround?

don't use a resource

Relevant log output

No response

@davidortinau davidortinau added the t/bug Something isn't working label Aug 14, 2022
@jfversluis jfversluis added area-xaml XAML, CSS, Triggers, Behaviors platform/iOS 🍎 labels Aug 15, 2022
@jfversluis jfversluis added this to the Backlog milestone Aug 15, 2022
@ghost
Copy link

ghost commented Aug 15, 2022

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

@AlexanderEgorov
Copy link

maui-ios 7.0.52/7.0.100 SDK 7.0.100
maui-android 7.0.52/7.0.100 SDK 7.0.100

Related issues:

        string GetXaml(string resource, string content) {
            return $@"
<ContentPage xmlns=""http://schemas.microsoft.com/dotnet/2021/maui"" xmlns:x=""http://schemas.microsoft.com/winfx/2009/xaml"">
    <ContentPage.Resources>
        {resource}
    </ContentPage.Resources>
    {content}
</ContentPage>";
        }

        //Throws a XamlParseException on real device (iOS and Android) when app is build in Release configuration 
        //Works fine in Debug configuration or on simulators.
        [Test]
        public async Task LoadXamlTest1() {
            var xaml = GetXaml(
                @"<x:String x:Key=""text"">TEST</x:String>",
                @"<Button Text=""{StaticResource text}""/>");
            var cp = new ContentPage().LoadFromXaml(xaml);
            var bt = (Button)cp.Content;
            Assert.AreEqual("TEST", bt.Text);
        }

        //Throws a XamlParseException on real device (iOS and Android) when app is build in Release configuration 
        //Works fine in Debug configuration or on simulators.
        [Test]
        public async Task LoadXamlTest2() {
            var xaml = GetXaml(
                @"<x:Double x:Key=""borderWidth"">3</x:Double>",
                @"<Button BorderWidth=""{StaticResource borderWidth}""/>");
            var cp = new ContentPage().LoadFromXaml(xaml);
            var bt = (Button)cp.Content;
            Assert.AreEqual(3, bt.BorderWidth);
        }

        //Throws a XamlParseException on real device (iOS and Android) when app is build in Release configuration 
        //Works fine in Debug configuration or on simulators. 
        [Test]
        public async Task LoadXamlTest3() {
            var xaml = GetXaml(
                @"<x:Int32 x:Key=""borderWidth"">3</x:Int32>",
                @"<Button CornerRadius=""{StaticResource borderWidth}""/>");
            var cp = new ContentPage().LoadFromXaml(xaml);
            var bt = (Button)cp.Content;
            Assert.AreEqual(3, bt.CornerRadius);
        }

         //Works file
        [Test]
        public async Task LoadXamlTest4() {
            var xaml = GetXaml(
                @"<Color x:Key=""borderColor"">#FF0000</Color>",
                @"<Button BorderColor=""{StaticResource borderColor}""/>");
            var cp = new ContentPage().LoadFromXaml(xaml);
            var bt = (Button)cp.Content;
            Assert.AreEqual(Colors.Red, bt.BorderColor);
        }
         //Works file
        [Test]
        public async Task LoadXamlTest5() {
            var xaml = GetXaml(
                @"<Thickness x:Key=""margin"">4</Thickness>",
                @"<Button Margin=""{StaticResource margin}""/>");
            var cp = new ContentPage().LoadFromXaml(xaml);
            var bt = (Button)cp.Content;
            Assert.AreEqual(new Thickness(4), bt.Margin);
        }
         //Works file
        [Test]
        public async Task LoadXamlTest6() {
            var xaml = GetXaml(
                @"<FontAttributes x:Key=""fontAttributes"">Italic</FontAttributes>",
                @"<Button FontAttributes=""{StaticResource fontAttributes}""/>");
            var cp = new ContentPage().LoadFromXaml(xaml);
            var bt = (Button)cp.Content;
            Assert.AreEqual(FontAttributes.Italic, bt.FontAttributes);
        }
         //Works file
        [Test]
        public async Task LoadXamlTest7() {
            var xaml = GetXaml(
                @"<x:Array x:Key=""source"" Type=""{x:Type Color}"">
                    <Color>#FF0000</Color>
                </x:Array>",
                @"<ListView ItemsSource=""{StaticResource source}"" />");
            var cp = new ContentPage().LoadFromXaml(xaml);
            var l = (ListView)cp.Content;
            Assert.AreEqual(1, l.ItemsSource.OfType<object>().Count());
        }

@vhugogarcia
Copy link
Contributor

vhugogarcia commented Jan 19, 2023

Hello friends,

I just wanted to share that this issue is still happening and it forced me to remove any reference to x:Double and x:String on my styles resource dictionary, so I could be able to run the application on DEBUG mode + Link SDK Assemblies only selected on iOS, just to figure out an issue on release mode only was facing. ;)

Visual Studio Community 2022 for Mac
Version 17.4.3 (build 21)
maui-ios 7.0.58/7.0.100 SDK 7.0.100

If you need anything from me =), please let me know I will be happy to share anything you need to reproduce the issue, however our friend @davidortinau I believe he explained it very simple and how to reproduce it.

Thanks for the help with this and anything related with .NET MAUI 👍🏻. Really appreciate it.

@mikeparker104 mikeparker104 added the partner/cat 😻 this is an issue that impacts one of our partners or a customer our advisory team is engaged with label Jan 19, 2023
@samhouts samhouts added the p/1 Work that is important, and has been scheduled for release in this or an upcoming sprint label Jan 24, 2023
@samhouts samhouts modified the milestones: Backlog, .NET 8 Planning Jan 26, 2023
@Nibby
Copy link

Nibby commented Feb 5, 2023

I can also attest that this issue is still happening. On a blank MAUI template project, adding x:String entries to the Styles.xaml resource dictionary causes the app to crash when it is deployed to a device (iOS and Android). Interestingly, it only occurs when <MtouchLink> is set to SdkOnly in the csproj file. If it is set to None, the problem goes away.

This is a serious blocker to a project I am working on.

My workload version are as follows:

Installed Workload Id      Manifest Version       Installation Source
---------------------------------------------------------------------
wasm-tools                 7.0.2/7.0.100          SDK 7.0.100        
macos                      13.1.1007/7.0.100      SDK 7.0.100        
maui-maccatalyst           7.0.59/7.0.100         SDK 7.0.100        
maui-ios                   7.0.59/7.0.100         SDK 7.0.100        
maui-android               7.0.59/7.0.100         SDK 7.0.100        
ios                        16.2.1007/7.0.100      SDK 7.0.100        
maccatalyst                16.2.1007/7.0.100      SDK 7.0.100        
maui                       7.0.59/7.0.100         SDK 7.0.100        
android                    33.0.26/7.0.100        SDK 7.0.100   

Hope this issue can be fixed in the near future.

@Eskissimo
Copy link

Hi,

The issue happens also when we publish Android app with AOT enable.

Regards.

@JonnySKK
Copy link

JonnySKK commented Mar 7, 2023

We are still encountering this issue with both x:String and x:Double in Release mode on Android & iOS

@jonathanpeppers jonathanpeppers self-assigned this Apr 11, 2023
@jonathanpeppers
Copy link
Member

I can repro this in Release mode (but works fine Debug):

image

One thing to note is that compiled .xaml appears to work fine for me. So, you can use XamlCompilation for now, and avoid things like LoadFromXaml("your xaml string")?

@vhugogarcia
Copy link
Contributor

Hello @jonathanpeppers ,

Thanks for looking into this issue.

It is also easy to reproduce it on DEBUG mode. Just enable: Link SDKs frameworks only and try it. 😎👍🏻

If there is anything else I can do to reproduce the issue let me know. I am happy to help 👍🏻🙂

@jonathanpeppers
Copy link
Member

@vhugogarcia is there a reason you're not using compiled XAML?

From my testing, the defaults work:

  • Debug mode works: parsed xaml + no trimming
  • Release mode works: compiled xaml + trimming

The only place you hit this issue is trimming + parsed xaml.

@jonathanpeppers
Copy link
Member

Note that I only tried Android so far, perhaps this fails on iOS with Debug defaults?

jonathanpeppers added a commit to jonathanpeppers/maui that referenced this issue Apr 12, 2023
Fixes: dotnet#9422
Context: https://github.com/dotnet/maui/blob/51df629f946122945cee8f57baed80eb48e45c4e/src/Controls/src/Core/Properties/AssemblyInfo.cs#L79

In `Microsoft.Maui.Core.dll`, the default `x` namespace is defined as:

    [assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2009/xaml", "System", AssemblyName = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]

The problem being that in apps on iOS and Android where
`PublishTrimmed` is `true`, `mscorlib.dll` will get trimmed away and
callsites will use `System.Private.CoreLib.dll` instead.

This is very much related to the issue fixed in 880ce09.

Unfortunately, my fix wasn't sufficient, because the `AssemblyName`
name in this case is the full name:

    AssemblyName = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

To solve the issue, let's also check for `StartsWith("mscorlib,")`.

We *could* add a new `XmlnsDefinition`, but this doesn't feel right:

    [assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2009/xaml", "System", AssemblyName = "System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]

It doesn't make sense for a "private" assembly to appear in XAML
intellisense.

I also moved these tests to a new `XamlTests` class, as it didn't
really make sense to put them with `RadioButton` tests.

Note that these new tests wouldn't fail until we start running device
tests in `Release` mode:

dotnet#14392
@vhugogarcia
Copy link
Contributor

vhugogarcia commented Apr 12, 2023

Note that I only tried Android so far, perhaps this fails on iOS with Debug defaults?

You are partially correct @jonathanpeppers . When you set DEBUG mode and set Link SDK Assemblies only it fails as well for iOS emulators or physical devices.

image

I'm sharing here a repository in case you need it. https://github.com/vhugogarcia/MauiStylesDemo

@jonathanpeppers
Copy link
Member

Link SDK Assemblies only

But you had to turn this on for iOS? It wasn't the default setting?

@vhugogarcia
Copy link
Contributor

vhugogarcia commented Apr 12, 2023

Yes, I had to set Link SDK Assemblies only setting on DEBUG mode, because I faced an issue when the app was in the stores and several clients reported unexpected crash of the app and I was unable to reproduce the issue because when I debug locally simulators or physical devices the Linker is set to NONE, which works fine for development.

However, in order for me to reproduce the issue the customers and users are facing I have to mimic the release mode but with the ability to set breakpoints on VS for macOS.

@jonathanpeppers
Copy link
Member

So, you'd probably want to also enable <MauiXamlCValidateOnly>false</MauiXamlCValidateOnly> if you are testing in this way:

<_MauiXamlCValidateOnly>$(MauiXamlCValidateOnly)</_MauiXamlCValidateOnly>
<_MauiXamlCValidateOnly Condition="'$(Configuration)' != 'Release' AND '$(_MauiForceXamlCForDebug)' != 'True'">True</_MauiXamlCValidateOnly>

@vhugogarcia
Copy link
Contributor

So, you'd probably want to also enable <MauiXamlCValidateOnly>false</MauiXamlCValidateOnly> if you are testing in this way:

<_MauiXamlCValidateOnly>$(MauiXamlCValidateOnly)</_MauiXamlCValidateOnly>
<_MauiXamlCValidateOnly Condition="'$(Configuration)' != 'Release' AND '$(_MauiForceXamlCForDebug)' != 'True'">True</_MauiXamlCValidateOnly>

I tried adding those and they did not work @jonathanpeppers . See screenshot below. Even adding those settings on the .csproj file

image

image

@jonathanpeppers
Copy link
Member

No, you put <MauiXamlCValidateOnly>false</MauiXamlCValidateOnly> in your project.

You can verify by watching an MSBuild log to see if the XamlCTask runs or not.

@jonathanpeppers
Copy link
Member

jonathanpeppers commented Apr 12, 2023

Actually, I'm reading it wrong, it would be <_MauiForceXamlCForDebug>true</_MauiForceXamlCForDebug>.

I'm not a fan of the MSBuild logic here... It might be something I can fix for them.

@vhugogarcia
Copy link
Contributor

Thanks @jonathanpeppers for the feedback. I remember I tried that in the past without luck. However, I tried it again just to double check and this is the result. It worked OK 👍🏻 .

So the results are below (iOS):

Using <_MauiForceXamlCForDebug>true</_MauiForceXamlCForDebug> in the .csproj file

  • DEBUG + Linker None = Error
  • DEBUG + Linker SDK Assemblies Only = OK
  • DEBUG + Linker All = OK

Not using <_MauiForceXamlCForDebug>true</_MauiForceXamlCForDebug> in the .csproj file

  • DEBUG + Linker None = OK
  • DEBUG + Linker SDK Assemblies Only = Error
  • DEBUG + Linker All = Error (Position 9:37. Cannot assign property "Source": Property does not exist, or is not assignable, or mismatching type between value and property)

So, what makes this interesting is why I should add that property in the .csproj file if I'm already declaring this on the Styles.xaml file
image

jonathanpeppers added a commit that referenced this issue Apr 17, 2023
Fixes: #9422
Context: https://github.com/dotnet/maui/blob/51df629f946122945cee8f57baed80eb48e45c4e/src/Controls/src/Core/Properties/AssemblyInfo.cs#L79

In `Microsoft.Maui.Core.dll`, the default `x` namespace is defined as:

    [assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2009/xaml", "System", AssemblyName = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]

The problem being that in apps on iOS and Android where
`PublishTrimmed` is `true`, `mscorlib.dll` will get trimmed away and
callsites will use `System.Private.CoreLib.dll` instead.

This is very much related to the issue fixed in 880ce09.

Unfortunately, my fix wasn't sufficient, because the `AssemblyName`
name in this case is the full name:

    AssemblyName = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

To solve the issue, let's also check for `StartsWith("mscorlib,")`.

We *could* add a new `XmlnsDefinition`, but this doesn't feel right:

    [assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2009/xaml", "System", AssemblyName = "System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]

It doesn't make sense for a "private" assembly to appear in XAML
intellisense.

I also moved these tests to a new `XamlTests` class, as it didn't
really make sense to put them with `RadioButton` tests.

Note that these new tests wouldn't fail until we start running device
tests in `Release` mode:

#14392
@ghost ghost locked as resolved and limited conversation to collaborators May 17, 2023
hartez added a commit that referenced this issue Jun 5, 2023
Fixes: #9422
Context: https://github.com/dotnet/maui/blob/51df629f946122945cee8f57baed80eb48e45c4e/src/Controls/src/Core/Properties/AssemblyInfo.cs#L79

In `Microsoft.Maui.Core.dll`, the default `x` namespace is defined as:

    [assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2009/xaml", "System", AssemblyName = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]

The problem being that in apps on iOS and Android where
`PublishTrimmed` is `true`, `mscorlib.dll` will get trimmed away and
callsites will use `System.Private.CoreLib.dll` instead.

This is very much related to the issue fixed in 880ce09.

Unfortunately, my fix wasn't sufficient, because the `AssemblyName`
name in this case is the full name:

    AssemblyName = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

To solve the issue, let's also check for `StartsWith("mscorlib,")`.

We *could* add a new `XmlnsDefinition`, but this doesn't feel right:

    [assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2009/xaml", "System", AssemblyName = "System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]

It doesn't make sense for a "private" assembly to appear in XAML
intellisense.

I also moved these tests to a new `XamlTests` class, as it didn't
really make sense to put them with `RadioButton` tests.

Note that these new tests wouldn't fail until we start running device
tests in `Release` mode:

#14392
rmarinho pushed a commit that referenced this issue Jun 6, 2023
Fixes: #9422
Context: https://github.com/dotnet/maui/blob/51df629f946122945cee8f57baed80eb48e45c4e/src/Controls/src/Core/Properties/AssemblyInfo.cs#L79

In `Microsoft.Maui.Core.dll`, the default `x` namespace is defined as:

    [assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2009/xaml", "System", AssemblyName = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]

The problem being that in apps on iOS and Android where
`PublishTrimmed` is `true`, `mscorlib.dll` will get trimmed away and
callsites will use `System.Private.CoreLib.dll` instead.

This is very much related to the issue fixed in 880ce09.

Unfortunately, my fix wasn't sufficient, because the `AssemblyName`
name in this case is the full name:

    AssemblyName = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

To solve the issue, let's also check for `StartsWith("mscorlib,")`.

We *could* add a new `XmlnsDefinition`, but this doesn't feel right:

    [assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2009/xaml", "System", AssemblyName = "System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]

It doesn't make sense for a "private" assembly to appear in XAML
intellisense.

I also moved these tests to a new `XamlTests` class, as it didn't
really make sense to put them with `RadioButton` tests.

Note that these new tests wouldn't fail until we start running device
tests in `Release` mode:

#14392
@samhouts samhouts added the fixed-in-8.0.0-preview.4.8333 Look for this fix in 8.0.0-preview.4.8333! label Jun 8, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-xaml XAML, CSS, Triggers, Behaviors fixed-in-8.0.0-preview.4.8333 Look for this fix in 8.0.0-preview.4.8333! p/1 Work that is important, and has been scheduled for release in this or an upcoming sprint partner/cat 😻 this is an issue that impacts one of our partners or a customer our advisory team is engaged with platform/iOS 🍎 t/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants