Photo under CC by Tsahi Levent-Levi
Halfway through my HCI degree I “saw the light” and moved from a flip phone to an Apple iPhone in 2010 despite being notoriously cheap. The following year I wrote my first iOS app for the device. Since then I’ve worked at Apple in the iOS division for two and a half years, watched every Apple keynote, been developing in Swift pre-1.0 and worked on Coursera’s iOS app while releasing another iOS app on the side…
So why have I been working on Android in Java for the last nine months?
Why Android Matters at Coursera
Photo under CC by Joseph McKinley
Today users can find Coursera on the Web, iOS, AppleTV and Android. This makes sense because each platform is going to reach a different set of users with different needs. It’s widely accepted some of these platforms are easier to monetize upon than others. Just as some platforms have greater potential for increasing global education equality. Both these factors are necessarily to achieve Coursera’s moral vision: “Universal Access to the World’s Best Education”.
Coursera’s own studies have found global learners from lower economic backgrounds benefit to a greater extent (from Coursera) than those of higher economic backgrounds. Inarguably, users who are the least able to afford U.S. education prices and have the least access to quality education will be on mobile, likely Android. I decided to work on Android because despite my passion for the Apple ecosystem, my passion to provide those educational opportunities was greater. I wanted to help bring that educational access to the majority of people in the world who don’t have access to quality education. A challenge that affects every country in the world.
Forget Dual-Platform, be Bilingual
Photo under CC by Ralf Peter Reimann
Starting on a new platform like this (even within the same company) can feel like starting over in a new job with a completely new codebase and set of processes. These inconsistencies are what make moving between platforms so difficult. Given this experience is the norm, I define a Dual-Platform engineer as someone with working knowledge of two platforms, but whom requires a long ramp up to become efficient.
However, at Coursera we are always figuring out how to build higher performing teams. A number of us (myself included) have been improving upon the Dual-Platform norms to reach something I call being Bilingual - someone who can concurrently develop both platforms, efficiently and with little to no ramp up. This has allowed us to treat these developers as a liquid resource flowing between whichever project or platform needed more support. It also improved communication between platform developers by having Bilingual Engineers as translators. This resulted in better code quality / design from the knowledge sharing of best practices, architecture advances and SDK approaches.
Driven by developer interest, over a period of six months over half our mobile team has become either Dual-Platform or Bilingual. This feat was nothing short of exceptional and wouldn’t have been possible everywhere, but for us it was easy due to our strong mobile values: openness to experimentation, curiosity and inclusiveness. Wait, did I say inclusiveness? Yes.
While many companies partition Android and iOS developers into separate organizations, we only have the concept of mobile at Coursera. Therefore cross-platform teams work on features together, share a common architecture, have the same release schedule, etc. After a quick platform-specific kickstart, this makes it easy for each team member to orient themselves to (and switch between) both codebases and as well as onboard onto a platform using these strong interpersonal relationships.
Photo under CC by JD Hancock
Within this great environment, I started with a quick week-long intensive deep dive into Android. The following week I launched Android Studio and began work on the Coursera Android app.
Starting out it was often frustrating to know the conceptual solutions for problems without understanding immediately how to begin implementing them. Having worked on native desktop and iOS software for years, Android felt similar in terms of the OS architecture concepts and challenges: permissions, persistence, UI lifecycle, threading, services, etc. However, it was a big initial shock going from feeling fairly expert on iOS to a novice on Android given the different language, toolset and third party frameworks.
I might quickly understand I needed to shift some work to a background thread or synchronize on a resource but have no idea how to use Executors, Runnables and Loopers compared to iOS dispatch queues. A class with too many responsibilities might be designed better using extensions in Swift, but composition in Java. Similarly, understanding view lifecycle specifics when creating custom components or good patterns for communicating between controllers (View Controllers vs. Activities/Fragments) all took time. Asking feedback from colleagues was very helpful here to avoid feeling like I wasn’t contributing enough while I was learning and less efficient. Some coworkers utilized pair programing to more quickly learn these platform specifics.
All this work brought me to the Dual-Platform stage, having working knowledge of each platform. However to be Bilingual you need common architecture, style and processes to make working on either platform consistent enough to reduce switchover costs. The first step was moving our already similar architecture towards greater consistency. Not only did this improve how we developed on each platform, but it also helped us become better at finding the right tool for the job. Including using the builder pattern in iOS or experimenting with RxSwift. Both commonly used in Java on Android, but infrequently used in iOS. Similarly having Android engineers experienced in iOS and Swift eased adoption of Android M’s new iOS-like permission concepts and encouraged us to embrace and quickly ramp up on using Kotlin.
The second part of being Bilingual is about working concurrently on each platform. I’ve found quickly referencing iOS code when debugging an issue or working on a feature in Android accelerated my development process since I had an example of working logic. Similarly if something on iOS breaks I feel empowered to go and fix it instead of waiting for someone else to look into it. All this feels one step closer to the goal of writing an application once instead of starting from scratch on each platform.
Photo under CC by George Thomas
When it comes to working in two distinct ecosystems the first thing people ask is what I think of the differences between each development platform. For starters, the tooling and API on each platform (iOS/Android) truly reflects each company’s (Apple/Google) approach to software development. Apple favors simple, elegant, streamlined interfaces and doesn’t care about backwards compatibility. As a result, Xcode offers only the few configuration options it feels useful, any IDE feature is well integrated and the layout system is reminiscent of hardware product design. Meanwhile the API is opinionated and deprecated heavily.
Alternatively, Android favors open source, running its OS everywhere and developer power. Android Studio surfaces as many features as possible via side-bars, has a highly integrated system for importing third-party frameworks, an incredible depth of configuration and very powerful text generation / linting. While its API is open source, heavily backwards compatible, never removes deprecated code and has a layout system very familiar to HTML.
Now, if I could combine the powers of both… How would I change each platform? I’d make Android’s API’s more opinionated with a one clear way of doing things, simplifying the support library and Fragment-Activity usage. Next I would add Android Studio’s powerful code generation/completion and linting to Xcode for Swift. Android’s third-party framework system (Gradle) isn’t perfect, but it would be nice to have something like this from Xcode. After that I would remove about 80% of the configurability in Android Studio to reduce feature overload, replace Stetho view inspection with the Xcode View Debugger, use the xcassets approach for design resources and streamline active debugging in Android Studio to look like Xcode’s Instruments. Finally, I would add LinearLayout from Android to iOS so it is easier to quickly stand up iOS layouts. Wait, Apple already did that with UIStackView! Progress!
The big personal take-away I had from this process was that setting up your workplace and processes towards experimentation, collaboration and inclusiveness sets your teams up to be more effective. If we hadn’t laid the groundwork for these values early on then becoming Bilingual would not have been possible. Even further, without these values I don’t think Coursera’s mobile team would have attempted developing engineers to become even Dual-Platform.