Создание приложения в .NET (8) MAUI BLAZOR HYBRID
Работа инициализируется на Android, Windows и iOS. Однако данные извлекаются и отображаются только в Windows и Android. платформа iOS не получает данные. Он отображает страницу без данных и не перезагружает ее (очевидно, данные все равно не извлекаются). Я поставил точку останова, она не выполняется и не доходит до следующей строки кода:
SharedData.SharedDataBundle = Global.DataBundleCollelction;
Проблема
Наблюдение заключается в том, что приведенный ниже асинхронный вызов не соблюдается на платформе iOS. Windows и Android ждут завершения асинхронного вызова и продолжают обработку данных.
Не знаю, как это исправить, я пробовал много способов его вызова, но async-await Task.Run() или Task.WhenAll(), похоже, не работает на iOS.
Стартовый код
Код в App.Xaml.cs выглядит следующим образом:
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();
}
}
Пожалуйста, подскажите мне, что мне не хватает?
ОБНОВЛЯТЬ:
Я использую следующий метод для чтения файлов JSON из /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!;
}
Наблюдение/Ответ
Приведенная выше функция считывает файл JSON как MauiAsset. Этот путь к файлу был указан как «Resources/Raw/MyJsonFile.json» — этот путь отлично работал для Android и Windows, но не понравился iOS.
Теперь это работает, ссылка, которой поделился (@Alexandar May - MSFT) в комментариях ниже, привела меня к решению.
@AlexandarMay-MSFT (1). Симулятор (2). Я переименовал некоторые переменные и удалил несколько строк кода, чтобы сохранить конфиденциальность. (3). SharedDataService предоставляет общие данные между различными проектами (хранящиеся в формате JSON). Отсюда поступают основные данные. Эти данные подвергаются дальнейшей обработке, прежде чем они будут показаны. (4). WeatherSettingsService — это сервис, который используется для настроек приложения. Пока это можно игнорировать.
Я заменил две задачи простой функцией журнала, запускаемой в симуляторе iOS. Он может выполнить функцию и добраться до точки останова. Я думаю, это связано с сервисом, который вы написали в Задачах. Также sharedDataService
(должен быть общедоступным).
@AlexandarMay-MSFT Я также пробовал просто асинхронные вызовы, даже var file = await FileSystem.AppPackageFileExistsAsync("Resources/Raw/parts.json");
с await
или без него... не работает на iOS. Все остальное работало и работает на Windows и Android. Пробовал на разных симуляторах iOS. читайте об await...async не работает для iOS, и они используют .Result
, что абсурдно! Только для iOS я уничтожу производительность на других платформах?! Я уверен, что должен быть другой способ обработки асинхронных вызовов для платформ iOS.
Неработающий FileSystem.AppPackageFileExistsAsync("Resources/Raw/parts.json")
может быть связан с github.com/dotnet/maui/issues/12635, вы можете следить за этим.
@AlexandarMay-MSFT Ссылка, предоставленная вами выше, привела меня к решению. Файлы JSON не были прочитаны iOS, и причина была той же, что и в ссылке, предоставленной вами выше. Пожалуйста, сделайте это ответом на вопрос, и я отмечу его как ответ.
Это известная проблема, отслеживаемая на Github: AppPackageFileExistsAsync не работает со связанным файлом с активами MAUI № 12635.
Чтобы это исправить, вы можете написать ссылку на ресурсы в своем csproj
файле, например:
<MauiAsset Include = "Resources\Raw\**" LogicalName = "%(RecursiveDir)%(Filename)%(Extension)" />
Затем вы можете прочитать файл следующим образом:
var isExist = await FileSystem.Current.AppPackageFileExistsAsync("MyJsonFile.json");
На самом деле, эта линия является ключевой. <MauiAsset Include = "Resources\Raw\**" LogicalName = "%(RecursiveDir)%(Filename)%(Extension)" />
, после в коде просто укажите файл как.... var isExist = await FileSystem.Current.AppPackageFileExistsAsync("MyJsonFile.json");
- обратите внимание, что нет упоминания «Raw/». Это нужно сделать таким образом, если вы хотите, чтобы он работал на платформе iOS. @Alexandar May - MSFT, пожалуйста, обновите ответ. это несколько неправильно и вводит в заблуждение.
@wafers Готово, спасибо за исправление. :)
1. Вы тестируете на симуляторе или на реальном устройстве? 2. Что такое
SharedDataService
,SharedData
,Global
и чтоWeatherSettingsService
вы используете, узнайте, как создать Минимальный воспроизводимый пример и добавьте его в свой пост.