async-awaitmaui.net-8.0maui-blazormaui-ios

Async calls on .Net-8.0 MAUI Blazor app do not work on iOS platform, works on Android and Windows - OpenAppPackageFileAsync() issue on iOS


Creating an app in .NET (8) MAUI BLAZOR HYBRID

The works initializes on Android, Windows and iOS. However, the data is retrieved and shown on Windows and Android only. the iOS platform doesn't fetch the data. It displays the page without data and doesn't reload it (obviously the data isn't fetched anyway). I placed a breakpoint, it doesn't execute or come to the following line of code:

SharedData.SharedDataBundle = Global.DataBundleCollelction;

The Problem

The observation is that, the async call below is not respected on iOS platform. Windows and Android do wait until the async call is finished and continue with the data though.

Not sure how to fix it, I have tried many way of calling it but async-await Task.Run() or Task.WhenAll() do not seem to be working on iOS.

Startup code

The code in the App.Xaml.cs is like below:

    public partial class App : Application
    {
        [Inject] SharedDataService sharedDataService { get; set; }

        public App()
        {
            InitializeComponent();
            sharedDataService = new SharedDataService();
            
            var tasks = new List<Task>
            {
                Task.Run(async () =>
                {
                    Global.DataBundleCollelction = await sharedDataService.UpdateSharedWeatherData(new List<int> { 1, 2, 4, 25, 26, 91 });
                    SharedData.SharedDataBundle = Global.DataBundleCollelction;
                }),
                Task.Run(async () =>
                {
                    var bundle = Global.DataBundleCollelction;
                    var weatherSettingsService = new WeatherSettingsService(bundle);
                    var weatherSettings = await weatherSettingsService.LoadSettingsAsync();
                })
            };

            Task.WhenAll(tasks).Wait();
            MainPage = new MainPage();
        }
    }

Please guide me what am I missing?

UPDATE:

I am using the following method to read JSON files from /Resources/Raw/MyJson.json (MauiAsset)

public async Task<ObservableCollection<T>> ReadJsonDataAsync<T>(string jsonDataFileName)
{
    ObservableCollection<T>? genericTypeList = new();
    var isExist = await FileSystem.AppPackageFileExistsAsync(jsonDataFileName);
    if (isExist)
    {
        var stream = await FileSystem.Current.OpenAppPackageFileAsync(jsonDataFileName);
        var reader = new StreamReader(stream);
        var contents = await reader.ReadToEndAsync();
        genericTypeList = JsonSerializer.Deserialize<ObservableCollection<T>>(contents);
    }
    return genericTypeList!;
}

Observation/Answer

The above function reads the JSON file as MauiAsset. That file path was given as 'Resources/Raw/MyJsonFile.json' - this path worked fine for Android and Windows but iOS didn't like it.

It now works, the link shared by (@Alexandar May - MSFT) in the comments below, led me to the solution.


Solution

  • This is a known issue tracked on Github: AppPackageFileExistsAsync Doesn't Work On Linked File with MAUI Assets #12635.

    To fix it, you can write a link to assets in your csproj file like:

     <MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
    

    Then you can read the file like:

    var isExist = await FileSystem.Current.AppPackageFileExistsAsync("MyJsonFile.json");