Let’s consider the necessities, starting with data.
The boss is calling (again!). She's holding your feet to the fire to get that mobile web app out the door, so it's time to roll up your sleeves and get to work. Where to start? Why not start with the list of requirements?
Application requirements:
- Real-time access to IBM i data and local storage when no mobile connectivity is available
- Ability to take pictures, store them on the device, and upload them
- Ability to retrieve and store geolocation information
- Ability to record audio for taking "audio notes"
We might as well get the spinach eaten before the ice cream and deal with the "bulk" of the application: getting data. We have two things to consider here:
- Getting data from DB2 on IBM i
- Having access to that data when there isn't a connection available
Getting Data from DB2 on IBM i
Requirement 1 really isn't all that difficult. Since you're going to build an HTML5 web application rather than a native application, you'll be relying primarily on AJAX calls to a program on your IBM i to return data to your app. But, without a connection, how will you handle the display of the web pages and retrieval of the data? The answer is local storage and a cache manifest.
So let's organize this a bit. First, if we're going to get data from the IBM i, the simplest solution in the web world is to access that data asynchronously rather than using a direct connection. If we use AJAX to make the call, then that will take care of the asynchronous part, but returning the data becomes the next hurdle. We could return the data in any number of ways, but because JSON can be used to render the data as an object in JavaScript, we might as well speak the "local lingo" and use a format that JavaScript can easily use. JSON is an acronym for JavaScript Object Notation. JSON has been around for years and is becoming the standard for data interchange for web applications.
There's another advantage to using JSON: It's just a string of text. Text is easy to store and manipulate. It also tends to be more "readable," so diagnosing issues can become quite easy: Just copy it to a text editor and take a look, or use a "linting" service like jsonlint.com that can parse and validate your JSON string. No binary or hex values to decipher! There's yet another advantage as well: local storage, a mechanism present in most modern browsers, can easily store text. So our initial plan is to create programs on our IBM i that retrieve the data and format it as JSON string and return it to our web app, and just to be on the safe side, when we return that JSON data, we'll store it in the browser's local storage.
So let's take a look at a JSON string returned by our database record retrieval program on the IBM i. To keep it simple, we'll look at a customer record. A pseudo-coded JSON string might be as shown below.
Note: Curly braces ({}) in JavaScript indicate an object, so a customer JSON record might be something like this:
{
"ID": 1,
"Name": "Acme anvil company",
"Addr1": "123 East Main Street",
"City": "Smalltown",
"State": "TX",
"Zip": 78787
}
But we'll have more than just one customer record and other records as well. How best to store multiple records in a string? An array of course! So our JSON is looking a little more complex as we go:
{
''customers'':
[
{customer 1},
{customer 2},
{customer 3},
….
]
}
Now we have an object ({}) that contains another object (an array called 'customers' []), which is an array of customer objects. (Hence the initial curly braces and then the "customer" [{},{},{},...}] notation. You should quickly see that this format can be easily extended to contain objects within objects within objects (and can quickly get confusing). So I recommend that you walk before you run and try just a couple of simple records and formats first.
How do you store it? It couldn't be simpler. Use the localStorage object in the browser. Just like JSON, local storage consists of a name:value pair. So if we were going to create a local storage object to store our customer data, we would first create the data and then assign it to local storage. Again, some pseudo-code, shown below.
An AJAX call to IBM i returns a JSON (text) object (or a full array of objects):
var data =
[
{customer 1},
{customer 2},
{customer 3},
….
]
The variable data now contains our array of customer objects, so just assign that to local storage:
localStorage.setItem(''customers'':data);
Nice! If we need to get the data from local storage, then we can assign it to a variable, like so:
var data = localStorage.getItem(''customers'');
Now data will contain our array of customer objects!
The real work is in managing the data in local storage. You'll need to get proficient at locating, updating, inserting, and deleting array data, but once you have a library of those functions, it will be as easy as calling updateCustomerData and passing in your customer object.
Access to IBM i When There Isn't a Connection Available
So we've handled the grunt work of retrieving the data and storing a copy of it locally in case we need it. But how do we know when we need to switch to "local mode"? That's where some network awareness would come in handy. There's a JavaScript library (offline.js) that can do the heavy lifting, or you could just write an error routine in your AJAX call that switches to the local storage repository for data if a call to your IBM i fails. There's a navigator.onLine property that can be monitored but tends to be unreliable, so having a fallback (or two) is helpful when dealing with network connection events.
So our logic is this: Whenever we make a round trip to the server for data, we not only retrieve and display the data, but also maintain a local copy of the data in local storage. We can either rely on a strategy of pulling everything we could possibly need into the local database or we could just store the items we retrieve, essentially caching them for future use. Should we encounter a network interruption, we can temporarily grab data locally until the network connection is available.
Caching Web Pages
With the data access issues resolved, we still have one remaining issue: If we don't have access to the server for data, we also don't have access to the server to serve our web pages to us. How do we handle that? The solution is to use a manifest file to tell the browser to cache the pages and resources locally. This is similar to the way that browsers cache pages and web artifacts but is more explicit in holding those resources locally. When offline, a user's browser can't reach the server to get any files that might be needed. You can't rely on the browser's cache to include the needed resources because the cache could have been cleared in a variety of ways. This is why you need to define explicitly which files must be stored so that all needed files and resources are available when the user goes offline: HTML, CSS, JavaScript files, and other resources, such as images and even video.
The manifest file is specified in the HTML form and contains the list of files that should be explicitly cached for offline use by your app.
<html manifest="cache.manifest">
Here's an example of the contents of a manifest file:
CACHE MANIFEST
# version 1
css/main.css
css/fonts.css
img/images.gif
js/main.js
index.html
The manifest file can be any name and should be downloaded from the server with a mime type of "text/cache-manifest." CACHE MANIFEST needs to be the first line of the file. It's a good idea to include a version number so that the files in the cache can be updated as needed. Even though the "version 1" is a comment, if you change the manifest file by changing the comment to # version 1.01, just the change alone is enough to force a refresh of the cached contents. So, all you need to do is to introduce any change to the manifest file to force all the referenced files to refresh. Using a "version" number and updating it is a great way to track changes and force updates.
Now you have completed the first requirement and your web app will look very "native" with the local storage and local caching of the data and the web resources.
Your next challenge will be the ability to take pictures with a mobile device, store them locally, and push them to your IBM i. Yet another item to get done before the boss calls again.
LATEST COMMENTS
MC Press Online