I am back to writing blog after a gap of nearly two months. Past few weeks had been very busy working on new features of ColdFusion and creating a mobile app for CFSummit2013 . I along with my colleagues Asha and Rakshith had been working on this app for nearly a month, though not necessarily full time. There were two main reasons for building the app 1. to use mobile features of next ColdFusion releases to provide feedback and catch bugs 2. to create a useful app for the attendees of CFSummit.
I don’t know if attendees would find the app useful (I certainly hope so), but we were able to provide a lot of valuable feedback on ColdFusion mobile features and catch many bugs. The application took more time than it should have, because the mobile features of ColdFusion were still under developement. We would hit a bug and would have to wait (if it was a blocking issue) till it got fixed. In many case we did try to work around issues. But the whole process took a lot more time.
But this post is not about mobile features of ColdFusion and how they were used in the CFSummit app. I am going to talk about my experience in creating HTML5 UI for this app, the issues we faced and lessons learnt. Some of the UI issues are still unresolved.
Implementing ‘dynamic image map’
Initially I thought of using image map. The problem was that the same image would stretch to different sizes on different devices, so the fixed image map was not going to work. I looked for options for dynamic image maps on the web and found a couple of solutions. But when I tried them, they did not work as expected (or quite possibly I did not use them correctly).
UI Event handling issue in Android
I used two banner images at the botom, only one visible at a time. One image with back and home option images and one without. Initially we allowed orientation of the app to change when device orientation was changed, but later we made the application orientation fixed to potrait.
When the device orientation changes, the size of the banner image also changes and I had to calculate image maps again (for back and home options) and attach event handlers. I was not removing old event handlers. This caused problems in Android. The back option worked very inconsistently, because multiple event handlers were fired. However this worked fine in Desktop and iOS devices.
Once I removed old event handlers, before attaching new ones, then touch events worked fine in Android.This made sense (removing old event handlers), but I was surprised that it did not cause any issues in iOS or desktop Chrome browser.
Difference in ‘orientationchange’ event handling in Android and iOS
As the name suggest ‘orienttionchange’ event is fired when orientation of the device is changed. However if you try to get width and height of the window in this event handler in Android, you will find that you get sizes before orientation was changed. This event handler is called in Android before updating width and height of the window. However iOS calls this handler after updating the window size. If you want to get window size after orientation is changed, then you might want to handle resize event.
Fullscreen mode in iOS
Initially the app was configured to run in full screen mode. In this mode the app takes up all the screen area, including the area of OS status bar. This mode was not set intentioanlly, it was caused by accepting some default build options in the CFBuilder. But even though in iOS the app takes up the full screen, iOS still showed time at the top center, which overlapped text in the application header. On the other hand, Android displayed the app correctly by hiding status bar completely.
We have re-built the application by removing full-screen mode and that version is now available for Android in Google Play store. We have submitted iOS version of the app to App Store and it is still under review at the time of writing.
There are still some un-resolved UI issues in the application –
Virtual keyboard overlapping input field
There is a comment input field in ‘Session Surveys’ page. This was the last field in the page, at the bottom. Whenever the field used to get focus for text input, the OS would pop-up virtual keyboard, which moved the screen upwards. The problem we faced in this app was that we have fixed banner at the bottom of the app. This banner image used to cover the comment text filed when virtual keyboard was displayed. This happened consistently in Android and not so consistently in iOS. iPhone simulator and iPad displayed the correct behavior by make sure input field was moved sufficiently up so that it is not blocked. But some of the users reported the issue on iPhone (with iOS 7).
I tried to fix this by removing css properties that made banner image fixed, when the virtual keyboard was displayed. This worked fine in Android, but iOS did not restore the layout correctly after keyboard was hidden. Since there was not much time to investigate the issue, fix it and make it avilable on the stores, I took an easy way out and moved the comment filed to the top. Android version of the app with change is updated on the store. iOS version is awiating review.
Scrolling issues in Div in iOS
Many users complained that scrolling did not feel native in the app in iOS. When you swipe the screen upwards, the page is expected to scroll fast. This worked fine in Android, but not in iOS. Number of solutions were suggested to fix this issue, like setting CSS property -webkit-overflow-scrolling: touch, or using libraries like iScroll4 , but none of the solutions I tried solved this issue.
By the way, though scorlling worked perfectly fine in the recent Android versions (4.0 and above), it did not wotk at all in Android 2.3. Aparently scrolling in div with CSS attribute “overflow:auto/scroll” does not work in older Android versions. So we set minimum suported version of Android for this app to be 4.0 (ICS).
Splash image in iOS
iOS and Android allow you to display a splash image at the starting of your app. You need to specify image name and duration in the config files. PhoneGap build allows you to set these paramters in the config.xml as follows –
<gap:splash src=”splash.png” />
<preference name=”splash-screen-duration” value=””/>
I did want to display a splash screen, but not for a fixed duration. When the app is launched first time, it executes one-time initialization code and I wanted the splash screen on till all the initialization was complete. I did not want to specify fixed duration for the splash screen. So I set splash screen duration to 0 in config.xml and expected that the OS would not display it. This worked in Android, but not in iOS. iOS still displayed a default PhoneGap splash image. Even calling navigator.splashscreen.hide() did not work for me.
I then specified splash screen image in config,.xml (because I did not wan to display default splash image) and set duration to a very low number. This again did not work. iOS did not take the splash image that I had specified and displayed a white screen instead before launching the app. App store also rejected the build giving ‘Invalid Binary’ error. The reason for this error, as per mail received from iTunes Store, was this –
” iPhone 5 Optimization Requirement – Your binary is not optimized for iPhone 5. New iPhone apps and app updates submitted targeting iOS 6 and above must support the 4-inch display on iPhone 5 and must include a launch image with the -568h size modifier immediately following the <basename> portion of the launch image’s filename”
Later I found that you need to follow certain naming convention for the splash image in iOS, as described in this link. But it was too late to make these changes and make a new build avilable in the App store. So you will still see the default PhoneGap splash image for this app in iOS.
Inspite of all above issues, it was fun building this application. It was most satisfying to use new mobile features of ColdFusion that we have been working on, and see that they made many apsects of developing this mobile application easier.