HomeiOS Developmentc# - CollectionView causes crash in Maui App on iOS solely

c# – CollectionView causes crash in Maui App on iOS solely


The problem

Here is my state of affairs : I’ve a web page in my Maui software with a CollectionView certain to an ObservableCollection. I dynamically add at a number of factors in my app gadgets to this Assortment via a customized WeakReferenceMessenger.
Particularly, I’ve a button in the identical web page which triggers a number of message additions to the gathering.

Right here comes my problem : after I press this button on an android atmosphere, every little thing works simply advantageous, I see my messages added to the gathering with none downside. However after I take a look at it on iOS, both on an emulator or on a bodily machine, the applying crashes and sends me the next exception :

Exception

Goal-C exception thrown.  Identify: NSInternalInconsistencyException Motive: request for index path for international index 12 when there are solely 12 gadgets within the assortment view
Native stack hint:
    0   CoreFoundation                      0x0000000197c87228 7821F73C-378B-3A10-BE90-EF526B7DBA93 + 1155624
    1   libobjc.A.dylib                     0x0000000195121abc objc_exception_throw + 88
    2   Basis                          0x0000000196f85670 34DE055D-8683-380A-9198-C3347211D13D + 7988848
    3   UIKitCore                           0x000000019a790ff8 96636F64-106F-30C8-A780-82DCEBB0F443 + 3362808
    4   UIKitCore                           0x000000019a9363cc 96636F64-106F-30C8-A780-82DCEBB0F443 + 5088204
    5   UIKitCore                           0x000000019a9362d4 96636F64-106F-30C8-A780-82DCEBB0F443 + 5087956
    6   UIKitCore                           0x000000019a9688a0 96636F64-106F-30C8-A780-82DCEBB0F443 + 5294240
    7   UIKitCore                           0x000000019a9684ec 96636F64-106F-30C8-A780-82DCEBB0F443 + 5293292
    8   UIKitCore                           0x000000019a4912b4 96636F64-106F-30C8-A780-82DCEBB0F443 + 217780
    9   UIKitCore                           0x000000019a75eec8 96636F64-106F-30C8-A780-82DCEBB0F443 + 3157704
    10  UIKitCore                           0x000000019a75d06c 96636F64-106F-30C8-A780-82DCEBB0F443 + 3149932
    11  UIKitCore                           0x000000019aa1bcec 96636F64-106F-30C8-A780-82DCEBB0F443 + 6028524
    12  UIKitCore                           0x000000019aa1b9d0 96636F64-106F-30C8-A780-82DCEBB0F443 + 6027728
    13  UBScoring                           0x0000000104977648 xamarin_dyn_objc_msgSendSuper + 164
    14  UBScoring                           0x0000000104b332b0 do_icall + 200
    15  UBScoring                           0x0000000104b318f4 do_icall_wrapper + 348
    16  UBScoring                           0x0000000104b24e28 mono_interp_exec_method + 2580
    17  UBScoring                           0x0000000104b221dc interp_entry_from_trampoline + 656
    18  UBScoring                           0x0000000104949970 native_to_interp_trampoline + 112
    19  UBScoring                           0x0000000104b8d458 -[__MonoMac_NSAsyncActionDispatcher xamarinApplySelector] + 96
    20  Basis                          0x000000019685d574 34DE055D-8683-380A-9198-C3347211D13D + 484724
    21  CoreFoundation                      0x0000000197b7ca8c 7821F73C-378B-3A10-BE90-EF526B7DBA93 + 64140
    22  CoreFoundation                      0x0000000197b7c8a4 7821F73C-378B-3A10-BE90-EF526B7DBA93 + 63652
    23  CoreFoundation                      0x0000000197b7c700 7821F73C-378B-3A10-BE90-EF526B7DBA93 + 63232
    24  CoreFoundation                      0x0000000197b7d080 7821F73C-378B-3A10-BE90-EF526B7DBA93 + 65664
    25  CoreFoundation                      0x0000000197b7ec3c CFRunLoopRunSpecific + 572
    26  GraphicsServices                    0x00000001e4d5d454 GSEventRunModal + 168
    27  UIKitCore                           0x000000019a591274 96636F64-106F-30C8-A780-82DCEBB0F443 + 1266292
    28  UIKitCore                           0x000000019a55ca28 UIApplicationMain + 336
    29  UBScoring                           0x00000001049601f4 xamarin_UIApplicationMain + 60
    30  UBScoring                           0x0000000104b33324 do_icall + 316
    31  UBScoring                           0x0000000104b318f4 do_icall_wrapper + 348
    32  UBScoring                           0x0000000104b24e28 mono_interp_exec_method + 2580
    33  UBScoring                           0x0000000104b229e0 interp_runtime_invoke + 236
    34  UBScoring                           0x0000000104af11a8 mono_jit_runtime_invoke + 1244
    35  UBScoring                           0x0000000104a9891c mono_runtime_invoke_checked + 148
    36  UBScoring                           0x0000000104a9e820 mono_runtime_exec_main_checked + 116
    37  UBScoring                           0x0000000104af7be4 mono_jit_exec + 356
    38  UBScoring                           0x00000001049760ac xamarin_main + 2032
    39  UBScoring                           0x0000000104b64634 most important + 64
    40  dyld                                0x00000001bea53f08 86D5253D-4FD1-36F3-B4AB-25982C90CBF4 + 257800

Code

The CollectionView within the web page’s structure

 
     
         
             
                 
                     
             
         
     
 

The code when the ViewModel is reacting to the message

[ObservableProperty] public partial ObservableRangeCollection SessionLog { get; set; } = new();

public void RegisterLogging()
{
    WeakReferenceMessenger.Default.Register(this, (r, m) => MainThread.BeginInvokeOnMainThread(() =>
    {
        SessionLog.Add($"{DateTime.Now:HH:mm:ss} | {m.Worth}");
    }));
}
public class UserLogMessage(string message) : ValueChangedMessage(message)
{
    public UserLogMessage(string CompetitionName, LoadCompetitionStatus standing) : this(StatusToMessage(CompetitionName, standing)) { }


    personal static string StatusToMessage(string CompetitionName, LoadCompetitionStatus standing)
    {
        return $"{CompetitionName} - {standing}";
    }
}

The operate referred to as when clicking on the Button inflicting the crash

[RelayCommand]
public void ReloadCompetitionInfo()
{
    MainThread.BeginInvokeOnMainThread(async () =>
    {
        IsBusy = true;
        IsSyncing = true;
        count_i = 0;
        await AppCore.Occasion.ReloadCompetitionInfo();
        AppData.Occasion.WriteLogFile("Competitors reloaded from server.");
        CanBroadcast = AppData.Occasion.AppDataCompetitions.LoggedOnUser.CanBroadcast;
        Broadcasting = AppData.Occasion.AppDataSettings.Broadcast;
        IsSyncing = false;
        IsBusy = false;
    });
}

The LoadCompetitionFromApiResponse, referred to as from inside ReloadCompetitionInfo

personal static UBModels.Competitors LoadCompetitionFromApiResponse(UBApiModels.CompetitionData CompetitionDataFromUBAPI, bool IsMatchDirector)
{
    UBModels.Competitors AppCompetition = new();

    WeakReferenceMessenger.Default.Ship(new UserLogMessage(CompetitionName: AppCompetition.Identify, LoadCompetitionStatus.Init));

    // Each Load[...]FromUBAPI methodology ends with a brand new UserLogMessage being despatched

    if (CompetitionDataFromUBAPI.squads.Depend != 0) LoadSquadsFromApiResponse(AppCompetition, CompetitionDataFromUBAPI);
    if (CompetitionDataFromUBAPI.groups.Depend != 0) LoadTeamsFromApiResponse(AppCompetition, CompetitionDataFromUBAPI);
    if (CompetitionDataFromUBAPI.opponents.Depend != 0) LoadCompetitorsFromApiResponse(AppCompetition, CompetitionDataFromUBAPI);
    
    if (CompetitionDataFromUBAPI.attracts.Depend != 0) LoadBracketsFromApiResponse(AppCompetition, CompetitionDataFromUBAPI);
    if (CompetitionDataFromUBAPI.rounds.Depend != 0) LoadRoundsFromApiResponse(AppCompetition, CompetitionDataFromUBAPI);
    if (CompetitionDataFromUBAPI.targets.Depend != 0) LoadTargetsFromApiResponse(AppCompetition, CompetitionDataFromUBAPI);
    
    if (CompetitionDataFromUBAPI.contest_results.Depend != 0) LoadResultsFromApiResponse(AppCompetition, CompetitionDataFromUBAPI);
    if (CompetitionDataFromUBAPI.duels.Depend != 0) LoadDuelsFromApiResponse(AppCompetition, CompetitionDataFromUBAPI);

    WeakReferenceMessenger.Default.Ship(new UserLogMessage(AppCompetition.Identify, LoadCompetitionStatus.CompetitionLoaded));

    return AppCompetition;
}

Workaround

I truly discovered a possible workaround : each time I ship a message via the messenger in ReloadCompetitionInfo , I added a name to a brand new methodology WaitIOS earlier than. Nonetheless it feels prefer it’s not the right strategy, and that I should not want so as to add a delay to each single message in right here.

personal static void WaitiOS(int delayMs = 1000)
{
#if IOS
    Activity.Delay(delayMs).Wait();
#endif
}

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments