在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方法中编写特定于平台的代码,以根据他们使用我的应用程序的设备操作系统来保存访问令牌。

当用户在其设备上使用我的应用程序时,如何仅运行特定于设备的代码?

这是一个可以通过dependency injection轻松解决的场景。

在共享或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(key, value); } public string GetString(string key) { (...) } } 

安卓:

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

根据您想要实现的目标以及您拥有的项目类型,有多个答案:

在不同平台上执行不同的Xamarin.Forms代码。
如果您想在不同平台上使用不同的字体,请使用此选项:

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

在共享(PCL)项目中执行特定于平台的代码常见的模式是使用DI(dependency injection)。 Xamarin.Forms提供了一个简单的DependencyService ,但使用您想要的任何内容。

在共享(共享资产项目)项目中执行特定于平台的代码由于代码是按平台编译的,因此您可以将平台特定代码包装在#if __PLATFORM__ #endif并将所有代码包含在同一文件中。 平台项目应该定义__IOS____ANDROID____WINDOWS_PHONE__ 。 请注意,包含Xaml和代码的共享资产项目在Xamarin.StudioXamarin.Studio用于iOS,并且具有编译器指令会使您的代码更难以阅读和测试。

这似乎不太关于Xamarin.Forms以及更多关于在PCL中使用默认值的内容。 查看James Montemagno的github repo进行跨平台默认设置。

然后只需调用他的静态方法来设置/检索。 nuget包是Xam.Plugins.Settings

它可以像这样使用:

 using Refractored.Xam.Settings; 

 CrossSettings.Current.AddOrUpdateValue("AccessToken", accessToken); var value = CrossSettings.Current.GetValueOrDefault("AccessToken"); 

Xamarin.Forms有一个内置的dependency injection器,如果你看一下他们网站开发者领域的指南( http://developer.xamarin.com/guides/cross-platform/xamarin-forms/dependency-service/

还有一个很棒的库,您可以从NuGet / Github( https://github.com/aritchie/acr-xamarin-forms )中获取,它将处理您正在寻找的存储要求…请查看设置服务在那里,它甚至可以处理更复杂对象的序列化。