Mobile app development is blooming and many software developers are transitioning either temporarily or permanently from different software fields. Thanks to matured platforms like Xcode and Android Studio, the experience of native mobile development nowadays does not differ much aside from the new language you need to learn. There are even hybrid application platforms like PhoneGap or Sencha Touch that allow web developers to code in familiar languages. However, there are always tips that are unique or emphasized in the mobile environment. Here I will list a few of those that I find personally interesting and important.
Although my examples focus on native iOS development on the Mac platform due to my personal skill set, I will try to be as general as I can.
Some people just have spontaneous implementation ideas, but getting ideas from other well-made apps is a good approach regardless of the platform. Here are some ways to get a little deeper into third party apps than just glancing at the interface.
Look into resources (image/sound, etc.)
Both on iOS and Android, the deliverables (.ipa file for iOS, .apk file for Android) are just zip files with different extensions. So, you can rename the extension and unzip the contents and view certain type of files as is (image file, sound file, meta file, etc). You can see whether the app is simply showing an image file vs. drawing graphics programmatically, whether it is playing a sound file vs. synthesizing audio programmatically, what kind of font it is using and more. (To view an image in .ipa files in a normal PNG viewer, you need to use pngcrush to revert the applied optimization.)
Look into data transfer
Due to the lack of computing resources compared to desktop machines, most mobile apps live on a data feed from server(s). So, capturing communication between mobile apps and server(s) becomes a big part of profiling the app.
Using the Charles proxy, you can monitor any third party app’s traffic. If you are not familiar with Charles, it is an HTTP proxy application that could show you all communication it captured. If you change your mobile phone settings and specify HTTP proxy as Charles’s IP address/port, all communication goes through Charles and will be displayed on it. Since most mobile apps use SSL for communication as they should, there are usually only a few more steps involved : Detail with iOS, Detail with Android.
View screen hierarchy
If you already have a jailbroken iPhone, you can view the hierarchy of any third party apps using libraries like Reveal or Spark Inspector (How to inspect the view hierarchy of 3rd party apps). This is a very cool trick that works very well, but unfortunately jailbreak is not available for iOS 7.1. Thus, it is only available for people with already jailbroken devices or old devices that don’t support iOS 7.1 at this point.
Divide one big network request into multiple small requests
If your screen is based on one big network request and you have flexibility to either choose/add variation of endpoints, consider splitting the request into multiple ones. Paging is one way of splitting if the data is a collection of same type elements. You can also divide data into main content and supplementary content. For example, Facebook timeline consists of a collection of posts and associated social information (comments, likes, etc.). If you load comments data quickly first, users can start reading/navigating the main contents without waiting for supplementary information. Considering that mobile applications could suffer from slow network conditions depending on time and place, this arrangement could help to improve your bounce rate.
Log network request/response
As I mentioned earlier, network communication is one of the biggest profiles of mobile apps. Logging every network request/response would reduce your time for debugging issues and you don’t have to do it everywhere. On most platforms, you should be able to just hook into a base network communication class. (In AFNetworking 1.x for iOS, you could subclass AFHTTPClient; in AFNetworking 2.x, you can do the same to AFHTTPRequestOperationManager. With Volley library in Android, you should be able to subclass Request/Response or its subclasses.)
What I particularly find useful is a network request formatted in curl command form.
curl -H Authorization:”XXXX” -H Accept:"application/json" "https://staging.deliradio.com/api/v2/favorites/band_profiles/accounts/30.json?account_id=30&page=1&key=abcdef”
If something erratic manifests on the interface (e.g., data won’t refresh), the first thing you want to check is whether it is a data problem or the interface (code). By copying and pasting above the command in the terminal, you can quickly check whether a corresponding request is working or not without depending on context. You can use the aforementioned Charles proxy for this purpose as well, but I like to combine this logging approach as well. In many cases, I don’t have Charles proxy open when I encounter something new.
Always use SSL
You should always use SSL for communication between your app and server. For one, it is so easy to intercept wireless communication data if somebody wants to. Two, as we can expect more and more context based information (which could be more personal) will be sent to servers in the coming days, “it’s impossible for software to determine whether a user’s data is confidential, embarrassing, or even dangerous.” (Quote from Apple Developer Document)
Crash log reporting service is also a must-have component for any type of software development. There are several different services that offer a crash report for mobile apps:
- Hockey App
Among these, we like using Crashlytics. Logging is very seamless and it also allows you to attach context information to an individual crash. It supports both iOS and Android, which covers the majority of the mobile market share. For people who need to support a Windows Phone, Crittersism or HockeyApp are options, too.
Sometimes, I see developers record all logs from one app into one bucket, which I think is a bad habit. We should always create two different Crashlytics App settings, one for the Debug/Beta environment and another for the Release Candidate/App Store environment. This way, you can accurately grasp how often the crash is happening in a real user’s world. Also, I prefer not logging to Crashlytics from a debug environment because it would log crashes caused by a temporary change that you fixed immediately.
Test slow network conditions
Mobile applications, as stated before, can suffer from slow network conditions depending on when and where someone uses your app. Most likely, your development environment has much better bandwidth. So, you somehow need to simulate a slow network to test that environment. There are several ways to do that:
- On simulator or emulator
- Use Network Link Conditioner on Mac
- On device
Monitoring & Analysis
Log user behavior
If you intend for your app to go over multiple versions, logging user behavior for later analysis is a must. Direction for the next revision should be based on the current user behavior.
We used Flurry and Google Analytics and both are good enough to track basic stuff like:
- Conversion (tied to specific screen or event)
However, there are some elements that both services lack (e.g., individual user activity tracking) so we are starting to try mixpanel now.
In this post, I listed some of the techniques that are common and emphasized in mobile development. Although most examples were based on iOS app development, the ideas should be applicable for general mobile development.