As Rob Lauer already did write on Going Offline with NativeScript, there are multiple ways of handling lack of Internet connectivity gracefully in your mobile app. When your app's data is stored in the cloud, it is up to you to manage what happens when the cloud is unreachable...or is it? Let's see how Progress Kinvey can help you handle such situations.
Like Google's Firebase, Kinvey is a serverless backend and offers great tooling for storing data, files, and integration with different data services. Besides, if you are sticking to Progress products and support, it is a natural step to take advantage of it.
To be able to work with Kinvey, in the first place include the kinvey-nativescript-sdk
dependency into your NativeScript project. Then, to get entities from a particular collection create a DataStore
object:
private constructionSitesStore = Kinvey.DataStore.collection<any>("ConstructionSites");
Refer the Kinvey Data Store documentation for more detailed information.
Start with Kinvey for free here!
In terms of offline support, there are three modes in which Kinvey operates:
The default one (Cache) will work just fine in most cases. The way it works is you subscribe to a find()
query, and the subscriber is called twice - when the data is retrieved from the local storage, and second time when it comes from the cloud:
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;
}
As you see in the code, we have a method trackQueryOnlineStatus
which reports to a service for managing the online status:
// 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);
});
}
On its own, the connectivityStatusService
is a service that combines information from both Kinvey and NativeScript core's connectivity
module. Thanks to its getCurrentStatus()
method and statusChangeEvent
, all components can be aware if the app is currently online or offline and can update accordingly:
this.statusChangeSubscr = this.connectivityStatusService.statusChangeEvent.subscribe((status) => this.onConnectivityStatusChange(status));
...
onConnectivityStatusChange(newStatus) {
if (newStatus) {
this.refreshData();
}
}
The above code samples are from the newly added Offline Support using Kinvey sample app:
It is a fully working data-driven app with offline support and nice design. To run the sample app in the NativeScript Playground you need to:
~/shared/config.ts
. Refer to the docs if you are getting started.~/shared/config.ts
Feel free to check it out!