This is a follow-up post on "Source code of CFSummit2013 mobile application" . There has been a lot of discussion in the comments of that post, as well as on a number of social media channels. I saw that some of the reactions were based on incomplete understanding of these features.
But first things first - Mobile features in Splendor and Thunder are specifically targeted for mobile application development. If you are not doing any mobile development or do not plan to do so in the near future, then these features may not appeal to you.
ColdFusion Mobile features are not just about cfclient
A lost of discussion is happening around cfclient. It is being assumed that this is a complete feature. Well, it is not. It is a part of overall mobile development features of Splendor and Thunder. These features can be categorized in four broad areas -
Writing mobile specific code. This is where cfclient plays a major part. You write code in CFML and our framework translates it to JS. I will come to why we had to implement this later.
CFBuilder also plays part in this by providing wizards for mobile projects, code assist for APIs and other editor features (like code hyperlink, code navigation, outline etc.).
If you have done HTML5 mobile development then you would know how difficult it is to debug HTML5 code running on a device (or for that matter in emulators/simulators). You either end up putting alerts in the code or run it with Ripple emulator and debug using Chrome debugger.
But many times you would want to debug the code that is running on an actual device. There are no easy solutions available currently. We are trying to address this by providing a step debugger for the code written in cfclient. You can set breakpoints in CFBuilder, step though the code and inspect variables. Again, all this works on HTML5 code running on devices (or emulators).
This is not possible only with CFBuilder. Server play a very important part of preparing code for debugging.
Weinre is a great tool for inspecting DOM. But it is not just useful for inspecting DOM. I find it very useful to see JS console log messages of an application running on a device. When an error occurs in JS code in an application running on a device, it is very difficult to see log messages. With Weinre you can do that. You can also inspect content of databases of an application running on a device using Weinre. All of this is useful for debugging too.
But Weinre requires you to inject JS code in every page. Splendor will be shipped with Weinre, which can be started/stopped from the administrator. It makes using Weinre very easy.
Both server and CFBuilder play part in injecting the JS code required for Weinre inspection. You can easily turn this on/off.
When your mobile project is ready for uploading to app stores, or directly on devices, you would want to package it first. You can very easily do that from CFBuilder by right clicking mobile project and selecting an option to package it. Of course you would have to configure a few things before you do that. But the process is very simple. We integrate with PhoneGap Build for packaging.
Again, CFBuilder and server work together to perform packaging. If cannot be done only in CFBuilder.
So, we are tageting all aspects of mobile application development with these features.
Why cfclient is necessary
This is the question many seem to be asking. Why we could not have just created JS libraries or provide REST Services? or Why we couldn't just create server side custom tags to implement these features?
I will try to explain here why cfclient is required. But before that please understand that mobile features are also targeted for developing stand-alone mobile applications. You can categorize mobile applications as stand-alone (where code is executed on the mobile, but it might interact with servers for data or services) and web application (where pages are loaded from the server). I am not going to talk about native code, because that is not what we are targeting in ColdFusion.
Mobile device can only execute HTML and JS (again I am going to ignore native development here). If you are developing mobile web application, then the server will generate HTML and JS code, just as CF generates HTML/JS output from CFML. But when you are creating standalone mobile app, CFML code is not going to work, unless you convert it to HTML and JS. That is what Splendor does - it takes all the code inside cfclient tag and generates JS code out of it.
HTML5 mobile application development is largely asynchronous in nature, if you want to access device APIs, like client side database, camera, contacts, device file system etc. PhoneGap is a popular cross platform framework to write mobile applications that require access to device APIs. If you look at PhoneGap documentation, you will realize that most APIs are asynchronous - the way you write code is not sequential. You call an API function, provide success and error callback handlers. If operation is successful, then success callback handler is called, which is where you will write follow up code.
ColdFusion developers, or for that matter many non-CF developers, are used to writing sequential code - except when a call is made from client to server. In the later case you don't know how long server will take to respond, so you don't want to block the UI of you application. So you call server function asynchronously. But device APIs are all executed locally and in most cases need to be called sequentially. Using asynchronous programming in such cases makes code difficult to read and maintain.
Let's take an example. CFSummit application reads session data from a file and populates local database. You can see this code in db_manager.cfc and sessions_mgr.cfc file in the source code.
I will take a small sub-set of this application and simplify it a bit. Let's say we want to create 'sessions' table, insert records into it and then fetch records. Fetching the same records from the table after inserting them may not make much sense, but you can imagine any other database operation like inserting or fetching speaker data.
If you have to do this entirely in JS, you might write the code something like this (I am trying to follow same code structure as in PhoneGap documentation here )
We wanted to simplify this. It would be much better if we could call device APIs one after the other, without chaining call back handlers. This could be done only be re-writing JS the code.
So that is why we implemented cfclient. Write mobile application code just as you would write desktop web applications using CFML (but adding device APIs to it) and we will take care of converting that to JS. This will make your mobile application code easy to write, read and maintain. The same above code could be written in cfclient as follows -
As you can see, the above code is much easier to write, understand and maintain that equivalent JS code. And note that above code also generates asynchronous code - UI is not blocked.
Do you think creating JS library and REST calls to the server could do this? I don't think so.
Are we making CFML ugly?
This is another criticism I have seen about our mobile features. How are we making CFML ugly? We are not changing any syntax. Yes, there are a few deviations from server side CFML, but for the large part it is the same CFML that you are used to writing on the server side.
One of the criticisms about source code of CFSummit app was with this statement -
This statement was in a page, which called many custom tags. It made sense to write the entire code in the same style.
Concerns regarding we may not do a good job of implementing these features are valid, but we are working very hard towards getting these features right.
So, after reading this post, I hope you take away following key points -
- Mobile features in Splendor and Thunder are specifically targeted for CFML developers, who want to create mobile applications
- cfclient is not an entire solution/feature, but part of larger solution/feature which involves support for developing, debugging, testing and packaging mobile applications.
- cfclient is not a wrapper for any JS library.