RadCollectionView Causing Crashes on iOS Devices

1 Answer 175 Views
CollectionView
Neil N
Top achievements
Rank 2
Iron
Iron
Veteran
Neil N asked on 08 Aug 2024, 07:27 PM

Added a RadCollectionView to an app and it's causing crashes on iOS devices (but not the simulator) whenever data is loading or finished loading.  Near as I can tell, the crash is occurring because of XAML binding failures.  I've attached a sample project which shows the failures (you might have to scroll the collectionview to see them). The data still appears, though.

The actual app has a retrieve button on the screen that the user taps after entering some retrieval arguments.  I can see data being populated in the RadCollectionView followed by an immediate crash on the physical device.

 

1 Answer, 1 is accepted

Sort by
0
Lance | Senior Manager Technical Support
Telerik team
answered on 08 Aug 2024, 08:14 PM

Hello Neil,

Thank for sharing the reproducible, it was very useful in getting hands-on with the issue. Let me get right into it.

1. XAML DataBinding Diagnostics

I know you weren't sure when mentioning this, but I thought I'd take a moment to explain what it is, so it doesn't throw you off in the future.

The XAML DataBinding warning you get are not real errors and are just from the XAML diagnostics output. The reality is that .NET MAUI XAML doesn't have the same level of object connection that you might see in UWP, WinUI or WPF. So it has to make an educated guess by looking at the closest BindingContext available in the XAML file. It is frequently wrong.

If you don't want a warning, you can set an x:DataType to the DataTemplate, like this:

Now, the Bindings inside the DataTemplate understand that the BindingContext is going to be an instance of that type (and not whatever it is throwing a warning for, usually the page view model).

Ultimately, this would not cause a runtime crash, any missing data is just empty.

2. Fix the Crashes

Now, onto looking at the ItemTemplate that is being used in this project, I see a very risky practice... a hard-coded array indexer. This can absolutely lead to a hard crash.

Solution

If you really must index that collection and get the first item, use a converter and return the first item (or null) instead of this risky approach. I suspect this is the reason because you get to a section of the data that does not have a grouped list, therefore the Items collection is empty or null.

In any case, let's prepare a converter that does everything you need. First, we must always validate the assumptions at this point through a couple checks in the converter:

public class FirstItemConverter : IValueConverter
{
    public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
    {
        // First, make sure the converter is being used for the GroupContext
        if (value is GroupContext context)
        {
            // Now, try to get the first item in the GroupContext's Items collection
            var firstOrder = context.Items.FirstOrDefault();

            // If that first item is not null and matches the type you are expecting
            if (firstOrder is CustomerOrder order)
            {
                // Put together and return the entire name
                return $"{order.FirstName} {order.LastName}";
            }
        }

        return "none";
    }

    public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Now, you can use it in the header template as a single line instead:

I've reattached your demo with this approach implemented, here's what it looks like at runtime:

3. iOS Trimming

as a final comment, I thought I'd bring up the possibility that the project is trimming too much and there's some form of type stripping happening. So, make sure that you have the Linker set to Sdk Assemblies Only.

Further Assistance

If you still have trouble in your real project, please consider opening a Technical Support ticket, instead of a forum post, so we can work with you more quickly and directly. Although we monitor and respond to forums posts as earnestly as we can, support tickets always take precedence and it may take a few days to handle forums.

Regards,
Lance | Senior Manager Technical Support
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Neil N
Top achievements
Rank 2
Iron
Iron
Veteran
commented on 08 Aug 2024, 09:01 PM

Hi Lance. How can a section of the data not have a grouped list?  I need to understand this better as the real project has eight properties (strings, dates, numbers) appearing in the header in a grid so eight converters will be needed, slowing down an already not-fast process.  Basically, we need to show lists within a list (like the sample project), allowing the user to tap an item in the main list (the group headers) or the nested list (the collection items).  Nested list or collection view controls would've been perfect (and suited the data structure a lot better) but both Microsoft and Telerik say, "don't do that!".

I have RayGun crash monitoring in the app which reports on unhandled exceptions (like assigning nulls) but I'm getting nothing for this crash..

I will look at iOS trimming.

Lance | Senior Manager Technical Support
Telerik team
commented on 08 Aug 2024, 09:14 PM

It's not necessarily am empty group. The easiest way to see what is happening is to place a breakpoint at the top of your converter and see all the times it is hit. Observe the value during each loop and you'll see that it might not always be a GroupContext.

As to your list-within-a-list problem, yes never embed two UI virtualized controls together... this is the guidance, not that there's a nested list. You can instead use a non-virtualized ItemsControl for that inner list, and the UI virtualized parent (like CollectionView). For example, consider this control for the inner list https://docs.telerik.com/devtools/maui/controls/itemscontrol/overview 

If grouping is not truly the UX you're after then you might want to consider a TreeView. This is specifically designed for the list-in-a-list scenario, see https://docs.telerik.com/devtools/maui/controls/treeview/overview 

Neil N
Top achievements
Rank 2
Iron
Iron
Veteran
commented on 08 Aug 2024, 09:36 PM

Thanks again. I'm going to open a ticket with a screenshot of the real UI and data class and see what you recommend.  I did look at the treeview but it didn't seem flexible enough.
Tags
CollectionView
Asked by
Neil N
Top achievements
Rank 2
Iron
Iron
Veteran
Answers by
Lance | Senior Manager Technical Support
Telerik team
Share this question
or