The road to my first commercial app

I have been wanting to build an actual app for such a long time. But, I wanted to build something that was not out there yet. Everything I thought of there was at least 2 of in every app store. I just needed to find that one thing that didn't exist yet. Then I finally figured it out.

My family is very active in Taekwondo. My son will be a black belt soon and he is only 7. We were at a tournament a while ago and I noticed that people always wrote down scores on paper. This is because the judges give a score and write it down on their official paperwork but it is not displayed anywhere. It is up to the spectators to keep track of scores as they deem fit. After watching people fumble around doing this I knew there had to be a better way.

I did some investigation and discovered there was no app to do this. This is when I knew I found the app to build.

I then spent about 3 months building a prototype. I showed it a few people and they were very excited about it. I showed it the school owner and he said he had never seen anything like it. I knew at that point that I was on the right track.

With a working (mostly) prototype I went to a tournament to test it out. I ran into a ton of usability issues that made me rethink how the app should work. I also showed it to a few people and the basic reaction was "Where do I get that?".

The next 2 months were spent rebuilding the app from scratch. I started completely over and redesigned about 90% of it. I needed to make the app faster and cleaner to use. After some more feedback and user testing, the app was complete.

Then, I gave it to my 7yr old son. He played with the app for about 10 minutes and found a very critical bug in the app. I managed to use the app in a way that I never intended or foresaw happening. I made the necessary adjustments to the app and then finalized the rest of it.

My initial intent was to just build it for Android. However, my wife convinced me that I really needed to create it for iOS as well. This process was something I was not looking forward to. But I did it anyways. The process was made much easer as I was using PhoneGap and PhoneGap Build to create the app.

I had to make a few changes to the app so it would work correctly and look right on iOS but it was all minor. If I recall it only took a day to make the adjustments. In the end I was glad that the wife pushed me to do it.

Ultimately I have my first comercial app on the app stores. I think my son is more excited then I am.

You can check it out here...

iOS: Tournament Scorecard

Google Play: Tournament Scorecard

Amazon: Tournament Scorecard

Till next time,

--Dave

Speaking at cf.Objective() 2013

I honored once again to be speaking at cf.Objective(). This year I am privileged enough to have two proposals selected. The ones selected are...

  • My SQL Skills Killed the Server .. This session is all about writing better SQL.
  • Fuse All the Greatness - Combining Charts, Websockets, and Scheduled Tasks to Present Realtime Data .. Long title that pretty much says it all.

I look forward to seeing you all the conference.

Till next time,

--Dave

ColdFusion Platform Survey

Take a quick moment out of your day and fill out this survey. Let Adobe know what production platforms you are running ColdFusion on.

https://www.surveymonkey.com/s/HMQG62Y

Till next time...

--Dave

ColdFusion 10 Scheduled tasks and misfires

In the event that you missed the changes in ColdFusion 10, I will recap one of them. The scheduled task engine was replaced with the Quartz Job Scheduler. This fancy new scheduler comes with more features then you will probably ever use. There are now handlers for when tasks start, finish, and error. Tasks can now call other tasks when they finish. You can even define rules for when a task fails or fails to start on-time.

There is also greater control on when tasks run. You can now schedule tasks to run faster than every 60 seconds. You can also use crontime to schedule a task. For example, this... "0 23 ? * MON-FRI" states to run a task every weekday at 23:00:00. You could even do something crazy like this "2-59/3 1,9,22 11-26 1-6 ? 2003" which translates into "In 2003 on the 11th to 26th of each month from January to June every third minute starting from 2 past 1am, 9am and 10pm".

But in creating crazy schedules or faster run times you now run into another feature of the new scheduled task engine, misfires. Misfires are a fancy name for a task that didn't start when it should have. For example, if the task was scheduled to start at 10:00:00 and it is now 10:00:01 and the task has not started it is now considered misfired.

Missing the start time is just one of a few reasons a task can misfire. Some of the others are, the scheduler engine is down, there were no available worker threads, or a task was configured to start in the past. You can also generate a misfire by resuming a paused task. By default the scheduler uses a "smart policy" to handle misfires.

[More]

Real-world Testing your Application

A couple months ago, at the time of writing this, I noticed there was a need for a mobile app. The app was very targeted to a group of people and an organization. After talking with a few people about my idea I decide that the need for this target group was large enough that I should go ahead with building the app.

The app in question is for spectators to record the scores given by judges as an ATA event. Currently people just write them down on paper and keep track there. The scoring is a fairly simple 3 judge scoring system. The problem for the spectators is that there is no score board for them view.

I am using jQuery Mobile, and PhoneGap to build the app. I have build a bunch of things with these tools before but mostly for fun. This will be the first commercial type app, that will go into the app stores, that has my name on it.

Over the course of the next couple months I made a few UI designs and floated those around. I received feedback and took parts of each one and created the final UI prototype. After checking with some people I went ahead and started building the app.

It took about a month to build the app from the UI mockups to a working, but crude, pro to type. I again enlisted feedback from some people and got more great feedback. I then continued to build the app out to a more alpha level and it worked as well as expected. I also finalized the features list for the first release. All that was left was to test it in the real world.

My real world testing would let me know a lot of things. Most importantly, if my design would hold up under real world conditions. I could also show the app to people outside my testing group and get some feedback.

The people that I showed it to were excited that someone was finally filling the void. Most of them had been looking for something like it for a long time but found nothing. They all asked the same basic question, when will it be available.

I didn't let anyone play with the app so all they had to go on was what I showed them. At this point I have at least gotten past my first problem. There is a need for it and people will want it. This got me excited as I felt I was on the right track.

[More]

New source for learning ColdFusion

A new source for getting your ColdFusion learning on has been launched. Learn CF in a Week will guild you through all the major aspects of the ColdFusion language and get you writing your own application in a week.

I think one of the best parts about this is how it was done. This course was not created in a vacuum buy a bunch of marketing people. It was actually created by experts in the community that live and breath this stuff every day.

So, if you are new to ColdFusion, or just want to expand what you know already, check it out.

Till next time,

--Dave

Websockets and the vanishing scopes, Part 2

Yesterday I blogged about an issue I was having with Websockets and scopes vanishing. After some comments to the post and subsequent messages on the FW\1 Google group I decided to do a little more testing. I was trying to see under what condition were the scopes being lost.

Initial test.

First step was to have an application.cfc setup with a websocket channel.

Application.cfc content:

view plain print about
1component {
2    
3    this.name = "wstesting";
4    this.wschannels = [{name:"wstest"}];
5    this.sessionmanagement = true;
6    this.sessiontimeout = CreateTimeSpan(0,2,0,0);
7    
8}

Next up is the cfm files. These 2 blocks of code would go into separate files.

First the file to receive messages (receive.cfm):

view plain print about
1<script language="JavaScript">
2    function myHandler(msg){
3        console.dir(msg);
4    }    
5    
6</script>
7<cfwebsocket name="myws" onmessage="myHandler" subscribeto="wstest">

Then the file to send a message (send.cfm):

view plain print about
1<cfscript>
2    writeDump(var: cgi, label: 'cgi before');
3    writeDump(var: session, label: 'session before');
4    wsPublish("wstest",'my message');
5    writeOutput("<hr>");
6    writeDump(var: cgi, label: 'cgi before');
7    writeDump(var: session, label: 'session before');
8
</cfscript>

So, to set it all up. Create the 3 files. First call the receive.cfm in a browser. Then in a new browser window call the send.cfm.

What you should see is that the session dumps are the same before and after. However, the cgi dump is different. The cgi dump is all based of the wspublish call and not the original request. However, the session scope is left untouched.

Now, lets make some modifications to do the same test inside a Framework One application. If you are unfamiliar with FW\1 then some of this may not make sense. But if you are you should be able to follow along.

First, modify the the application.cfc to extend the framework. Also, add a before and after function to the app.cfc that contain the scope dumps.

view plain print about
1function before( rc ) {
2    writeDump(var: request, label: 'request before');
3    writeDump(var: cgi, label: 'cgi before');
4    writeDump(var: session, label: 'session before');
5}
6    
7    
8function after ( rc ) {
9    writeDump(var: request, label: 'request after');
10    writeDump(var: cgi, label: 'cgi after');
11    writeDump(var: session, label: 'session after');            
12}

Next create a view for the send and receive. In the receive put in the same code as the first example. The send view can be an empty file.

In the controller that would be called for the send just do a simple wspublish.

view plain print about
1public void function send( rc ) {
2    wsPublish("wstest", 'something');
3}

Now, that you have all that setup lets run the code. Just like before, first call the receive code. You should see 6 dumps that all mirror each other. Next call the send. This should throw an error. You should have 5 dumps and then the error. Take careful note of the dumps. The request dump in the after is all but gone except for one value. The CGI scope is redone just like the first example.

Now the odd part. The error that is thrown should state that "Variable SESSION is undefined."

For fun, go into the controller and remove the wspublish line. Then call the send again. This time the dumps should all work without error.

So there you go. While this doesn't correct the issue it at least gives more insite as to what is going on.

Till next time...

--Dave

Websockets and the vanishing scopes

I have been working on a new application in FW\1. This application has a messaging aspect to it that sends alerts to users. The alerts can be either on screen, email, or a websocket message. When I went to start adding the websocket parts I started running into strange errors.

First, I was getting the following error after sending a websocket message and trying to do a redirect in FW\1.

The code looks like this (just a couple relevant parts)

view plain print about
1getmessengerService().sendMessage(message: "Message goes here", type: "error", delivery: 2);
2variables.fw.redirect('home:main.default', "displayMessage");

Original exception in onRequest
Cannot lock session scope.
Cannot use cflock to lock the application or session shared scopes without these scopes using the cfapplication tag. To use the session scope, you must enable session management. Application and/or Session variables must also be enabled in the ColdFusion Administrator. (Lock)

This struck me as odd because on refresh, I still had a session and was still logged in. I checked the redirect code and removed the preserve item (2nd argument) and tried again. This time I received a different error:

File not found: /Users/dferguson/Documents/Development/nfmtools/common/config/handler.cfc/Users/dferguson/Documents/Development/nfmtools/common/config/handler.cfc

Now I was totally lost. The redirect was going to a very odd place. However, the odd place it was going to was to not as odd as it seems. It was the defined handler for the websocket channel. So, I then decided to take out the handler and see how that would affect it. I now received this error:

File not found: /Applications/ColdFusion10/cfusion/wwwroot/CFIDE/websocket/ChannelListener.cfc/Applications/ColdFusion10/cfusion/wwwroot/CFIDE/websocket/ChannelListener.cfc

This is the default system handler for websockets. So, now I am totally confused and resting my head on my desk... over and over. I can't seem to get around these errors. Also, if I take out the wspublish() code everything works just fine. I even went as far as to put an application.cfc file in the directory with the handler to see if that did anything. Well... it didn't.

At this point I went in and started using the line debugger. If you have never used this tool then you are missing out. Instead of putting dumps and traces in your code you can actually watch the path that CF it taking through the code and what vars are being set. You can also see what is being passed to functions. So, I added a few breakpoints and ran the debugger.

[More]

RIACon 2012 is almost here

The title says it all. In just under a week RIACon will be upon us. I am very excited to be attending the conference this year. It is one of the conferences I have yet to get to. Not only am I going to attend, I will also be speaking this year. My session will be covering Websockets in ColdFusion 10.

Websockets is probably one of the most underrated HTML5 features. Forms, Canvas, and Video seem to get all the HTML5 press. But, once you start using websockets you will start to think of ways to add it into your applications. They are super easy to implement but can become very powerful.

Then, if all that wasn't enough some big conference news came out this week. First off, I know I am a terrible spy, so keeping this to myself for a few days totally sucked. It was announced that there will be a panel discussion. The panel is titled.. "Developing for the Future: A Community Panel Discussion hosted by CFHour". Scott and myself will be moderating a panel to discuss current and future development trends. If you are going to the conference you will want to come to this. If you were thinking of going this should push you over the edge and make you want to be there.

http://riacon.com/content/developing-future-community-panel-discussion-hosted-cfhour

The list of panel members is very impressive. The list includes...

Kelly Brown
Chief Technology Officer - AboutWeb

Gert Franz
Chief Executive Officer - Railo Technologies

Adam Lehman
Sr. Product Manager for Interactive Development - PhoneGap/Adobe

Joe Rinehart
Lead Associate - Booz Allen Hamilton

Todd Sharp
Associate - Booz Allen Hamilton

On a more personal note. I am very honored that we (CFHour) were chosen to moderate the panel. A big thank you goes out to Phill "From Brazil" Nacelli and the rest of those involved in the conference. I am excited to be a part of this event and am looking forward to it.

See you at RIACon.

Till next time...

--Dave

ColdFusion Developer Week Recordings

So, you missed one of the ColdFusion Developer week presentations? Fear not... all the sessions were recorded. You can view them all here... http://www.adobe.com/devnet/coldfusion/events.html.

Most, if not all, of the presenters have posted their slides and demo code as well. Unfortunately, the Adobe site doesn't list those. You might want to check the respective presenters blogs or use Google to find them.

till next time,

--Dave

Previous Entries / More Entries