So far I have posted CFMobile examples that were mostly standalone applications (except a photo application that uploaded image to server). However many mobile applications may need to interact with server, for example to show data from a remote database, to modify data or for many other purposes.
CFMobile features in ColdFusion Splendor make accessing remote CF server very easy. I will demonstrate this using a simple example – I will build a mobile app that displays employee records fetched from a remote CF server. The client side (cfclient) code calls a CFC on the server side which fetches data and returns result to the calling page. You will see that creating and accessing a server side CFC is as easy as it is in a completely server side CFML code – you don’t need to worry about writing code to make AJAX calls. cfclient does that for you transparently. I should mention here that this feature to call server CFCs from cfclient is not limited to mobile application, you can even use it for any web application.
Here is a screenshot of the application –
I will start with building the server side application. We need to create a database and a table on the server. I am going to use Embedded Apache Derby database for this application. Using ColdFusion Administrator, you can create both database and datasource for Embedded Apache Derby. Open up the administrator and go to ‘Data & Services’->Data Sources page and add a new data source, called EmployeeDS –
Click Add button, and you will see details page –
Specify database folder and select ‘Create Database’ option. I have created the database in cfusion/db/EmployeeDS folder. Derby database driver creates the last folder, so make sure EmployeeDS folder does not already exist in cfusion/db, otherwise Derby throws error.
We now need to create employee table. I have created a simple cfml file, db_scripts.cfm with functions to create database, list and delete records.
Run this page and it will create employee table with fields id, first_name, last_name and address.
Next I will create a server side CFC, EmployeeDBManager.cfc with two functions – getEmployees and addEmployee –
Note that both the functions are marked remote (because they will be called from a cfclient block).
getEmployee returns Array in JSON format. It returns array of Struct with fields id, fistName, lastName and address.
addEmployee takes Struct argument with the same fields as above, except id. It returns id of the newly added employee.
We are done with the server side code for this application.
In the cfscript block in cfclient, I first instantiate the server side CFC, EmployeeDBManager, and then call getAllEmployees function.
empMgr is a global variable. You can create page level variable also using variables prefix, i.e variables.empMgr.
Notice that you instantiate server CFC from cfclient block just as you would do it in server side code.
In getAllEmployees, I call getEmployees method of the server CFC. But before calling the server CFC, I set callback handler (function) which will be called when server function returns.
If you do not set the callback handler, remote CFC function would be called synchronously, which will block application UI till the CFC function returns. So make sure you set callback handler when invoking remote CFC function from cfclient.
Argument to the callbakc handler is an object with result field. This field actually contains result returned by the remote CFC function. getEmployee function of the CFC returns array (of struct/object), so I iterate over it and call addEmpToHTMLTable function for each employee struct.
There is one more function in the cfscript block of cfclient, to add new employee
addEmployee (in cfclient) takes three arguments – firstName, lastName and city (address). I create a new struct using these arguments and pass it to addEmployee method of the remote CFC (EmployeeDBManager). Here also I set the callback handler because I don’t want call to a server function blocking the application.
addEmployee function on the server side returns id of the new employee. I get this as result field of the argument to callback handler. Then I call addEmpToHTMLTable (see above) to append new employee to the HTML table.
This completes code for the application. You can open index.cfm of the client application in Chrome/Safari and see how the application works. You can also test it on mobile as a standalone application using PhoneGap Shell app that we have built (see links in my earlier post – Simplify Mobile Application Development Using ColdFusion).
However if you package the client application and install it on mobile device, you will find that application does not work – no data is fetched from the server.
When resolving URL of remote CFC in cfclient, the framework tries to resolve it from the URL of the client page. If client page and server CFC are loaded from the same server, which is what happens when you run the application in desktop browser or in the Shell application, cfclient is able to resolve the server CFC. But it cannot resolve it in a packaged application, because the client page is loaded locally from the device and server side CFC does not exist on the device.
To help resolve server CFCs (used in cfclient), you need to provide base URL of the server when packaging the application. You do that by going to project properties (right click the project in the Navigator view of ColdFusion Thunder and select Properties menu option)->ColdFusion Mobile Project-> Miscellaneous page and specifying ‘Application Base URL’
When you right click on the project and select ‘Generate PhoneGap Build’ menu option, the above URL will be used in the generated code to resolve server side CFCs.
You also need to provide access to the external server from your mobile application. To do that, go to PhoneGap tab (in Mobile Project Properties) and click New button. Go to Access page and type IP of the external (CF 11) server or * to allow access to any external server.
Download CFBuilder projects for this application. EmpMobileApp folder in this zip contains client side application and EmpServerApp folder contains server side app. I am not providing Android APK file for this app because my server side CFC will not be accessible from this APK when you install it on you device.
Though I showed you how to access remote database from CFMobile application in this post, the technique is not limited to database access. Server CFC can get data from any source and return to cfclient.
Update : Final build of ColdFusion 11 has a bug because of which access to CFC on the server does not work. To fix this issue, copy cfclient_main.js to wwwroot/CFIDE/cfclient folder of the server. Make sure you keep back-up of the old file before you overwrite it.