web-dev-qa-db-fra.com

Écrire du code spécifique à la plateforme de l'appareil dans Xamarin.Forms

J'ai les éléments suivants Xamarin.Forms.ContentPage structure de classe

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();
        }
    }
}

Je voudrais écrire du code spécifique à la plate-forme dans la méthode MyPageLogIn pour enregistrer le jeton d'accès en fonction du système d'exploitation de l'appareil sur lequel ils utilisent mon application.

Comment exécuter uniquement du code spécifique à un appareil lorsque l'utilisateur utilise mon application sur son appareil?

22
Michael Kniskern

Il s'agit d'un scénario qui est facilement résolu avec l'injection de dépendances.

Avoir une interface avec les méthodes souhaitées sur votre code partagé ou PCL, comme:

public interface IUserPreferences 
{
    void SetString(string key, string value);
    string GetString(string key);
}

Avoir une propriété sur votre classe App de cette interface:

public class App 
{
    public static IUserPreferences UserPreferences { get; private set; }

    public static void Init(IUserPreferences userPreferencesImpl) 
    {
        App.UserPreferences = userPreferencesImpl;
    }

    (...)
}

Créez des implémentations spécifiques à la plate-forme sur vos projets cibles:

iOS:

public class iOSUserPreferences : IUserPreferences 
{
    public void SetString(string key, string value)
    {
        NSUserDefaults.StandardUserDefaults.SetString(key, value);
    }

    public string GetString(string 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)
    {
        (...)
    }
}

Ensuite, sur chaque projet spécifique à la plate-forme, créez une implémentation de IUserPreferences et définissez-la à l'aide des méthodes App.Init(new iOSUserPrefernces()) et App.Init(new AndroidUserPrefernces()).

Enfin, vous pouvez changer votre code pour:

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);
        }
    }
}
47
Pedro

Il y a plusieurs réponses, selon ce que vous voulez réaliser et le type de projet que vous avez:

Exécutez différents Xamarin.Forms code sur différentes plates-formes.
Utilisez ceci par ex. si vous voulez différentes tailles de police sur différentes plateformes:

label.Font = Device.OnPlatform<int> (12, 14, 14);

Exécuter du code spécifique à la plate-forme dans un projet partagé (PCL) Le modèle courant est d'utiliser DI (injection de dépendance) pour cela. Xamarin.Forms fournit un simple DependencyService pour cela, mais utilisez ce que vous voulez.

Exécuter le code spécifique à la plate-forme dans le projet partagé (Shared Asset Project) Comme le code est compilé par plate-forme, vous pouvez encapsuler votre code spécifique à la plate-forme dans #if __PLATFORM__#endif et avoir tout le code dans le même fichier. Le projet de plateforme doit définir __IOS__, __Android__ et __WINDOWS_PHONE__. Notez qu'un projet d'actif partagé contenant Xaml et du code ne fonctionnera pas bien pour iOS sur Xamarin.Studio, et le fait d'avoir des directives de compilation rend votre code plus difficile à lire et à tester.

9
Stephane Delcroix

Cela semble moins sur Xamarin.Forms et plus sur l'utilisation des valeurs par défaut dans un PCL. Consultez repo github de James Montemagno pour faire des valeurs par défaut multiplateforme.

Ensuite, appelez simplement ses méthodes statiques pour définir/récupérer. Le paquet nuget est Xam.Plugins.Settings.

Il peut être utilisé comme ceci:

using Refractored.Xam.Settings;

...

CrossSettings.Current.AddOrUpdateValue("AccessToken", accessToken);
var value = CrossSettings.Current.GetValueOrDefault<string>("AccessToken");
2
valdetero

Xamarin.Forms dispose d'un injecteur de dépendances intégré si vous consultez son guide dans la zone développeur de leur site Web ( http://developer.xamarin.com/guides/cross-platform/xamarin-forms/ service de dépendance / )

Il existe également une merveilleuse bibliothèque que vous pouvez extraire de NuGet/Github ( https://github.com/aritchie/acr-xamarin-forms ) qui gérera les besoins de stockage que vous recherchez ... prenez un coup d'oeil au service Paramètres là-dedans, il va même gérer la sérialisation des objets plus complexes.

1
J Geary