此文章由机器翻译。

新型应用程序

Windows 应用商店应用中的数据访问和存储可选方案

Rachel Appel

 

Rachel Appel管理数据是应用程序开发中的关键组成部分。 无论是游戏、新闻、旅游还是时尚应用程序,总是跟数据有关。 新型应用程序通常需要对分散在多个离散位置且格式种类繁多的数据进行管理。 我将讨论可用来构建 Windows 应用商店应用的各种数据存储可选方案和数据访问 API(所有语言),以及内容和配置的数据管理策略。

数据管理和存储注意事项

作为应用程序开发人员,您需要在项目启动之前确定应用程序的数据需求,因为更改底层体系结构会导致很多工作都要返工。 您可能已经有了数据源,这种情况无需再做决定,但是对于初始项目,您必须考虑数据存储在何处。 您有两个选择,在设备上或远程位置:

  • 本地: 通常这些数据在文件或本地数据库中,但是在 Windows 8 中,您现在可以使用内置的文件选取器或合约,将其他应用程序作为数据源。 在 JavaScript 应用程序中,Web 存储和索引型数据库 (IndexedDB) API 也可用作本地数据源。
  • 远程: 这些数据可以位于云中(使用 Windows Azure SkyDrive),或者位于可提供 JSON 或 XML 数据的远程 HTTP 端点(包括 Facebook 或 Flickr 之类的公共 API)。

数据的大小通常决定了数据在本地还是远程;但是,对于大多数的新型应用程序,这两种数据源中的数据都可以使用。 这是因为更小、移动性更强的设备(如平板电脑和手机)随处可见,它们通常没多少存储空间。 尽管如此,它们在脱机时仍然需要数据才能正常工作。 例如,Surface 与很多便携式设备一样,有 32GB 和 64GB 型号。 简单的基于文本的数据(如 JSON)通常不大,但是关系数据库和媒体数据(如图像、音频和视频)可以很快填满设备。

让我们看一下都有哪些本地和远程可选方案可用于存储应用程序的内容数据。

Web 存储

从字面上来看,Web 存储 (bit.ly/lml0Ul) 就是 Web 上的存储,但事实并非如此。 相反,作为 HTML5 标准,Web 存储是将应用程序数据保存在客户端本地的好办法。 Windows 应用商店应用和普通旧 HTML 页面都支持 Web 存储。 由于 Web 存储是一种内存中数据库,因此不需要数据库设置,也不需要复制文件。

借助下面的两个窗口对象属性之一可以通过 JavaScript 来访问 Web 存储:

  1. localStorage: 本地数据在应用程序终止后持久存储,可供将来的应用程序实例使用。
  2. sessionStorage: 也是本地数据;但是,sessionStorage 在 Windows 应用商店应用终止执行时销毁。

通过将动态属性附加到 sessionStorage 或 localStorage 变量,可以将数据(从简单类型到复杂对象)存储到 Web 存储中。 动态属性是键/值对,语法如下:

sessionStorage.lastPage = 5;
WinJS.xhr({ url: "data/data.json" }).then(function (xhr) {
  localStorage.data = xhr.responseText;
};

lastPage 属性是 sessionStorage 的组成部分,延续到应用程序终止;而 localStorage 的 data 属性则在应用程序的生命周期完结之后仍会持久保存。

Web 存储可在应用程序会话之间将数据持久保存在本地,从而使其成为支持脱机应用方案的极佳选择。 小型数据也更适合脱机支持。 由于 JSON 数据很紧凑,因此很容易将整个 JSON 数据集都存入 Web 存储提供的 5MB 空间中,还能有足够的空间留给某些媒体数据。

因为 Web 存储是 HTML5 标准,因此只能用于使用 JavaScript 构建的 Windows 应用商店项目中。

IndexedDB

HTML5 系列中的另一个标准是 IndexedDB (bit.ly/TT3btM),针对大型可搜索持久数据集的本地数据存储。 作为 HTML5 的组件,可以将 IndexedDB 用于浏览器客户端 Web 应用程序和 Windows 应用商店应用。 IndexedDB 在对象数据库中存储项,并且极为灵活,可以存储从文本到二进制大对象 (BLOB) 的任何类型的数据。 例如,多媒体文件往往很大,因此在 IndexedDB 中存储音频和视频是很好的选择。

因为 IndexedDB 是对象数据库,因此它不使用 SQL 语句,必须通过面向对象的样式语法来访问数据。 与 IndexedDB 数据存储交互需通过事务和游标,如下面所示:

var dataStore = "Datastore";
var trn = db.transaction(dataStore, IDBTransaction.READ_ONLY);
var store = trn.objectStore(dataStore);
trans.oncomplete = function(evt) { // transaction complete };
var request = store.openCursor();
request.onsuccess = function(evt) {
  var cursor = evt.openCursor();
};
request.onerror = function(error) { // error handling };

由于 IndexedDB 专门针对的是大型数据,用它来存储小型项会导致运行效率低下,因此位(或字节)级别的本地数据更适合采用 Web 存储。 IndexedDB 还非常适合存储内容数据,但是不适合存储应用程序配置数据。

SQLite

SQLite (bit.ly/65FUBZ) 是一种基于文件的自包含事务性关系数据库,它不需要配置,且不需要数据库管理员来维护。 可以将 SQLite 与任何 Windows 运行时 (WinRT) 语言一起使用,并且可用作 Visual Studio 扩展。 尽管 SQLite 在 JavaScript 应用程序中工作良好,但是您在使用之前仍需要从 GitHub 获得 SQLite3 的 WinRT 包装 (bit.ly/J4zzPN)。

具有 ASP.NET 或 Windows Forms 背景的开发人员更倾向于使用关系数据库。但是,鉴于移动设备的空间问题,以及数据的各种类型和格式(尤其是多媒体),对于开发新型应用程序而言,关系数据库管理系统 (RDBMS) 并非总是最佳选择。 由于 SQLite 是关系数据库,对于需要关系和事务性行为的应用程序,它才有用武之地。 这意味着 SQLite 是业务线 (LOB) 应用程序或数据输入应用程序的很好选择,也可以作为一个存储库,最初从联机源获得数据,然后存储在本地供脱机使用。

如果 SQLite 数据库对于便携移动设备过大,可以将其移动到服务器或云位置。 需要更改的代码并不多,因为 SQLite3 库使用传统连接,创建/读取/更新/删除 (CRUD) 对象类似于下面的代码:

// C# code that opens an async connection.
var path =
  Windows.Storage.ApplicationData.Current.LocalFolder.Path + @"\data.db";
var db = new SQLiteAsyncConnection(path);
// JavaScript code that opens an async connection.
var dbPath =
  Windows.Storage.ApplicationData.current.localFolder.path + '\\data.db;
SQLite3JS.openAsync(dbPath).then(function (db) {
  // Code to process data.
});

可见,SQLite 的使用和其他 SQL 数据库一样。 SQLite 数据库的上限可高达 140TB。 请注意,非常大的数据通常需要专业的数据库管理,以获得可能最佳的数据完整性、性能和安全性。 大多数使用关系数据库的 DBA 和开发人员,首选 GUI 工具来创建和管理数据库对象或对数据运行即席查询,对于所有基本 SQLite 操作而言,Sqliteman (bit.ly/9LrB1o) 管理实用工具是理想的选择。

如果您要移植用 Windows Forms、Windows Presentation Foundation (WPF) 或 Silverlight 编写的现有 Windows 桌面应用程序,您可能已经在使用 SQL Server Compact (SQL CE)。 如果确实如此,可以使用 ExportSqlCE (bit.ly/dwVaR3) 实用工具将 SQL CE 数据库迁移到 SQLite,然后使用 Sqliteman 来管理数据库。

文件即数据和文件 API

何必纠结于数据库,尤其是应用程序的用户希望坚持使用他们已有的文件? 对于照片和文档尤其如此。 文件 API 远不止是目录和文件的导航器;它给予用户选择应用程序作为文件位置的能力。 这意味着应用程序可相互对话和交换数据。 文件打开选取器可与 Bing、相机或照片应用程序,以及常规目录和命名位置(如“我的文档”、“视频”或“音乐”)交互。 在应用程序、服务和个人文件之间如此轻松共享数据是 Windows 最炫的功能。

很多操作系统提供了一种机制,用于注册应用程序要使用的文件类型,当用户对操作系统中的文件图标进行操作时,系统将启动相应的应用程序。 在 Windows 中,这称为文件关联。 Windows 8 延伸了这一概念,通过名为“合约”的系统级功能,应用程序可以相互对话。 实现合约的一种方法是通过文件选取器。 请注意,以下代码与桌面应用程序或早期 Windows 版本的文件对话框 API 类似(注意:为简洁起见,此示例省略了部分代码;有关 FileOpenPicker 类的更详尽说明,请参阅 bit.ly/UztmDv):

fileOpen: function () {
  var openPicker = new Windows.Storage.Pickers.FileOpenPicker();
  openPicker.viewMode = Windows.Storage.Pickers.PickerViewMode.thumbnail;
  openPicker.suggestedStartLocation =
    Windows.Storage.Pickers.PickerLocationId.picturesLibrary;
  openPicker.fileTypeFilter.replaceAll([".png", ".jpg", ".jpeg"]);
  openPicker.pickSingleFileAsync().done(function (file) {
  // ...
});
}

从 Windows 8 选取器中选择一个应用程序将会启动该应用程序。 例如,如果用户选择 Bing,选取器将启动 Bing 应用程序,然后将用户的图像选择返回给您的应用程序。

现在,我们了解了本地可选方案,接下来看看远程数据的可选方案。

Web 服务和 ASP.NET Web API

大多数开发人员都熟悉利用 XML Web 服务来使用和修改数据,因为他们经历了 Microsoft .NET Framework 1.x 的那个时代。 使用 Web 服务的主要优点是,数据存储在一个远程的中心位置中,多个设备的应用程序可在连接的任何时刻访问数据。 对底层数据库的访问则通过一组 HTTP 端点间的管道来交换 JSON 或 XML 数据。 很多公共 API,如 Twitter 或 Flickr,公开可在 Windows 应用商店应用中使用的 JSON 或 XML 数据。

Web 服务有各种类型:

  • ASMX 服务: 使用传统 ASP.NET 通过 HTTP 发送数据。
  • Windows Communication Foundation (WCF) 和丰富 Internet 应用程序 (RIA) 服务: 一种基于消息、在 HTTP 端点间发送数据的方法。
  • OData: 开放数据协议,另一种通过 HTTP 传输数据的 API。
  • ASP.NET Web API: 一个新的 ASP.NET MVC 4 框架,可以轻松构建支持 REST 的 HTTP 服务,向应用程序或网站发送 JSON 或 XML 数据。

如果您从头开始构建后端服务,ASP.NET Web API 可简化开发过程,因为它能够以一致的方式轻松构建支持 REST 的服务并可供应用程序使用。 

无论什么后端服务,只要是通过 HTTP,就可以使用 HttpWebRequest 和 HttpWebResponse 对象通过 C# 与 Web 服务通信。 在 JavaScript 应用程序中,WinJS XMLHttpRequest 包装适合异步操作,类似下面的代码:

WinJS.xhr({ url: "data.json" }).then(function (xhr) {
  var items = JSON.parse(xhr.responseText);
  items.forEach(function (item) {
    list.push(item);
  })
});

存储空间对于 Web 服务来说通常不是问题,因为 Web 服务只是在端点之间传输数据的软件。 这意味着其底层数据库可位于任何位置,如远程服务器、Web 主机或 Windows Azure 实例。

您可以在 Windows Azure 上托管前面提到的任何 Web 服务,如 ASP.NET Web API 实例或 WCF 服务,以及数据本身。

SkyDrive

不要忘记 SkyDrive (bit.ly/HYB7iw) 不仅是数据存储的可选方案,而且是一个绝佳的方案。 将 SkyDrive 想像成非存储的存储可选方案。 用户可以选择 SkyDrive 作为云中的位置,并通过“文件打开”或“保存”选取器访问文档。 允许用户将文件保存到 SkyDrive 意味着无需操心数据库管理,而且每用户 7 GB 的空间绰绰有余。 SkyDrive 用户还可购买更多存储空间。

Live API (bit.ly/mPNb03) 包含有一整套支持 REST 的 SkyDrive API,可用于读取和写入 SkyDrive。 下面显示了一个用于检索共享项列表的 SkyDrive 调用:

GET https://apis.live.
netv5.0/me/skydrive/shared?access_token=ACCESS_TOKEN

Microsoft.Live 命名空间允许 C# 开发人员访问 Live 和 SkyDrive API,而 JavaScript 开发人员可以用 HTTP 谓词 POST 或 PUT 发出支持 REST 的调用。 应用程序配置数据不推荐使用 SkyDrive。

Windows Azure 移动服务

Windows Azure 移动服务是构建跨平台和多平台应用程序的极佳可选方案。 依托于 Windows Azure 的支持,此可选方案提供的不仅仅是可扩展的存储;它还提供推送通知、业务逻辑管理、身份验证 API 和一套完整的 SDK。 除了这些功能外,它还提供了一个易于使用的基于 Web 的管理工具。

移动服务 SDK 集成了对 Windows 应用商店、Windows Phone 8、iOS 和 Android 应用程序的支持。 支持所有主流平台;通过移动服务 SDK,您只需几分钟便可构建出一个工作原型,随即便可直接将数据交付到多平台应用程序。

SDK 提供了诸多功能。例如,您可以使用查询对象来查询表中的数据,如下所示:

var query = table.orderBy('column').read({ success: function(results) { ...
}});

如您所见,代码与任何其他 API 非常相似,因此学习曲线与此处讨论的其他可选方案一样。可以使用任何 Windows 应用商店应用的开发语言访问 SDK 和媒体服务。

应用程序数据管理和存储可选方案

前面说到的所有数据存储和访问可选方案都可以用来存储内容,但是作为开发人员,您还需要处理应用程序的配置数据。这指的是描述应用程序或其设备能力的元数据,而不是用户的数据。新型应用程序会使用持久应用程序数据(如用户首选项)和临时元数据(如用户上次滚动位置或趋势搜索项)。这些小但有效的便利措施确保用户获得尽可能好的体验,因此将它们构建到应用程序中非常重要。

虽然其中的某些数据属于设备,但考虑到很多应用程序跨多个平台和设备工作这一实际情况,将应用程序数据集中于 Windows Azure 并与内容数据同步通常会带来益处。

Windows.Storage 命名空间中的 ApplicationData 类(恰如其名)提供了一组专用于管理应用程序数据的 API,代码如下:

var localSettings = Windows.Storage.ApplicationData.current.localSettings;
var roamingSettings = Windows.Storage.ApplicationData.current.roamingSettings;

您可以在 localSetting 或 roamingSetting 属性中存储简单或复杂对象。

使用本地或漫游设置是处理配置数据的首选方式。 IndexedDB、文件或 SkyDrive 之类的技术通常不是应用程序配置数据的好选择,而 SQLite 只有在应用程序已经使用它来存储内容的情况下才会有意义。 您还必须考虑,应用程序在脱机或与 Internet 断开连接时应该如何使用数据。 换言之,您的某些数据需要缓存,但是不应消耗过多磁盘空间。

内容和配置

总之,为了实现正确的数据体系结构,您不应依赖于便携设备上的有限空间,因此在云中托管数据通常是个好办法。 但是,如果有旧式数据库,则重用该数据库或许不可避免。 针对内容和配置,Windows 应用商店应用支持各种结构化和 BLOB 存储需求。

如果您要构建 Windows 应用商店应用,并希望获得有关如何选择数据访问策略的帮助,强烈建议您了解“新一代应用”(bit.ly/W8GenAppDev) 计划。 “新一代应用”通过提供免费的技术和设计咨询及帮助,以及专门的提示与资源,指导您完成在 30 天内构建 Windows 应用商店(或 Windows Phone)应用的过程。

Get help building your Windows Store app!

Rachel Appel 是 Microsoft 在纽约市的开发推广人员。 您可以通过 rachelappel.com 网站与她联系,或者通过电子邮件 (rachel.appel@microsoft.com)与她联系。 您还可以在 Twitter 上(网址为 twitter.com/rachelappel)留意她的最新更新。

衷心感谢以下技术专家对本文的审阅: Scott KleinMiriam Wallace