返回博客首页
← 所有文章

使用 NativeScript 和 Kinvey 实现离线功能

2018年11月8日 — 作者:Teodor Bozhikov

正如 Rob Lauer使用 NativeScript 实现离线功能 中所写,在您的移动应用中优雅地处理网络连接中断有多种方法。当您的应用数据存储在云端时,您需要管理云端不可访问时会发生什么……或者不是这样?让我们看看 Progress Kinvey 如何帮助您处理此类情况。

Kinvey

Kinvey 与 Google 的 Firebase 类似,是一个无服务器后端,并提供强大的工具用于存储数据、文件以及与不同数据服务的集成。此外,如果您坚持使用 Progress 产品和支持,那么利用它是一个自然而然的步骤。

离线支持实现

为了能够使用 Kinvey,首先将 kinvey-nativescript-sdk 依赖项包含到您的 NativeScript 项目中。然后,要从特定集合中获取实体,请创建一个 DataStore 对象

private constructionSitesStore = Kinvey.DataStore.collection<any>("ConstructionSites");

请参阅 Kinvey 数据存储文档 以获取更多详细信息。

免费开始使用 Kinvey,请访问 这里

在离线支持方面,Kinvey 有三种操作模式

  • 缓存(默认) - 数据在获取后本地存储,并在随后请求时重复使用。一旦您更新了某些内容,SDK 就会尝试将其持久化到云端。
  • 同步 - 手动将数据的副本拉取到本地,对其进行处理或修改,并在需要时以编程方式将其“同步”到云端。
  • 网络 - SDK 在此模式下不使用任何缓存。而是直接与云端交互。相应地,当离线时,应用将无法与数据交互。

在大多数情况下,默认模式(缓存)可以正常工作。其工作方式是您订阅 find() 查询,订阅者会被调用两次 - 一次是在从本地存储检索数据时,另一次是在从云端获取数据时。

allItems: BehaviorSubject<any> = new BehaviorSubject([]); // we subscribe to this object in some components, thus binding the UI to its updates

updateData() {
    this.ensureLoggedIn().then(() => {
        this.load().subscribe(((constructionSitesRaw: Array<any>) => {
            const allConstructionSites = [];
            constructionSitesRaw.forEach((constructionSiteData: any) => {
                constructionSiteData.id = constructionSiteData._id;
                const constructionSite = new ConstructionSite(constructionSiteData);

                allConstructionSites.push(constructionSite);
            });

            this.allItems.next(allConstructionSites);
        }), (err) => {
            console.log(err);
        });
    });
}

private load(): Observable<Array<any>> {
    const sortByNameQuery = new Kinvey.Query();
    sortByNameQuery.ascending("name");
    const findQuery = this.constructionSitesStore.find(sortByNameQuery);

    this.trackQueryOnlineStatus(findQuery); // pass the query to a service which (based on the result) evaluates whether we are online/offline

    return findQuery;
}

如您在代码中所见,我们有一个方法 trackQueryOnlineStatus,它向一个服务报告在线状态的管理情况。

// subscribes to query results and reports whether it passed OK or failed due to network loss
private trackQueryOnlineStatus(kinveyQuery: Observable<any>) {
    kinveyQuery.subscribe(null,
        (error: Kinvey.BaseError) => {
            console.log("Kinvey error:" + error);
            if (error.message.indexOf("offline") !== -1) { // this error lets us know the issue is connectivity -> report offline status
                this.connectivityStatusService.reportConnectivity(false);
            }
        }, () => { // Called after both sets of data (local and network) have been retrieved -> report online status
            console.log("both sets of data (local and network) have been retrieved");
            this.connectivityStatusService.reportConnectivity(true);
        });
}

connectivityStatusService 本身是一个服务,它结合了 Kinvey 和 NativeScript 核心 connectivity 模块的信息。得益于其 getCurrentStatus() 方法和 statusChangeEvent,所有组件都可以知道应用当前是联机还是离线,并可以相应地更新。

this.statusChangeSubscr = this.connectivityStatusService.statusChangeEvent.subscribe((status) => this.onConnectivityStatusChange(status));
...
onConnectivityStatusChange(newStatus) {
    if (newStatus) {
        this.refreshData();
    }
}

以上代码示例来自新添加的 使用 Kinvey 的离线支持 示例应用。

kinvey nativescript offline sample app

这是一个功能齐全的数据驱动应用,具有离线支持和漂亮的设计。要在 NativeScript Playground 中运行示例应用,您需要

  • 创建一个 Kinvey 应用,并在 ~/shared/config.ts 中将其连接。如果您是初学者,请参阅 文档
  • 在应用中创建一个用户,并在 ~/shared/config.ts 中连接用户和密码。

欢迎查看!