When Should I Go Native?
You may think the need to use device features such as GPS play an important factor in deciding if you need to go native. Even then, HTML5 allows you to access GPS and the Camera directly from the browser. If you wrap your App in a container (e.g. Phone Gap or Apache Cordova) you can then get access to pretty much everything else on the device.
In certain cases, however, you have to go native. One of the reasons we went native was to facilitate offline store and sync as well as allowing low level control of connected blue tooth devices. Added to that, the operating environment was not a friendly one and internet connectivity was spotty at best.
Mobile Device Management (MDM)
The first line of defense is the mobile device itself. MDM allows you to enforce security policies, deploy new versions of your Apps, deploy network and device configurations and monitor device activity. It also allows you to erase/shutdown the device should it get lost or stolen.
The next level of defense is the requirement for the iOS device to pass an SSL certificate along with the payload. The firewall was programmed to only allow entry to requests that came along with the certificate attached. This immediately blocks requests from computers and devices that should not have access.
The last line of defense came with ORDS native OAUTH2 support. As the devices were managed by MDM we decided to go with the OAUTH Client Credentials Flow. With this flow, the device itself stores the client ID and Secret which it can use to obtain a token. The token lasts for an hour and must be used to call any of the other web services.
With this approach, we can disable the OAUTH client at any point in time, immediately preventing all future attempts to access the web services. invalidating the client does bring with it the challenge of pushing out a new client Id and secret to all of your devices. This is another reason for having a good MDM solution as it allows you to deploy a new version of the App (with the new credentials embedded) in minutes.
When considering ORDS security you also have to consider exactly which of your ORDS services these Apps will have access to. Privileges in ORDS allow you to tie a specific client / token to a specific set of services. When exposing services outside the firewall, it is especially important that all your services have security enabled. This ensures people don't happen across an un-secured service. You can reduce the risk significantly if your load balancer only allows requests inside the firewall that are routed to a specific ORDS module.
Working with ORDS and Mobile iOS Apps
REST principals suggest that you should create services for each of your resources (e.g. item, customer, order). While I am not advocating straying too far from these principals, sometimes it is much more efficient to create composite services that perform multiple steps in one web service call. An example could be a service which creates a customer and an order in one step.
- Removing complexity and business logic from iOS and place it on the server (i.e. in your PL/SQL logic). If business rules change, you can change them in your PL/SQL logic, without having to re-deploy your App. This is especially important if you are primarily an Oracle shop and don't want to have to call your local iOS developer every time business logic changes.
- Reduces network chatter. This in turn improves user experience, especially if network bandwidth is a challenge (as it was for us).
If you are dealing with multiple languages (which we were), you will need to provide web services that allow the iOS App to pull data translated to the user's current language. This in turn means you must design your tables to facilitate serving up translated values when called on from the web service.
When it comes to translating form labels for the iOS App you will again need to plan ahead. You will get a plain text file from your iOS developer with a dump of the strings contained in the App. It is up you to then take this file and present it to your translators in a format that they can easily translate from.
Managing the Application Lifecycle
While it is relatively easy to deploy your Oracle tables, PL/SQL code and ORDS services between DEV, TEST and PROD, you will also have to consider how you are going to move the iOS App through the application lifecycle. The only way the iOS App has of talking to the server is via web services so you have to let the App know which set of URLs (and which client id and password) it should be using depending on which instance you are currently testing in.
Offline Store and Sync
When providing users the ability to update data on the iPad while disconnected, you are left with the challenge of what to do when updates are posted back to Oracle and the records in Oracle were already updated by someone else. The approach we took was to use a record version number column in each table. GET services obtain the record version when fetching data and the PUT services validate that the version number has not changed when updating changes back to the database. If the version has changed then the update would not be committed, and a message displayed to the iPad user that they would have to fetch a new copy of the data and re-apply their changes. While inconvenient to the end user, it is more important to ensure data consistency.
Monitoring and Trouble Shooting
There are a number of tools out there which will post log messages in the event of a crash on your iOS device. These log messages are posted to a centralized server which you can then inquire on from your browser. We used Crashlytics for our project which worked well for us. You can even enable real-time analytics that help you understand what's happening in your app.
On the ORDS side there are two areas where you can log web service requests. One is the Tomcat logs and the other is based on custom logging in your ORDS Handler logic.
On the Tomcat server, reviewing the Tomcat logs can get you high level information on the volume of requests but does not tell you much about the payloads and the results of these requests.
If you need to know what data was passed to your ORDS services and what responses were returned, you have to add code to your ORDS handlers to log that information to tables in the Oracle database. We built an APEX App on top of these log tables so that we could easily inquire on failed requests and view the payloads sent by the iOS App.