So you want to build a mobile app? Not all mobile apps are created equally

Most smartphones users I know ditch apps pretty quickly if they don’t work or end up being clunky. So, if your company is considering offering mobile apps to your customers you should be aware of a few things.

Buy a Smartphone. If you don’t already have a smartphone then you should go out and buy one. Then download a number of apps that interest you and try them out and see what you like and what you don’t like. For example, if you do the shopping for your family you might consider trying out a bar code scanner app that lets you compare pricing. Some scanner apps may work faster than others. If you don’t own a smartphone then you won’t be able to understand what a good app is.

Likes and Dislikes. Pay close attention to what you like and don’t like about a particular app. Here are a few questions to take note of:

  • Was it easy to use?
  • Did it hang and/or crash?
  • Did it perform its tasks gracefully?
  • Did it do what you expected?
  • Was it visually appealing?

Become Tech Savvy. Become a bit more tech savvy about things that the phone is doing behind the scene. There are apps that do this for both Android and iPhone that help you monitor what’s going one. Things to look out for:

  • Apps that keep running even after you think you shut them off. These will run the battery down faster.
  • Apps that consume more and more memory over time. Using more memory equals more battery usage and shorter time between charges.
  • Apps that seem to slow your phone down when they run. These apps may be using more CPU than necessary resulting in greater battery usage.
  • Apps that connect to the internet frequently costing you extra data charges. There are apps that let you monitor how much data your phone uses and some apps can help pinpoint which apps use the most data.

Which Phones to Support? Understand what devices to support. If you are building an application for internal use, then you have an easier decision since you hopefully have some control over which devices are being used and how often their software gets updated. If you work in retail, your users may have Androids, Blackberries, iPhones, iPads, Kindle’s, Nook’s and possibly other tablets that get updated whenever and however the customer dictates. My advice is do some research and pick one that is used the most and work on that first.

Release Early and Iterate Often. Technology changes so quickly these days that if your app takes more than 3 – 6 months to build, then the technology will change underneath you. In other words, you might be releasing an application that doesn’t work perfectly with the latest phone operating systems or browsers that your customers are using. When that happens, it will cost you even more time and money to fix the problem and the problem will repeat itself. Be sure to take into account the speed at which technology will change once you begin your software development process.

Go Native, Go Web Browser, or Both? Last, it’s important to understand that there are two common types of mobile applications. Native apps are downloaded from an app store and installed directly on the phone, the other is a web app that runs in the phones web browser. My advice is to research and understand your target market. What do your competitors use? What do your customers prefer? What are the trends in your industry?

If you go with native apps, you’ll need to understand which phones to support and how often you will be updating the app. If you choose web apps you’ll need to know which browsers to support. Also take into consideration which skill sets your development team has and understand if they can tackle the project or if you need outside help.

Update, Update, Update. No matter what you decide, you can’t just deploy an app and think you’re done. If you want to keep your customers happy, you’re going to have to keep updating the app until the product line is discontinued or replaced. And, you have to update it often enough to stay on top of the latest technologies. New smartphone models are being released all the time and they all may have different screen sizes and screen resolutions. An app that looks good at one screen size may look horrible on a tablet or iPad. These things have to be accounted for. And, the smartphones operating system software may be updated three or more times per year offering new functionality and fixing bugs. If your customers download a broken app, or if they see the app that hasn’t been updated in a while and something stops working they may not be your customers for much longer. This is especially true for retail apps where customers make split second decisions whether to stay or walk away and try something else.

Conclusion. I hope you find this list useful and at least give you some ideas to think about before you dive head first into bringing a new mobile application into the world. It can be fun, be there is a lot of hard work involved. But, if you plan it right you’ll be successful and learn alot in the process!

State of the Internet Browser 2012 – consumer browser usage will decrease

Over the next two years I see consumer browser usage decreasing and people will increasingly spend more time using native mobile applications. This has a number of interesting implications.

The facts. As a web application developer I pay close attention to browser and browser-related technology usage statistics and trends. Like most people, I judge statistics based on my own experience and the experience of my co-workers, family and peers.  Here are some trends which I’ve been keeping an eye on:

  • Smartphones are rapidly replacing non-smart phones around the world.
  • The number of specialized smartphone applications is continuing to expand.*
  • The number of games for smartphones continues to grow rapidly.**
  • The amount of time people spend on their smartphone, whether it’s playing games or using specialized applications, is increasing.

Also based on my personal experience are the following additional observations that further tilt the balance in favor of native applications:

  • Performance. Native smartphone applications, when built correctly, almost always outperform web applications: I’m referring to actions such as page refresh, general drawing capabilities and to a lesser degree but still a factor is the look-and-feel. This is a general fact of application technology: compiled applications perform faster than interpreted applications. For the most part, once I’ve used a native application, such as Southwest Airlines check-in app, I loathe having to use their web page. It just seems so clunky and slow in comparison.
  • Games. Ah yes, we can’t forget game performance as well as their look-and-feel. Why would I want a mobile browser-based game? What’s the point of building a high-performance, beautiful user interface game in a browser? See my previous bullet’s comment about compiled application performance. Yes, yes, yes I know that HTML 5 is making big strides, but we are talking mobile applications and the technology as it exist today. You can’t tell your customers that they’ll have to wait another year for better game performance, because by then your favorite browser will have such and such HTML 5 functionality figured out. Your competitors would jump right in, tweak their native app and leave you in the dust!

A Corollary. If you generally agree with my bullets above, the perhaps you’ll agree that the corollary is this trend:

  • Consumers are spending less time on desktop and laptop machines “browsing the web” and more time using their smart phones.

In addition to the reasons I already listed, there are many reasons for this. I suspect the top reasons are because it’s so easy to use your smartphone, and it’s right by your side all the time even when you aren’t home. You most likely have seen people with their heads down playing with their smartphones during business meetings, while eating, while standing in line, while watching TV and even during sports events.

What about the Browser Vendors? These trends have interesting implications for browser vendors. They have to be aware of what’s going on. It’s possible that this is one of the many factors behind their massive push to add HTML 5 capabilities in an attempt to stave off what I’m going to call “user erosion”, as consumers spend less time using web browsers.

But, there are some facts to consider related to building applications that run in the browser:

  • Still functionality problems between different browsers. While the latest generation of browsers are the closest they have ever been to parity, in terms of JavaScript and HTML functionality, web developers are still hacking code to make certain things work equally across all browsers. These “hacks” cost extra time and money to code and maintain and the functionality differences between browsers cause customer frustration when things look different or don’t work as expected. This is especially true in large, retail-type consumer apps were you have little control over what browser your customers choose to use.
  • Faster but fast enough? Today’s browsers have the fastest parsers ever, but it’s a fact that they still aren’t as fast as native code, and they never will be. For the geeks reading this, browsers incur a CPU cost associated with parsing and then executing interpreted code. Smart engineers are going to continue to close the gap, but compiled code will always be faster and more powerful than code running in a browser. Period.
  • Memory usage. Browsers tend to be what we call “leaky”. The longer you use one without restarting it the more memory it will consume. I believe this is less of a problem in mobile browsers where windows get closed a lot more frequently than desktop/laptop browsers. However, it’s still an important consider this in mobile phones where more memory usage equals less battery life. Native apps can definitely leak memory, but they are also starting from a smaller initial footprint, and there are much better tools available for finding native app memory leaks. For browser apps, you also have the browser’s memory usage in addition to your application’s memory usage.
  • Security. Security is getting better for web browsers. But…it’s still easier to build a highly secure native app today than it is to build a secure web app. Also, for better or for worse, I suggest that many consumers perceive native apps to be more secure than web apps. Do you want to do your mobile banking over a web app or a native app? And whether a perception is right or wrong sometimes is irrelevant because it always strongly affects people’s behavior.

Concluding Remarks

Consumer-based companies are going to make important strategic choices based on information similar to what I’ve written above. My guess is that the most successful businesses will be the ones that adapt to what their customers want and if your customers are spending less time “on the web” then you should seriously consider adapting. Just to be clear, I’m definitely not saying that browsers are going away. No one has as crystal ball, and new technology is being created all the time. However, the momentum and sheer size of these trends, with hundreds of millions of people buying and using smart phones worldwide, makes it well worth studying its potential impact on your business.

References:

Mobile Apps Put the Web in Their Rear View Mirror
Mobile Apps vs. the Web – Which is Better For Business?
Gartner Report on Smart Phone Sales in 3rd Quarter 2011

* Companies are building specialized apps that essentially replace the need for customers to visit their web site. However, these apps offer much more control and typically provide a more consistent user experience that the web. Southwest Airlines, for example offers three types of mobile apps in addition to a mobile web site: https://www.southwest.com/html/air/products/mobile.html.

** Books and games, respectively have consistently been the top two categories for the most popular apps, for example: https://www.gottabemobile.com/2011/07/06/ipad-app-store-breakdown-top-apps-categories-chart/

10 Essentials for developing commercial Flex 4.5.1 mobile applications

This post is for Adobe Flex/Actionscript/Flash developers who are looking to build commercial-grade mobile apps. I’ve tried to pull together a high-level check list of items you’ll need to build successful and stable apps based on Flex 4.5.1. I’ve also uploaded a fully-functional prototype that demonstrates these concepts in a real-time, GPS navigation app. You can download the app here. So, here goes.

1. Set your initial splashScreenImage and application icon. For your app to look professional you’ll want to display an image while it launches so there isn’t just a blank screen. Here’s a great blog post that goes into more detail and covers handling multiple screen resolutions. One caveat on the splashScreenMinimumDisplayTime property is use this with caution. If you delay the app start too much you run the risk of really annoying users.

<s:TabbedViewNavigatorApplication xmlns:fx="https://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
splashScreenImage="@Embed('assets/splashscreen.png')"
splashScreenMinimumDisplayTime="1500"
splashScreenScaleMode="letterbox">

And, be sure to set the application icon. When you install your app, this is the image that will be displayed in the phone’s UI. Configure this in the yourappname-app.xml file. Note if you image icon isn’t the absolute correct size you’ll get a compiler error:

<icon>
     <image16x16>assets/appicon16x16.png</image16x16>
     <image32x32>assets/appicon32x32.png</image32x32>
     <image36x36>assets/appicon36x36.png</image36x36>
     <image48x48>assets/appicon48x48.png</image48x48>
     <image72x72>assets/appicon72x72.png</image72x72>
     <image114x114>assets/appicon114x114.png</image114x114>
     <image128x128>assets/appicon128x128.png</image128x128>
</icon>

2. Manage your applications life-cycle. The best article to read is the old but still very useful Hero View and ViewNavigator  – Functional and Design Specification and this blog post on Understanding View and ViewNavigator. For some reason the ViewNavigatorEvent poperties listed below aren’t documented in the Adobe on-line help. I’ve complained and so should you!

  • viewActivate Event – called when the view is fully activated. It actually happens after the creationComplete event. If you want to know more about view states in general then read this Adobe article.
  • viewDeactivate Event – use this in a View if you want to handle certain things when the user changes to a different View and the current one has been deactivated.
  • removing Event – This is called right before the viewDeactivate Event. So if there is something you want to do right before the view is fully deactivated then use this event.
  • persistNavigatorState – This property works at the application level and allows you to save the navigator’s view stacks and navigation history to a local persistent object. This is a property that is set in the main application’s mxml file and by default it is set to false. The standard architecture of a mobile app is to destroy the view contents when a user switches views so that the application saves memory. But, if there is a significant cost to destroying and recreating a particular view then you should test setting this property to never. Cost in this case means the amount of time, memory and CPU it takes to destroy and recreate a view. Also, if your end user is repeating this over and over that will ultimately affect battery life. Once a view is destroyed my guess is that memory is set for garbage collection. For info see this very informative Adobe blog post.
    <s:TabbedViewNavigatorApplication xmlns:fx="https://ns.adobe.com/mxml/2009"
         xmlns:s="library://ns.adobe.com/flex/spark"
         persistNavigatorState="true">
    
  • destructionPolicy – This is a property that can be set on individual views and can prevent an individual view from having all its data destroyed when the view is deactivated. For example, you may allow some views to be destroyed where others are mission critical and shouldn’t be destroyed because it’s too expensive to recreate them. As I write this, I believe this only works if the persistNavigatorState property has been set but it’s been a while since I verified that.
    <s:View xmlns:fx="https://ns.adobe.com/mxml/2009"
    		xmlns:s="library://ns.adobe.com/flex/spark"
    		destructionPolicy="never"
    		viewActivate="settingsViewActivateHandler(event)"
    		viewDeactivate="settingsViewDeactivateHandler(event)">
    

3. Manually changing views. Use pushView(), popView(), popToFirstview(), popAll() and replaceView().

  • pushView() navigates the user to a new screen.
  • Use popView() to move back to the previous screen.
  • popToFirstView() changes to the screen to the very first view that was opened. This is programmatically referred to as the view at the bottom of the view stack and uses the FIFO principal.
  • popAll() returns a blank screen. I’ve never used this and I haven’t come across a use case (yet) that would require given the user a blank screen.
  • replaceView() removes the current view and replaces it in the view stack with the new view you that you assign.

4. Passing data between views. One of the requirements of commercial apps is sharing data between different views. There are a number of ways to do this including singletons, dependency injection and using the data property in the pushView() method. Here are some good articles on all three:

  • Using singletons or tightly coupling data. This is typical for prototyping where you don’t want or need the overhead of a full framework. The prototype app download (link at top of page) uses a singleton model for simplicity.
  • Using framework-based, dependency injection. Use this when you want to use a framework such as Swiz, Parsely or Robotlegs.
  • Using the pushView() data property. When you have fairly simple data needs use this via the pattern pushView(viewClass:Class, data:Object = null, context:Object = null, transition:spark.transitions:ViewTransitionBase = null) Note that this pattern is for basic usage and the data object only supports standard content within the object such as Strings, Array, ArrayCollection, etc. If you have a custom class be sure to register them with the registerClassAlias() method or you’ll get runtime errors when you go to switch views.

5. Set application permissions.These are root permissions that are set via manifestAdditions for Android and infoAdditions for iOS – and these are located in the yourappname-app.xml file in your application’s root directory. Here’s an Adobe article with additional details. When the application is installed the user will be alerted to what permissions you are asking for.

<android>
     <manifestAdditions><![CDATA[
          <manifest android:installLocation="auto">
	       <!--See the Adobe AIR documentation for more information about setting Google Android permissions-->
	       <uses-permission android:name="android.permission.INTERNET"/>
	       <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
	       <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
	       <uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
               <uses-permission android:name="android.permission.WAKE_LOCK"/>
               <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
               <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
	   </manifest>
	]]>
     </manifestAdditions>
</android>

6. Shutdown the app. This only works on Android. On iOS, the user has to do this manually.

NativeApplication.nativeApplication.exit(); 

7. Temporarily disable the screen saver. This is required in apps where you don’t want the screen to go to sleep such as navigation apps where it may be open for a long time without any user intervention. You also need to set the WAKE_LOCK permission in the manifest file.

<uses-permission android:name="android.permission.WAKE_LOCK"/>

 

//Make sure we are on a mobile device and then
//keep the application awake so it doesn't go to sleep and close the screen.                                                      
if(Capabilities.cpuArchitecture == "ARM")
{                                                                             
     NativeApplication.nativeApplication.systemIdleMode = SystemIdleMode.KEEP_AWAKE;                                                                            
}

8. Detecting when phone rotates. If you need to know when the phone rotates use this listener:

stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGE,stateChangeHandler);

9. Gracefully fail when network connection is lost. If your app needs network access then it’s a best practice to gracefully fail and let the user know when internet connection is lost and then again when it’s restored.

public function NetworkChangeController(autoStart:Boolean = false)
{             
    var req:URLRequest = new URLRequest(_MAP_URL);
    _urlMonitor = new URLMonitor(req);
    _urlMonitor.addEventListener(StatusEvent.STATUS,serviceMonitorStatusHandler);

    NativeApplication.nativeApplication.addEventListener(Event.NETWORK_CHANGE,networkChangeHandler);
}

private function networkChangeHandler(event:Event):void
{
     if(!_urlMonitor.running)
     {
          _urlMonitor.start();
     }
}

private function serviceMonitorStatusHandler(event:StatusEvent):void
{
     trace("Network Status Event: " + event.code + ", " + _urlMonitor.available);
     _urlMonitor.stop();
     event.code == "Service.unavailable" ? _doSomething = false : _doSomething = true;
}

10. Multiple Device Support –sizing for different dpi’s. Last, but not least is using CSS and media queries to help with sizing and layout. Media queries are actually part of the W3C core CSS spec. The cool thing about them is they let you auto-majically detect the users screen dpi (dots-per-inch) and operating system and adjust your CSS accordingly. This saves a huge amount of work on your part:

@namespace s "library://ns.adobe.com/flex/spark";
/* DPI specific styles */
s|Button{
     color:#000000;
     fontWeight:bold;
}

@media (application-dpi:240)
{
     s|Button{
          color:#FF0000;
     }
}

@media (application-dpi:320)
{
     s|Button{
          color:#0000FF;
     }
}

/* Platform specific styles */
@media (os-platform:"IOS")
{
     s|Application{
          backgroundColor:#FFCCCC;
     }
     
     s|ActionBar{
          defaultButtonAppearance:beveled;
     }                      
}

@media (os-platform:"Android")
{
     s|Application{
          backgroundColor:#CCCCFF;
     }
}