#c# #xamarin.ios #xamarin #xamarin.android #xamarin.forms
#c# #xamarin.ios #xamarin #xamarin.android #xamarin.forms
Вопрос:
У меня следующая Xamarin.Forms.ContentPage
структура классов
public class MyPage : ContentPage
{
public MyPage()
{
//do work to initialize MyPage
}
public void LogIn(object sender, EventArgs eventArgs)
{
bool isAuthenticated = false;
string accessToken = string.Empty;
//do work to use authentication API to validate users
if(isAuthenticated)
{
//I would to write device specific code to write to the access token to the device
//Example of saving the access token to iOS device
NSUserDefaults.StandardUserDefaults.SetString(accessToken, "AccessToken");
//Example of saving the access token to Android device
var prefs = Application.Context.GetSharedPreferences("MySharedPrefs", FileCreationMode.Private);
var prefsEditor = prefs.Edit();
prefEditor.PutString("AccessToken", accessToken);
prefEditor.Commit();
}
}
}
Я хотел бы написать код для конкретной платформы в MyPage
LogIn
методе сохранения токена доступа в зависимости от того, на какой ОС устройства они используют мое приложение.
Как мне запускать специфичный для устройства код только тогда, когда пользователь использует мое приложение на своем устройстве?
Ответ №1:
Это сценарий, который легко решается с помощью внедрения зависимостей.
Иметь интерфейс с желаемыми методами в вашем общем коде или коде PCL, например:
public interface IUserPreferences
{
void SetString(string key, string value);
string GetString(string key);
}
Создайте свойство для своего App
класса этого интерфейса:
public class App
{
public static IUserPreferences UserPreferences { get; private set; }
public static void Init(IUserPreferences userPreferencesImpl)
{
App.UserPreferences = userPreferencesImpl;
}
(...)
}
Создавайте реализации, зависящие от платформы, в ваших целевых проектах:
iOS:
public class iOSUserPreferences : IUserPreferences
{
public void SetString(string key, string value)
{
NSUserDefaults.StandardUserDefaults.SetString(value, key);
}
public string GetString(string key)
{
return NSUserDefaults.StandardUserDefaults.StringForKey(key);
}
}
Android:
public class AndroidUserPreferences : IUserPreferences
{
public void SetString(string key, string value)
{
var prefs = Application.Context.GetSharedPreferences("MySharedPrefs", FileCreationMode.Private);
var prefsEditor = prefs.Edit();
prefEditor.PutString(key, value);
prefEditor.Commit();
}
public string GetString(string key)
{
(...)
}
}
Затем в каждом проекте, зависящем от платформы, создайте реализацию IUserPreferences
и установите ее, используя App.Init(new iOSUserPrefernces())
App.Init(new AndroidUserPrefernces())
методы либо и .
Наконец, вы можете изменить свой код на:
public class MyPage : ContentPage
{
public MyPage()
{
//do work to initialize MyPage
}
public void LogIn(object sender, EventArgs eventArgs)
{
bool isAuthenticated = false;
string accessToken = string.Empty;
//do work to use authentication API to validate users
if(isAuthenticated)
{
App.UserPreferences.SetString("AccessToken", accessToken);
}
}
}
Комментарии:
1. Во
App
фрагменте кода класса я получаю сообщение «Метод должен иметь возвращаемый тип» при попытке его закодировать. Должен ли он иметь возвращаемый типvoid
?2. Метод init, вероятно, должен иметь
void
возвращаемый тип.3. Это очень хорошее решение, которое организует код в каждом проекте, зависящем от платформы. Спасибо.
4. Спасибо Майклу и Вальдетеро за то, что указали на это и исправили это. Рад, что этот ответ вам подходит, я использую этот подход для нескольких различных функций, специфичных для платформы, к которым мне нужен доступ. Также стоит обратить внимание
DependencyService
, как упоминал Стефан Делькруа.
Ответ №2:
Xamarin.В Forms 2.3.4 представлен новый метод для этого:
if (Device.RuntimePlatform == Device.Android)
{
// Android specific code
}
else if (Device.RuntimePlatform == Device.iOS)
{
// iOS specific code
}
else if (Device.RuntimePlatform == Device.UWP)
{
// UWP specific code
}
Есть и другие платформы на выбор, вы можете ввести Device.
в Visual Studio, и он покажет вам варианты.
Ответ №3:
Существует несколько ответов, в зависимости от того, чего вы хотите достичь, и типа вашего проекта:
Выполнять разный Xamarin.Forms
код на разных платформах.
Используйте это, например, если вам нужны разные размеры шрифта на разных платформах:
label.Font = Device.OnPlatform<int> (12, 14, 14);
Выполнить код, зависящий от платформы, в общем проекте (PCL)
Общим шаблоном является использование DI (внедрение зависимостей) для этого. Xamarin.Forms
предоставляет простой DependencyService
способ для этого, но используйте все, что хотите.
Выполните код, зависящий от платформы, в проекте shared (Shared Asset Project) Поскольку код компилируется для каждой платформы, вы можете обернуть свой код, зависящий от платформы #if __PLATFORM__
#endif
, и поместить весь код в один файл. Проект платформы должен определять __IOS__
, __ANDROID__
и __WINDOWS_PHONE__
. Обратите внимание, что проект с общим ресурсом, содержащий Xaml
код и, не будет хорошо работать для iOS Xamarin.Studio
, и что наличие директив компилятора затрудняет чтение и тестирование вашего кода.
Комментарии:
1. В настоящее время я использую вариант 3 «Выполнить код, зависящий от платформы, в проекте shard (проект с общим ресурсом)» с синтаксисом
__IOS__
and__ANDROID__
, но код, специфичный для Android, не отображается в Intellisense. Специфичный для iOS код отображается в Intellisense2. @MichaelKniskern: измените цель сборки на Android, чтобы для нее был intellisense. и убедитесь (в настройках вашего проекта), что символ экспортирован. кстати, я нахожу забавным, что вы используете этот ответ и принимаете другой 🙂
3. Я решил выбрать ответ, который не зависел от функциональности Xamarin, потому что у меня были другие проблемы с пустым приложением (Xamarin. Формы общего доступа) тип проекта. Кроме того, необходимость каждый раз переключать запуск проекта, если вы хотите использовать код, зависящий от платформы, не идеальна.
Ответ №4:
Xamarin.Forms имеет встроенный инжектор зависимостей, если вы посмотрите их руководство в разделе для разработчиков на их веб-сайте (http://developer.xamarin.com/guides/cross-platform/xamarin-forms/dependency-service /)
Также есть замечательная библиотека, которую вы можете извлечь из NuGet / Github (https://github.com/aritchie/acr-xamarin-forms ), который будет обрабатывать требования к хранилищу, которые вы ищете … взгляните на службу настроек там, она даже будет обрабатывать сериализацию более сложных объектов.
Ответ №5:
Это похоже не Xamarin.Forms
столько на использование значений по умолчанию, сколько на использование значений по умолчанию в PCL. Ознакомьтесь с репозиторием github Джеймса Монтеманьо для выполнения кроссплатформенных настроек по умолчанию.
Затем просто вызовите его статические методы для настройки / извлечения. Пакет nuget является Xam.Plugins.Settings
.
Его можно использовать следующим образом:
using Refractored.Xam.Settings;
…
CrossSettings.Current.AddOrUpdateValue("AccessToken", accessToken);
var value = CrossSettings.Current.GetValueOrDefault<string>("AccessToken");