教程:使用 MAUI 的 Atlas Device Sync for .NET
在此页面上
预计完成时间:30 分钟,具体取决于您在Maui的体验
Realm 提供了 .NET SDK,支持使用 C# 和 MAUI 创建多平台应用程序。本教程基于名为 maui.todo.flex
的 .NET 灵活同步模板应用,该应用演示了 MAUI 待办事项应用程序的创建。该应用程序使用户能够:
将他们的电子邮件注册为新用户帐户。
使用他们的电子邮件和密码登录他们的帐户(然后退出)。
查看、创建、修改和删除任务。
在本教程中,您将向现有 Item
模型添加一个新的 Priority
字段,并更新灵活同步订阅以仅显示优先级范围内的事项。
先决条件
确保您已安装必要的软件。选择您的开发环境对应的标签页:
- 适用于 Mac 的 Visual Studio
- 2019 或更新版本。
Xcode10 。0 或更高版本。请注意,Xcode 10需要 macOS High Sierra ( 10 . 13 ) 或更新版本。
Windows 7 或更高版本。推荐使用 Windows 10。
Visual Studio2017 (推荐使用 Visual Studio 2019)。
要在 Windows 上构建 iOS 项目,您还需要一台 Mac 电脑,可以通过 Windows 电脑进行网络访问,且符合在 macOS 上运行 Xamarin 的最低要求。
您需要具备将 MAUI 或 Xamarin 应用部署到 Android 模拟器、iOS 模拟器和/或物理设备的经验。
从模板开始
本教程基于名为 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
模板创建一个模板应用。
设置模板应用程序
探索应用结构
在 Visual Studio 中,花几分钟时间探索解决方案的组织方式。其结构就像一个标准 MAUI MVVM 解决方案,单个项目包含视图、模型和视图模型。
该应用使用单个模型 Item
,该模型实现了 IRealmObject
。我们有三个视图,一个用于登录 (LoginPage
),另一个用于查看事项 (ItemsPage
),第三个用于编辑和创建新事项。每个视图都有相应的视图模型。
除了标准的 MVVM 结构之外,我们还将所有 Realm 逻辑集中到一个 RealmService 类中,该类位于“Services”文件夹中。这种架构确保我们自始至终共享同一个 Realm。
检查后端
登录 Atlas App Services。在 Data Services 标签页中,单击 Browse Collections。在数据库列表中,找到并展开 todo 数据库,然后找到并展开 Item 集合。您应该会看到在此集合中创建的文档。
修改应用程序
添加新属性
现在您已经确认一切都按预期进行,我们可以添加更改。在本教程中,我们决定为每个事项添加“Priority”属性,以便我们可以按事项的优先级过滤事项。Priority 属性将映射到 PriorityLevel 枚举以限制可能的值。
为此,请按照以下步骤操作:
在创建或修改项目时设置优先级
EditItemViewModel
ViewModel 用于创建新事项和修改现有事项。创建或修改事项时,用户需要通过用户界面(和代码)来设置事项的优先级。添加一个 ObservableProperty 来保持优先级:
[ ]private int? priority; 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"; } } 最后,在
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 }); } });
更新用户界面元素
最后一项任务是添加设置和显示优先级所需的用户界面元素。
首先,在
ItemsPage.xaml
中,我们将向 ListView 添加一个显示优先级的标签。在 ViewCell 中,添加一个显示项目优先级的标签:<Label Text="{Binding Priority}" HorizontalOptions="Center" VerticalOptions="Center"/> 在
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>
更改订阅
更新订阅
在 RealmService.cs
文件中,我们定义两个灵活同步订阅。一个只显示当前用户创建的事项,另一个则显示所有用户的所有事项。
我们将添加一个新订阅,以显示当前用户的优先级为 0 或 1 的事项。
在
RealmService
类的底部,向SubscriptionType
枚举添加一个名为“MyHighPriority”的条目:public enum SubscriptionType { Mine, MyHighPriority, All, } 向上滚动以找到
GetQueryForSubscriptionType
方法。我们在这里定义订阅。复制第一个,其中
subType == SubscriptionType.Mine
,立即将其粘贴到其下面的else if
块中。将新条件设置为
subType == SubscriptionType.MyHighPriority
。修改此新订阅查询以插入一个 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"; } 在上面的
GetCurrentSubscriptionType
方法中,将新订阅名称添加到 switch 语句中,如下所示:return activeSubscription.Name switch { "all" => SubscriptionType.All, "mine" => SubscriptionType.Mine, "myHighPri" => SubscriptionType.MyHighPriority, _ => throw new InvalidOperationException("Unknown subscription type") }; 最后,打开
ItemsViewModel
类并找到OnIsShowAllTasksChanged
方法。我们不变换用户界面以启用 3 个订阅,而是只将现有“mine”订阅替换为新订阅。更改SetSubscription
方法,使其类似如下所示:await RealmService.SetSubscription(realm, value ? SubscriptionType.All : SubscriptionType.MyHighPriority);
运行和测试
再次运行应用程序。如果出现提示,请使用本教程前面创建的 帐户登录。
您应该会看到您创建的任何优先级为“高”(1) 或“严重”(0) 的项目。如果切换“Show all tasks”(显示所有任务)开关,应显示所有用户的所有任务。
提示
在启用开发者模式的情况下更改订阅
在本教程中,当您首次更改优先级字段的订阅和查询时,该字段将自动添加到 Device Sync Collection Queryable Fields 中。出现这种情况是因为模板应用默认启用了开发模式。如果未启用开发模式,您必须手动将该字段添加为可查询字段,以便在客户端同步查询中使用它。
有关更多信息,请参阅可查询字段。
结论
向现有 Realm 对象添加属性是一项非重大更改,并且开发模式可确保模式更改反映在服务器端。
接下来的步骤
阅读我们的 .NET SDK 文档。
在 MongoDB 开发者中心查找面向开发者的博客文章和集成教程。
加入 MongoDB Community 论坛,向其他 MongoDB 开发者和技术专家学习。
探索工程和专家团队提供的示例项目。