Tuesday, January 15, 2019

The World of Mobile Development

If I started talking about IPAs and APKs you may assume that I'm a confused fan of beer, unless you happen to be a member of the mobile development community. In 2016 the global mobile developer community numbered twelve million. The barrier to entry in the field is shrinking every year, with improved tooling and better educational resources. Today, mobile apps can be built with most mainstream languages, opening the field to plenty of non-mobile developers and making mobile apps a more attractive businesses investment.

Whichever technology you decide to embrace, there are some inevitable experiences and lessons when writing mobile apps. This piece covers the core "mobile specific" knowledge that I picked up from building and deploying in this space.

If you are new to mobile development then I recommend skimming, noting the sections, and revisiting this down the road.

Development Concepts

For all the flexibility and features of mobile devices, developers pay an extra cost to build robust apps. It is not enough to just build your business logic and a UI that is connected to it. For example, you will need to handle screen orientation changes, and on Android you will have to save data to ensure that state isn't lost. Thankfully tooling on this has improved but just a few years ago it was a bit of the wild west. In addition, mobile devices are memory constrained, so developers need to handle saving state when an app is back-grounded and the OS decides to reclaim memory from it. Other common concerns include handling network status changes, and dealing with different screen sizes and form factors.

On top of the technical concerns, developers often have novel user concerns due to the global reach of mobile apps. Your users may be on on a metered connection or using low end devices. For your app to be successful with this segment you must limit network consumption, and be considerate of battery life.

Costs

Android devs pay a one time $25 fee to get access to the Android Developers platform to publish their apps, they can develop on a Windows, Linux or Apple machine. iOS devs pay about $100 per year to maintain a developer license, and must have a legitimate mac to sign their apps before uploading them to the app store. This is the case even if you use a cross platform development tool (Xamerin, React Native, etc).

Releases

In the pre-internet days, developers would build installers for their applications and burn them onto diskettes and CD's to be released. To try to ensure that these apps were safe Windows and Apple would push developers to digitally sign their apps so people installing them would know who it was from. As the internet became a content delivery system, people started to deliver applications from their own servers and domains.

The web also gave birth to a new class of applications, web apps, these were applications that ran on a remote server and users interacted with them via a web browser. No installation, no signing (this is a simplification, applets and https both partially contradict these statements).


Mobile app development has evolved differently. The delivery model for apps relies on the walled garden of the Play and App stores. Apps must be built as an APK for Android and IPA for iOS. Then, the developer must sign the app, upload it to the respective developer portals, and include accompanying documentation. After you upload, there is a review process to ensure the app is safe and performs as advertised. You can circumvent the process and release your app somewhere else, but that makes it unlikely that anyone will install it.


Once you are using the app stores, the only way to update an app is by uploading a new version to the store. Once the new version is released, users are prompted to install it and the old one is no longer available for download by the public. If there is bug in the app, you have to make another release and put it on the appstore via the regular release process. This results in straightforward support and maintenance channels since all users have access to your latest app and you don't need to backport bug fixes to old versions.

Languages

In Android at first there was Java, now there is Kotlin. Kotlin is a language that took the best language features (in my opinion) from Java, C# and JS and compiles it down to JVM 6 compliant bytecode (meaning it can run on somewhat old versions of the JVM). They are also working on native compilation so it can run without the JVM. I’d recommend checking it out as it helped me see where C#’s, Java’s and JS’s short-comings are. If you choose to use these languages, you will likely work with the Android activity/fragment framework. It is complex and nuanced, I can't do it justice in just a few sentences, and it's hard to find a resource which encapsulates it so I will leave that as an exercise for the future.

IOS development was introduced with Obj-C as its language for development. Objective-C is kinda verbose, and you need to relearn pointers, but many who have been using it for a while extol its virtues. Since 2014 Swift has been introduced by Apple into its development ecosystem. There is also a standard framework for developing native iOS apps, I have only tried it once and can't speak to it much.


There are also many cross platform solutions for writing Android and iOS apps. These all come with basically the same pros and cons. Some common pros are "fixing a mobile problem" like state management from React Native, reaching a new group of developers, or filling a niche for certain types of apps as Unity does for game development. The typical cons are that you are limited by the APIs the platform supports, and lord forbid the platform stop getting updates as you will need to rewrite all your code.


You can read a more granular history of mobile languages here.

Testing

Adoption of mobile app testing is poor in my personal experience (but perhaps that can be said for all software). Mobile testing strategy is still maturing for both platforms, and many developers forgo them for this reason. Others avoid them because they don't intend to maintain the app for a long period of time.

This isn't to say that tooling doesn't exist to write tests! Unit tests can be written for both platforms, iOS offers XCTest and Android utilizes JUnit. Android unit tests are regularly paired with a tool called Robolectic to help mock out Android APIs.

UI tests also exist for both platforms and support has drastically improved over the last few years. In general, these tests start an emulator, install the app and interact with it. The go-to instrumentation tool for Android is Espresso and the official tool for Apple is XCUI. These tests are fragile compared to unit tests so you should limit them to a small portion of your testing strategy.

If your mobile development team starts to grow, you may consider setting up a continuous integration (CI) solution to periodically run tests for you. Running mobile unit tests on a CI server doesn’t (normally) require anything more than downloading the project, building it and running it (same as tests for any java or obj-C app.

Running UI tests on a CI server is expensive with both platforms. You can (a) spin up simulators in your CI machines, which requires the machines to have virtualization technology for android emulators and to be macs for apple simulators. Or (b) make or use a device farm to run your tests, your CI machine will still need to build your apk and ipa files, but they can then send them to the device farm to run the tests. Today there are a few online device farm solutions that you can use (google, amazon, etc) that are pretty affordable and low maintenance compared to running your own.

Device Specific APIs

Even though there are two dominant mobile operating systems there is a wide variety of mobile device manufacturers. Each of these manufacturers can add some additional capabilities and apis on the core OS. Almost all of these devices run a variant of the Android OS. This means that as an Android developer you will occasionally run into bugs or quirks with specific devices, a fictional example would be that the Moto X2 flips the orientation of photos you take. There is no good way to address this preemptively (are you planning to test your app with every device out there?), you will instead need to rely on crash reports and complaints to address them.

Apple only supports iOS on their own devices so if you are an iOS developer, you rarely need to worry about this.

OS backwards compatibility

One of the most characteristic parts of mobile development is the annual OS api updates that you need to incorporate in your app. These updates will normally affect how you interact with device APIs, like Bluetooth, camera, background processing, and even the apis for rendering on the screen. These changes will rarely (if every) require you to change your business logic unless you want to take advantage of a new language feature that is introduced (ex: lambdas in Java 8, or using Swift and Kotlin). Due to the histories of the platforms and the markets they cater to, Android and Apple manage OS upgrades differently.


Android

The Android OS runs on devices created by many manufacturers. Each has the ability to customize the OS resulting in many manufacturers not upgrading the OS for a specific device after a couple releases (if you have an Android device not made by Google, you have probably experienced this). This means that developers must support APIs on a wide variety of OS versions. There is a set of libraries (Appcompat and Jetpack) that abstract some of this away, but some APIs (ex: camera) that are too strikingly different between versions to do that. The most recent version of the Android OS (8) came with a scheme for device manufacturers to more easily manage their customizations, this should result in devices receiving more OS updates in the future.

Android also didn’t require developers to upgrade their target OS to keep publishing to the app store. This changed in 2018 and going forward, developers can only submit updates to app if they are targeting the last two OS versions.

Apple

Apple is the sole device manufacturer of phones that run iOS, making it easy for them to manage providing upgrades for all of their phones. Developers have a limited amount of time to update their code to target a new OS and if you don’t install the new OS onto your phone you will eventually stop receiving updates for an app. As a result, iOS developers only need to support the last two versions of the OS.

Server backwards compatibility (this is not unique to mobile)

If you are building a mobile app that is released alongside a server solution, there will probably come a time where you introduce an api change between the two platforms. When you have a js app, this just requires the front end to change to be in sync with the new API since the back-end and front end code ship together. However, with a mobile app you will normally need to support both versions of the API to support old server versions since your mobile app upgrade will go to users who may be using an old server version!

Oh my, you made it!

When I set out to write this I didn't realize how many topics and concepts I would cover. I ended up writing a lot more than I had imagined, and I think there two important takeaways. The first is the top level "subjects" we covered (releases, costs, languages, testing, device apis, and compatibility) and the second is the realization that Apple and Google dictate a lot within those spaces.

Rearing to explore more? The posts I linked throughout the article are informative reads. Another related read is this three part series from Simon Bates, offers a sweeping look at history of mobile development from it's earliest days to the future. One random topic to throw in is Android Things is turns Android into a platform for developing internet of things devices. These can be run on a wide variety of devices including raspberry pis and is still in its early days.

Please share your thoughts! Any topics I missed? Follow up questions? Stories of your entry into mobile development?

Thanks for reading!

0 comments:

Post a Comment