更新现有 Xamarin.Forms 应用

按照以下步骤更新现有 Xamarin.Forms 应用以使用 Unified API 并更新到版本 1.3.1

重要

由于 Xamarin.Forms 1.3.1 是支持 Unified API 的第一个版本,因此应更新整个解决方案以使用最新版本,同时将 iOS 应用迁移到 Unified。 这意味着,除了更新 iOS 项目以支持统一支持之外,还需要编辑解决方案中所有项目中的代码。

通过两个步骤执行更新:

  1. 使用 Visual Studio for Mac 的迁移工具将 iOS 应用迁移到 Unified API。

    • 使用迁移工具自动更新项目。

    • 按照更新 iOS 应用的说明(特别是在自定义呈现器或依赖项服务代码中)中所述更新 iOS 本机 API。

  2. 将整个解决方案更新为 Xamarin.Forms 版本 1.3。

    1. 安装 Xamarin.Forms 1.3.1 NuGet 包。

    2. 更新共享代码中的 App 类。

    3. 更新 iOS 项目中的 AppDelegate

    4. 更新 Android 项目中的 MainActivity

    5. 更新 Windows Phone 项目中的 MainPage

1. iOS 应用(Unified 迁移)

迁移的一部分需要将 Xamarin.Forms 升级到支持 Unified API 的版本 1.3。 为了创建正确的程序集引用,首先需要更新 iOS 项目以使用 Unified API。

迁移工具

单击 iOS 项目,使其处于选中状态,然后依次选择“项目”>“迁移到 Xamarin.iOS Unified API...”,并同意显示的警告消息。

Choose Project > Migrate to Xamarin.iOS Unified API... and agree to the warning message that appears

这将自动:

  • 更改项目类型以支持 Unified 64 位 API。
  • 将框架引用更改为 Xamarin.iOS(替换旧的 monotouch 引用)。
  • 更改代码中的命名空间引用以删除 MonoTouch 前缀。
  • 更新 csproj 文件,以使用 Unified API 的正确生成目标。

清理生成项目,以确保没有其他要修复的错误。 无需执行进一步操作。 Unified API 文档中更详细地介绍了这些步骤。

更新本机 iOS API(如果需要)

如果添加了其他 iOS 本机代码(如自定义呈现器或依赖项服务),可能需要执行其他手动代码修复。 重新编译应用并参阅“更新现有 iOS 应用”说明,获取有关可能需要更改的其他信息。 这些提示还有助于识别所需的更改。

2.Xamarin.Forms 1.3.1 更新

将 iOS 应用更新到 Unified API 后,解决方案的其余部分需要更新到 Xamarin.Forms 版本 1.3.1。 这包括:

  • 更新每个项目中的 Xamarin.Forms NuGet 包。
  • 更改代码以使用新的 Xamarin.Forms ApplicationFormsApplicationDelegate(iOS)、FormsApplicationActivity (Android) 和 FormsApplicationPage (Windows Phone) 类。

这些步骤如下所述:

2.1 在所有项目中更新 NuGet

使用 NuGet 包管理器针对解决方案中的所有项目将 Xamarin.Forms 更新为 1.3.1 预发行:PCL(如果存在)、iOS、Android 和 Windows Phone。 建议删除并重新添加 Xamarin.Forms NuGet 包以更新到版本 1.3。

注意

Xamarin.Forms 版本 1.3.1 目前为预发行版。 这意味着必须在 NuGet 中选择预发布选项(通过 Visual Studio for Mac 中的勾选框或 Visual Studio 中的下拉列表),才能查看最新的预发行版本。

重要

如果使用的是 Visual Studio,请确保已安装最新版本的 NuGet 包管理器。 Visual Studio 中较旧版本的 NuGet 无法正确安装 Unified版本的 Xamarin.Forms 1.3.1。 转到“工具”>“扩展和更新...”,然后单击“已安装”列表,检查 Visual Studio 的 NuGet 包管理器是否至少为版本 2.8.5。 如果较旧,请单击“更新”列表以下载最新版本。

将 NuGet 包更新到 Xamarin.Forms 1.3.1 后,在每个项目中进行以下更改以升级到新 Xamarin.Forms.Application 类。

2.2 可移植类库(或共享项目)

更改 App.cs 文件,以便:

  • App 类现在继承自 Application
  • MainPage 属性设置为要显示的第一个内容页。
public class App : Application // superclass new in 1.3
{
    public App ()
    {
        // The root page of your application
        MainPage = new ContentPage {...}; // property new in 1.3
    }

我们已完全删除 GetMainPage 该方法,且在 Application 子类上设置了 MainPage属性

这一新点 Application 基类还支持 OnStartOnSleepOnResume 替代,以帮助管理应用程序的生命周期。

然后,App 类将传递到每个应用项目中的新 LoadApplication 方法,如下所示:

2.3 iOS 应用

更改 AppDelegate.cs 文件,以便:

  • 类继承自 FormsApplicationDelegate(而不是以前的 UIApplicationDelegate)。
  • LoadApplication 需使用 App 的新实例调用。
[Register ("AppDelegate")]
public partial class AppDelegate :
    global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate // superclass new in 1.3
{
    public override bool FinishedLaunching (UIApplication app, NSDictionary options)
    {
        global::Xamarin.Forms.Forms.Init ();

        LoadApplication (new App ());  // method is new in 1.3

        return base.FinishedLaunching (app, options);
    }
}

2.3 Android 应用

更改 MainActivity.cs 文件,以便:

  • 类继承自 FormsApplicationActivity(而不是以前的 FormsActivity)。
  • LoadApplication 需使用 App 的新实例调用
[Activity (Label = "YOURAPPNAM", Icon = "@drawable/icon", MainLauncher = true,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity :
    global::Xamarin.Forms.Platform.Android.FormsApplicationActivity // superclass new in 1.3
{
    protected override void OnCreate (Bundle bundle)
    {
        base.OnCreate (bundle);

        global::Xamarin.Forms.Forms.Init (this, bundle);

        LoadApplication (new App ()); // method is new in 1.3
    }
}

2.4 Windows Phone 应用

我们需要更新 MainPage - XAML 和代码隐藏。

更改 MainPage.xaml 文件,以便:

  • 根 XAML 元素应为 winPhone:FormsApplicationPage
  • 应将 xmlns:phone 属性更改xmlns:winPhone="clr-namespace:Xamarin.Forms.Platform.WinPhone;assembly=Xamarin.Forms.Platform.WP8"

下面显示了一个更新的示例 - 你只需编辑这些内容(其余属性应保持不变):

<winPhone:FormsApplicationPage
   ...
   xmlns:winPhone="clr-namespace:Xamarin.Forms.Platform.WinPhone;assembly=Xamarin.Forms.Platform.WP8"
    ...>
</winPhone:FormsApplicationPage>

更改 MainPage.xaml.cs 文件,以便:

  • 类继承自 FormsApplicationPage(而不是以前的 PhoneApplicationPage)。
  • LoadApplication 需使用 Xamarin.Forms App 类的新实例调用。 可能需要完全限定此引用,因为 Windows Phone 具有已定义的 App 类。
public partial class MainPage : global::Xamarin.Forms.Platform.WinPhone.FormsApplicationPage // superclass new in 1.3
{
    public MainPage()
    {
        InitializeComponent();
        SupportedOrientations = SupportedPageOrientation.PortraitOrLandscape;

        global::Xamarin.Forms.Forms.Init();
        LoadApplication(new YOUR_APP_NAMESPACE.App()); // new in 1.3
    }
 }

疑难解答

更新 Xamarin.Forms NuGet 包后,偶尔会看到类似于此的错误。 当 NuGet 更新程序未从 csproj 文件完全删除对旧版本的引用时,就会发生这种情况。

YOUR_PROJECT.csproj:错误:此项目引用的 NuGet 包在此计算机上不存在。 启用“NuGet 包还原”以下载它们。 有关详细信息,请参阅 https://go.microsoft.com/fwlink/?LinkID=322105。 缺少的文件为 ../../packages/Xamarin.Forms.1.2.3.6257/build/portable-win+net45+wp80+MonoAndroid10+MonoTouch10/Xamarin.Forms.targets。 (YOUR_PROJECT)

若要修复这些错误,请在文本编辑器中打开 csproj 文件,并查找引用旧版 Xamarin.Forms 的 <Target 元素,如下面所示的元素。 应从 csproj 文件手动删除此整个元素,然后保存更改。

  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
    <PropertyGroup>
      <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see https://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
    </PropertyGroup>
    <Error Condition="!Exists('..\..\packages\Xamarin.Forms.1.2.3.6257\build\portable-win+net45+wp80+MonoAndroid10+MonoTouch10\Xamarin.Forms.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Xamarin.Forms.1.2.3.6257\build\portable-win+net45+wp80+MonoAndroid10+MonoTouch10\Xamarin.Forms.targets'))" />
  </Target>

删除这些旧引用后,项目应该就能成功生成。

注意事项

将现有 Xamarin.Forms 项目从 Classic API 转换为新的 Unified API(如果该应用依赖于一个或多个组件或 NuGet 包)时,应考虑以下注意事项。

组件

应用程序中包含的任何组件也需要更新为 Unified API,否则在尝试编译时会出现冲突。 对于任何包含的组件,请将当前版本替换为支持 Unified API 的 Xamarin 组件存储中的新版本,并执行全新生成。 作者尚未转换的任何组件都将在组件存储中显示仅 32 位警告。

NuGet 支持

虽然我们贡献了 NuGet 的更改以使用 Unified API 支持,但尚未推出 NuGet 的新版本,因此我们正在评估如何让 NuGet 识别新 API。

在此之前,与组件一样,需要将项目中包含的任何 NuGet 包切换到支持 Unified API 的版本,然后执行干净生成。

重要

如果在将应用程序转换为 Unified API 之后收到以下形式的错误,这通常是因为项目中有组件或 NuGet 包尚未更新到 Unified API:“错误 3 无法在相同的 Xamarin.iOS 项目中同时包含 "monotouch.dll" 和 "Xamarin.iOS.dll" - "Xamarin.iOS.dll" 被显式引用,而 "monotouch.dll" 按 'xxx, Version=0.0.000, Culture=neutral, PublicKeyToken=null" 引用”。 需要删除现有组件/NuGet,更新到支持 Unified API 的版本并执行干净生成。

启用 Xamarin.iOS 应用的 64 位版本

对于已转换为 Unified API 的 Xamarin.iOS 移动应用程序,开发人员仍需要从应用的“选项”中为 64 位计算机启用应用程序生成。 有关启用 64 位版本的详细说明,请参阅 32/64 位平台注意事项文档中的启用 Xamarin.iOS 应用的 64 位版本

总结

Xamarin.Forms 应用程序现在应更新为版本 1.3.1,而且 iOS 应用已迁移到 Unified API(它支持 iOS 平台上的 64 位体系结构)。

如上所述,如果 Xamarin.Forms 应用包含本机代码(如自定义呈现器或依赖项服务),则这些代码可能需要更新才能使用 Unified API 中引入的新类型。