#xamarin #xamarin.forms #xamarin.ios #xamarin.essentials
Вопрос:
У меня в приложении произошла любопытная ошибка.
У меня есть этот очень простой вспомогательный метод, который я использую для хранения некоторых интересных данных на пользовательском устройстве:
public static async Task TrySetAsync(string key, string value)
{
try
{
await SecureStorage.SetAsync(key, value);
}
catch (Exception ex)
{
await App.Current.MainPage.DisplayAlert(
"Device incompatible",
"Your device is not compatible with this app.",
"Ok");
}
}
Он отлично работает и никогда не имел проблем, но я решил выполнить проверку совместимости при запуске приложения, чтобы пользователь сразу знал, что его устройство не отключит его. Для этого я решил реализовать его в методе OnAppearing() на начальной странице входа в систему. Это выглядит так:
protected override async void OnAppearing()
{
try
{
// Try to save data to a random container
string tempKey = System.Guid.NewGuid().ToString();
// Should throw an exception if SecureStorage is not compatible
await Xamarin.Essentials.SecureStorage
.SetAsync(tempKey, string.Empty);
// Remove the datum
Xamarin.Essentials.SecureStorage
.Remove(tempKey);
}
catch
{
await App.Current.MainPage.DisplayAlert(
"Device incompatible",
"This device does not support secure storage required for the application.",
"Ok");
App.Terminate();
}
base.OnAppearing();
}
Я удалил Права из проекта, чтобы проверить свою маленькую стряпню, и все же она проходит через него без проблем. Никаких исключений не возникает. Но при входе в систему, где используется исходный метод TrySetAsync (первый фрагмент кода), возникает ожидаемое исключение (отсутствует право). Отладчик входит в блок try и оставляет его без проблем.
Вкратце:
Похоже, что приложение не требует никаких прав, когда на SecureStorage ссылаются в OnAppearing (), но вызывает ожидаемое исключение в TrySetAsync (…), определенное в основном классе приложения.
Есть какие-нибудь советы?
P.S. Первоначально я использовал GetAsync со случайной строкой guid в OnAppearing(), которую я изменил на SetAsync и удалил, подумав, что, возможно, получение данных не требует совместимости. В общем, у меня никогда не было такой проблемы с SecureStorage, и мне это действительно кажется какой-то внутренней ошибкой.
ответ
Я виноват в использовании строки.Пусто как значение. Похоже, что SecureStorage.SetAsync проигнорирует такое значение и не сохранит его, что в результате вообще не вызовет никаких исключений. Кроме того, попытка синхронизации несуществующего ключа из SecureStorage также не приведет к исключению отсутствия права
Комментарии:
1. Крайне маловероятно (я склонен сказать, что это невозможно), что расположение кода позволяет использовать несуществующее право. Гораздо более вероятно, что симптом, который вы наблюдали, не означает, что право сработало. Я понятия не имею, как могло случиться, что исключение не было выдано, но я бы проверил более тщательно. Тщательный тест заключается в том, чтобы сохранить значение в securestorage, а затем прочитать его обратно в другую переменную. Используйте линии записи отладки, чтобы узнать, выполняются ли все эти строки кода, и выяснить, правильно ли значение, возвращенное из хранилища.
2. Прогноз: Если у вас есть строка записи отладки после первого вызова securestorage, эта строка никогда не будет выполнена. Также не будет никаких следующих строк в этом блоке try. Если это предсказание окажется верным, то мы исследуем, что это значит. Также добавьте строку записи отладки в качестве первой строки
catch
. Меня не удивит, еслиDisplayAlert
что-то не получится, когда все будет сделано внутриOnAppearing
.3. Кроме того, вы проверили панель вывода VS, чтобы узнать, были ли какие-либо предупреждения или сообщения об ошибках во время выполнения этого кода?
4. Привет, Стив, извини за длинный ответ, я смог сесть за него только сегодня. Следуя вашему совету, я написал более подробный тест и обнаружил, что есть два случая, когда исключение не возникает: 1. значение в SetAsync-строка. Пустой или нулевой: приложение игнорирует значение и не сохраняет его, исключение не создается. 2. ключ, на который ссылается GetAsync, в настоящее время не существует в связке ключей устройства: fetch возвращает значение null (как и ожидалось) и не создает исключения. За исключением этих двух случаев, код работает так, как ожидалось. Мне просто не повезло (и я был немного глуп) использовать строку. Пусто и не вызывает как Get, так и Set
5. Я отредактирую свой исходный вопрос, чтобы он содержал ответ, и сообщу об этом как о проблеме на их GitHub. Спасибо за помощь
Ответ №1:
(ОП сами ответили на этот вопрос):
Я виноват в использовании строки.Пусто как значение. Похоже, что SecureStorage.SetAsync проигнорирует такое значение и не сохранит его, что в результате вообще не вызовет никаких исключений. Кроме того, попытка синхронизации несуществующего ключа из SecureStorage также не приведет к исключению отсутствия права