Docs 菜单
Docs 主页
/ /
Atlas App Services

教程:使用 MAUI 的 Atlas Device Sync for .NET

在此页面上

  • 先决条件
  • 从模板开始
  • 设置模板应用程序
  • 打开应用
  • 探索应用结构
  • 运行应用
  • 检查后端
  • 修改应用程序
  • 添加新属性
  • 添加优先级属性
  • 在创建或修改项目时设置优先级
  • 更新用户界面元素
  • 运行和测试
  • 更改订阅
  • 更新订阅
  • 运行和测试
  • 结论
  • 接下来的步骤

预计完成时间:30 分钟,具体取决于您在Maui的体验

Realm 提供了 .NET SDK,支持使用 C# 和 MAUI 创建多平台应用程序。本教程基于名为 maui.todo.flex 的 .NET 灵活同步模板应用,该应用演示了 MAUI 待办事项应用程序的创建。该应用程序使用户能够:

  • 将他们的电子邮件注册为新用户帐户。

  • 使用他们的电子邮件和密码登录他们的帐户(然后退出)。

  • 查看、创建、修改和删除任务。

在本教程中,您将向现有 Item 模型添加一个新的 Priority 字段,并更新灵活同步订阅以仅显示优先级范围内的事项。

注意

查看“快速入门”

如果更想开始使用自己的应用程序而不是跟随引导式教程,请查看 .NET快速入门。 其中包括可复制的代码示例以及设立Atlas App Services后端所需的基本信息。

  • 确保您已安装必要的软件。选择您的开发环境对应的标签页:

    • Windows 7 或更高版本。推荐使用 Windows 10。

    • Visual Studio2017 (推荐使用 Visual Studio 2019)。

    • Android6.0 / API 级别23

    • 要在 Windows 上构建 iOS 项目,您还需要一台 Mac 电脑,可以通过 Windows 电脑进行网络访问,且符合在 macOS 上运行 Xamarin 的最低要求。

  • 您需要具备将 MAUI 或 Xamarin 应用部署到 Android 模拟器、iOS 模拟器和/或物理设备的经验。

  • 本教程从“模板应用程序”开始。创建“模板应用程序”需要 Atlas 帐号、API 密钥和 App Services CLI。

    • 如需了解有关创建 Atlas 帐户的更多信息,请参阅 Atlas 入门文档。在本教程中,您需要一个带有免费层级集群的 Atlas 帐户。

    • 您还需要一个用于登录的 MongoDB Cloud 账户的 Atlas API 密钥。您必须是项目所有者才能使用 App Services CLI 创建模板应用。

    • 要了解有关安装 App Services CLI 的更多信息,请参阅安装 App Services CLI 。安装后,使用 Atlas 项目的 API 密钥运行登录命令。

本教程基于名为 maui.todo.flex 的 MAUI 灵活同步模板应用。我们先使用默认应用,然后在其上构建新功能。

要了解有关模板应用的更多信息,请参阅模板应用

如果您还没有 Atlas 帐号,请注册以部署“模板应用程序”。

按照“创建App Services App”指南中描述的步骤操作,然后选择 Create App from Template 。 选择Real-time Sync模板。 这将创建一个预先配置为与Device Sync模板应用客户端之一一起使用的App Services App 。

创建模板应用后,用户界面会显示一个标有 Get the Front-end Code for your Template 的模态窗口。此模态窗口提供有关将模板应用客户端代码下载为 .zip 文件或使用 App Services CLI 获取客户端的说明。

选择 .zip 或 App Services CLI 方法后,请按照屏幕上的说明获取客户端代码。对于本教程,请选择 C# (.NET MAUI) 客户端代码。

注意

默认的Windows ZIP 实用程序可能会显示 .zip 文件为空。 如果遇到这种情况,请使用可用的第三方 zip 程序。

appservices apps create 命令设置后端,并创建一个 C# (MAUI) 模板应用,供您用作本教程的基础。

在终端窗口中运行以下命令,创建一个名为“MyTutorialApp”的应用,将该应用部署在 US-VA 地区,并将其环境设置为“开发”(而不是生产或 QA)。

appservices app create \
--name MyTutorialApp \
--template maui.todo.flex \
--deployment-model global \
--environment development

该命令在当前路径中创建一个新目录,其名称与 --name 标志的值相同。

Github您可以创建分支并克隆包含Device Sync 客户端代码的 存储库。C#客户端代码位于 https://github.com/mongodb/template-app-maui-todo。

如果您使用此过程来获取客户端代码,则必须创建一个 App Services 应用以配合客户端使用。按照创建模板应用中的说明操作,基于 sync.todo 模板创建一个模板应用。

1

导航到 Realm CLI 创建模板应用的目录,然后在 Visual Studio 中打开 realm-todo-app.sln 解决方案。

2

在 Visual Studio 中,花几分钟时间探索解决方案的组织方式。其结构就像一个标准 MAUI MVVM 解决方案,单个项目包含视图、模型和视图模型。

该应用使用单个模型 Item,该模型实现了 IRealmObject。我们有三个视图,一个用于登录 (LoginPage),另一个用于查看事项 (ItemsPage),第三个用于编辑和创建新事项。每个视图都有相应的视图模型。

除了标准的 MVVM 结构之外,我们还将所有 Realm 逻辑集中到一个 RealmService 类中,该类位于“Services”文件夹中。这种架构确保我们自始至终共享同一个 Realm。

3

无需对代码进行任何更改,您应该能够在 Android 模拟器、iOS 模拟器或物理设备上运行该应用。无需进行任何更改,因为当您在 App Services 用户界面中或通过 CLI 设置模板时,Atlas App Services 也会设置一个新的后端。如果您下载了模板应用,则需要添加 App Services 应用的 ID。为此,请打开 Services/RealmService.cs 文件,并将您的 ID 添加到 private const string appId = "appId"; 行。

运行应用,注册一个新用户帐户,然后将新事项添加到待办事项清单中。

4

登录 Atlas App Services。在 Data Services 标签页中,单击 Browse Collections。在数据库列表中,找到并展开 todo 数据库,然后找到并展开 Item 集合。您应该会看到在此集合中创建的文档。

现在您已经确认一切都按预期进行,我们可以添加更改。在本教程中,我们决定为每个事项添加“Priority”属性,以便我们可以按事项的优先级过滤事项。Priority 属性将映射到 PriorityLevel 枚举以限制可能的值。

为此,请按照以下步骤操作:

1
  1. RealmTodo 项目中,展开 Models 文件夹并打开 Item 类文件。

  2. 添加以下公共属性:

    [MapTo("priority")]
    public int? Priority { get; set; }

    请注意,我们已将此属性设置为可为空,这将确保数据库中的现有项(没有 Priority 属性)继续可用。

2
  1. EditItemViewModel ViewModel 用于创建新事项和修改现有事项。创建或修改事项时,用户需要通过用户界面(和代码)来设置事项的优先级。

  2. 添加一个 ObservableProperty 来保持优先级:

    [ObservableProperty]
    private int? priority;

    注意

    [ObservableProperty] 属性

    [ObservableProperty] 属性是 MVVM 工具包 提供的一项功能,用于简化数据绑定。

  3. ApplyQueryAttributes 方法有点像此视图模型的“构造函数”,检查现有事项是否传递到此视图进行编辑。在这里,我们会捕获任何现有值,以便显示在视图中。

    如果正在编辑现有项,我们希望设置现有项的优先级:Priority = InitialItem.Priority;

    同样,如果是创建新事项,则将默认优先级设置为 Medium(中):Priority = 2;

    完成后,此方法现在应类似如下所示:

    public void ApplyQueryAttributes(IDictionary<string, object> query)
    {
    if (query.Count > 0 && query["item"] != null) // we're editing an Item
    {
    InitialItem = query["item"] as Item;
    Summary = InitialItem.Summary;
    Priority = InitialItem.Priority;
    PageHeader = $"Modify Item {InitialItem.Id}";
    }
    else // we're creating a new item
    {
    Summary = "";
    Priority = 2;
    PageHeader = "Create a New Item";
    }
    }
  4. 最后,在 SaveItem() 方法中,我们希望持久化优先级值。由于我们正在创建或修改托管对象,因此更改被包装在 realm.WriteAsync 调用中。

    对于现有事项,请在现有对象上设置 InitialItem.Priority;对于新事项,请在 Add() 调用中设置该属性。写完后的 WriteAsync 块应如下所示:

    await realm.WriteAsync(() =>
    {
    if (InitialItem != null) // editing an item
    {
    InitialItem.Summary = Summary;
    InitialItem.Priority = Priority;
    }
    else // creating a new item
    {
    realm.Add(new Item()
    {
    OwnerId = RealmService.CurrentUser.Id,
    Summary = summary,
    Priority = Priority
    });
    }
    });
3
  1. 最后一项任务是添加设置和显示优先级所需的用户界面元素。

    首先,在 ItemsPage.xaml 中,我们将向 ListView 添加一个显示优先级的标签。在 ViewCell 中,添加一个显示项目优先级的标签:

    <Label Text="{Binding Priority}"
    HorizontalOptions="Center"
    VerticalOptions="Center"/>
  2. EditItemsPage.xaml 中,我们将添加两个 UI 元素:一个选取器(让用户能够选择为新事项设置何种优先级)和一个选取器标签。找到用于设置摘要的 Entry 元素,并在其下方添加以下元素:

    <Label Text="Priority:"/>
    <Picker x:Name="newItemPriority" SelectedIndex="{Binding Priority}">
    <Picker.Items>
    <x:String>Severe</x:String>
    <x:String>High</x:String>
    <x:String>Medium</x:String>
    <x:String>Low</x:String>
    </Picker.Items>
    </Picker>
4

此时,您可以再次运行应用程序。使用本教程前面创建的帐户登录。您将看到先前创建的一个列项。添加新列项,您将看到现在可以设置优先级。为优先级选择 High 并保存条目。

现在切换回浏览器中的 Atlas 数据页面,并刷新 Item 集合。您现在应该会看到添加了 priority 字段并将其设置为1 的新项目。您还会注意到,现有项目现在也有一个priority 字段,并且它设置为 null,如以下屏幕截图所示:

集合中的两个项目
点击放大

注意

为什么没有中断同步?

向 Realm 对象添加属性不是一项重大更改,因此不需要重置客户端。模板应用启用了开发模式,因此对客户端 Realm 对象的更改会反映在服务器端模式中。有关更多信息,请参阅开发模式更新数据模型

1

RealmService.cs 文件中,我们定义两个灵活同步订阅。一个只显示当前用户创建的事项,另一个则显示所有用户的所有事项。

我们将添加一个新订阅,以显示当前用户的优先级为 0 或 1 的事项。

  1. RealmService 类的底部,向 SubscriptionType 枚举添加一个名为“MyHighPriority”的条目:

    public enum SubscriptionType
    {
    Mine,
    MyHighPriority,
    All,
    }
  2. 向上滚动以找到 GetQueryForSubscriptionType 方法。我们在这里定义订阅。

    1. 复制第一个,其中subType == SubscriptionType.Mine ,立即将其粘贴到其下面的else if 块中。

    2. 将新条件设置为 subType == SubscriptionType.MyHighPriority

    3. 修改此新订阅查询以插入一个 LINQ 查询,该查询不仅仍按 OwnerId 筛选,还按优先级值小于 2 进行筛选。

    4. 将新查询的名称改为“myHighPri”。您的代码将类似如下所示:

    if (subType == SubscriptionType.Mine)
    {
    query = realm.All<Item>()
    .Where(i => i.OwnerId == CurrentUser.Id)
    .Where(i => i.Priority < 2);
    queryName = "mine";
    }
    else if (subType == SubscriptionType.MyHighPriority)
    {
    query = realm.All<Item>()
    .Where(i => i.OwnerId == CurrentUser.Id &&
    i.Priority < 2);
    queryName = "myHighPri";
    }
    else if (subType == SubscriptionType.All)
    {
    query = realm.All<Item>();
    queryName = "all";
    }
  3. 在上面的 GetCurrentSubscriptionType 方法中,将新订阅名称添加到 switch 语句中,如下所示:

    return activeSubscription.Name switch
    {
    "all" => SubscriptionType.All,
    "mine" => SubscriptionType.Mine,
    "myHighPri" => SubscriptionType.MyHighPriority,
    _ => throw new InvalidOperationException("Unknown subscription type")
    };
  4. 最后,打开ItemsViewModel 类并找到OnIsShowAllTasksChanged 方法。我们不变换用户界面以启用 3 个订阅,而是只将现有“mine”订阅替换为新订阅。更改SetSubscription 方法,使其类似如下所示:

    await RealmService.SetSubscription(realm, value
    ? SubscriptionType.All
    : SubscriptionType.MyHighPriority);
2

再次运行应用程序。如果出现提示,请使用本教程前面创建的 帐户登录。

您应该会看到您创建的任何优先级为“高”(1) 或“严重”(0) 的项目。如果切换“Show all tasks”(显示所有任务)开关,应显示所有用户的所有任务。

提示

在启用开发者模式的情况下更改订阅

在本教程中,当您首次更改优先级字段的订阅和查询时,该字段将自动添加到 Device Sync Collection Queryable Fields 中。出现这种情况是因为模板应用默认启用了开发模式。如果未启用开发模式,您必须手动将该字段添加为可查询字段,以便在客户端同步查询中使用它。

有关更多信息,请参阅可查询字段

向现有 Realm 对象添加属性是一项非重大更改,并且开发模式可确保模式更改反映在服务器端。

注意

分享反馈

怎么样?使用页面右下角的 Rate this page 小组件来评价其有效性。如果有任何问题,也可以在 Github 存储库 上提交问题。

来年

什么是 Atlas App Services?