mDevCamp 2019: Welcome & Keynote

mDevCamp is one of the biggest mobile development events, and we’ve had the chance (and luck) to be able to assist to this year’s edition. With a lively atmosphere and refreshing and influential talks, mDevCamp’s speakers filled us up with their vigor and knowledge.

presentation mDevCamp

Michal Šrajer presenting mDevCamp. Twitter

The event started with a Keynote where mDevCamp’s CHO (Chief Happiness Officer) and co-founder, Michal Šrajer, explained the event’s beginnings, how it evolved from a small conference in a single rented room to its current state, taking place in Prague’s Congress Centre. Afterwards, he gave way to Daniel Čech, our master of ceremonies, who asked us to stand up and start doing some exercises he called “developer’s warm up”: simulating the mouse’s circular movement, writing on an imaginary keyword or putting on and off our headsets.

After this warm up, the event proper began, introducing the conference’s heroes.

mDevCamp’s heroes

Before the technical talks, a couple of members of important communities participating in the event presented some inspiring talks, tackling technology’s social impact in our current world and how each of them help society through their respective communities.

Jakub Nesetril mDevCamp

Jakub Nesetril talking about the developers’ “luck”. Twitter

Things started off with Jakub Nesetril, founder of Apiary, recently acquired by Oracle and Česko.Digital‘s representative, and told us about how this community created by developers and other IT professionals is helping and collaborating with organizations that don’t receive any benefits from the government.

presentación comunidad czechitas

Next in line was Dita Přikrylová, founder of Czechitas, a community created with the goal of bringing technology to the country’s kids, teens, women and the elderly. As an example of their work, she showed how a group of older people who had lost their jobs could get reintroduced to the labour world thanks to Chechitas’ courses and help.

Dita Přikrylová representing Czechitas

Dita Přikrylová representing Czechitas. Twitter

Lastly, Josef Holy presented his Think Broad talk. He started by sharing his blog, Algocracy News, where he exposes how our society is becoming more and more automatized and our everyday lives ruled by algorithms. He reminded us to keep collaborating and helping each other, regardless of all that, encouraging open source relationships and with people outside the IT world, with a broader perspective.

mDevCamp Talks

After this keynote, the technical talks began. They were divided into three tracks, totalling 21 talks about diferent areas of the mobile world (if you’re curious, here’s the calendar). We couldn’t attend all of them, but we’d love to talk about those we did take part in:

Level up in Kotlin Pamela Hill (10am)

The first talk we attended was about Kotlin. Pamela Hill, Android Engineer at Luno, started the talk by asking us about the most important photo of the year, and linked that with Katie Bouman, who led the development and investigation team that produced such results, giving a shout out to women in tech.

She then proceeded to talk about the singularity that is Kotlin’s apparition in the mobile world and it has been adopted as the first Android language. During her talk she tackled some advanced Kotlin topics: Coroutines, Conventions and DSLs.

She told us some basic concepts about Coroutines, like how are lightweight threads platform natives compared to RxJava, as well as some basic constructors and their scopes. She also talked about the use of keyword suspend in order to have functions we can postpone without blocking the main thread and how to combine them with other suspend functions. She also mentioned the possibility to decide the thread where we want to execute them through their dispatchers.

In short, thanks to coroutines we can improve the performance, the code’s readability and compatibility with Jetpack. Here‘s a summary with all the keys.

She then talked about Conventions, operators used with certain functionalities of the language. Their use helps us create a much more functional and readable code and that, by compacting them in an isolated manner, it becomes easier to maintain and boosts our capacity to memorize where they’re executed.

She explain some of these functions in different contexts: arithmetic operations like minus or sum, comparatives like eq or in to replace the contains function to check a list and even unstructured operations, being able to create n-variables from one function:

    data class Result(val result: Int, val status: Status)
    fun function(...): Result {
        // computations

        return Result(result, status)
    }

    val (result, status) = function(...)

The keys here.

Lastly, she introduced DSLs or domain-specific languages. She briefly explained the concept and some tips to create our own DSLs, like: using extension functions to increase readability, creating lambdas with receivers, using the invoke operator or using usar infix functions.

What is a DSL?

On her blog you can find a much deeper research of all these elements.

Live Coding in Swift Chris Eidhof (11am)

At 11 o’clock in the main hall we saw Chris Eidhof‘s Live Coding in Swift, something we were very excited about, since we closely follow all the fantastic content he and his partner Florian Kugler publish on their website www.objc.io.

Following the tone of said videos, Chris presented us with a problem from scratch: to create a wrapper of an old C library in Swift. It’s a low level library that allows the drawing of some shapes onscreen.

First he taught us how to import C libraries to Swift with XCode.

It didn’t take long since we got to the solution to the problem, that is, the finished wrapper written in Swift. But as we said earlier, following the same methodology they use on their videos, Chris kept doing iterations, each new one more interesting than the last, until he obtained a simple but high level API with some generic that allowed the use of the no longer updated C library.

To end his talk, he encouraged us to do the same with the near infinite amount of useful C libraries that still exist and don’t have a runway to Swift.

Chris Eidhof's presentation

Chris Eidhof’s Presentation


Lunch (12am – 1:15pm)

After the first talks it was lunch break time. The catering consisted of traditional food, with lots of vegetables, and also tons of fruits 💚

Fruits!

Fruits!

After the break, we went our separate ways so we could attend those talks more focused on our favorite platforms:


CHUCHEL, Our Problem Child Jakub Dvorský (1:15pm)

Jakub Dvorský told us in his CHUCHEL, Our Problem Child talk all the problems they faced during the development of the CHUCHEL videogame. While a less technical talk, it was still very interesting.

The Nitty Gritty of Unit Testing in Kotlin Yun Cheng (1.15pm)

At the start of her talk, Yun Cheng introduced the Asics projects she was working on: an app they were migrating from Java to Kotlin and another one they were creating from scratch.

She started her reflections with a classic MVP using a classic Android stack of third party libraries: RxJava, Mockito and JUnit, alongside the common presentation test consisting of receiving a list of objects and checking if it’s void or not to properly update our view.

So, her talk consisted in seeing how she kept iterating many solutions to the problems the compiler was giving to her test.

The first one appeared because the compiler launched this error:

    Mockito cannot mock/spy following:
     final classes
     anonymous classes
     primitive types

This error happens because the Mockito 1.x library isn’t optimized to work in Kotlin and its final classes, so she started contemplating different solutions, like adding the open modifier to our class, emphasizing that it is a bad practice since it modifies the production classes. Another solution was to create interfaces replicating our class’ behavior. She proceeded by updating the library to Mockito 2, additionally applying a library called mockito-inline (or creating a MockMaker file with the mock-maker-inline line). After this change the error was solved, but then a new one appeared:

    java.lang.IllegalStateException: captor.capture() must not be null

To solve this new error, she recommended using this gist to avoid the exception.

Lastly, when using the when method from the Mockito library the test launches an error, since it’s called like Kotlin’s keyword when. The solution is simple: put the method between quotation marks, and all tests will go back to green.

This is a particular case derived from using the Mockito library, but to avoid these inconveniences there are other community approved, third party libraries like mockK or mockito-kotlin.

Introducing MicroViewController Ken Tominaga (1:55pm)

Ken Tominaga, developer at Mercari, an e-commerce app present in Japan and USA, introduces us to his Introducing MicroViewController talk. it was a bit polemic, since he proposed a drastic change to views by migrating all UIView to ViewControllers.

A normal view using MicroViewControllers

A normal view using MicroViewControllers

At the end of the talk, there were a lot of questions about potential caveats due to the massive us of ViewControllers, like the two-way communication with buried elements in a view hierarchy. A possible solution given by Ken himself was to use a generic DataStore and singleton to directly access buried layers.

Among the evident benefits of using this architecture are the ease with which many developers can work isolatedly with a particular ViewController without stepping on their peers’ work. Another one is that in iOS the UIView don’t have a life cycle while UIViewControllers do.

Why do we need micro view controllers

Evolution of Test Automation in Spotify Sangsoo Nam (1:55pm)

One of the most anticipated talks of the event, and it didn’t disappoint. Sangsoo Nam explained how they’ve improve the testing applied to Spotify though different iterations depending on how they scales in the producto.

He started off by introducing us to the test pyramid that we can find, for example, in this article by Martin Fowler, which can be summed up like this:

Test pyramid by Martin Fowler

After introducing a test example (an app’s Login) he mentioned the importance of doing integration tests since their main goal is to deliver that specific content to each user, and to do that we need to extract information from multiple entities until we can obtain a dedicated playlist, a recommended author, etc… To that end he showed us one of the tools they use, Beanshell, which creates a script simulating our integration and does it outside of our app.

Focusing on this, increasing the number of integration tests, the tests also became slower, greatly delaying the releases. To solve that, they created an internal tool, Cassette, with which they improved their old tests’ speed 20 fold.

Cassette Capabilities

Cassette Capabilities

Thanks to that and using Espresso for the UI tests they managed to stabilize the pyramid and have a productive test environment.

Lastly, he talked a bit about his company’s test culture, where they created a manifesto called TC4C or test certified for client, detailing the conditions and goals of their tests.

TC4C, Test Certified for Client

TC4C, Test Certified for Client

Free Cocoa: hack mobile app and skim the cream Kamil Borzym (2:35pm)

Kamil Borzym talked about how important it is to pay attention to our apps’ security.

During his talk, Kamil showed us in an interactive way the process of hacking into an app of an imaginary cafe where the first time you register you obtain a free cafe.

Thanks to a reverse engineering open source software we can obtain an already compiled app (.ipa/.apk) with all code lines in assembler, but since they didn’t obfuscate the names of the methods we can easily find methods like validateCredentials.

Once we’ve found the methods we know deal with the user’s control, we can erase critical code lines from the compiled app and obtain a new one that every time that it’s executed it bypasses all security checks. Which means, we’d have a free cafe every time we used this app.

Of course this modified app is not one found in the market (AppStore/PlayStore), but thanks to fraudulent stores like cydia it wouldn’t be difficult for an user to obtain a completely modified version of your company’s app.

As final notes, he recommended that before we upload an app to the market it goes through an obfuscation process where all method names are changed into random ones with no logical relation to their actual functionality, difficult any potential hacking. El software para ofuscar que propuso.

Security disclaimer

Security disclaimer

Incorporating Material Theming into Custom Views Nick Rout (2:35pm)

After many talks focused on the business side of app development, we had Nick Rout, Android Engineer at Over, who told us how to use material components in our Android app.

He started by asking “What is Material Theming?”, linking that question with the ASCII system, with which we can create sized, typographies and colors.

He told us that since androidX’s inception, the library we commonly used to introduce Material Designs elements had been modified, including new components we can set up through styles and re-use them our application.

    //old
    implementation com.android.support:design
    //androidX
    implementation com.google.android.material:material

After this introduction he segued into a Playground where he had many material components he wanted to modify in an homogeneous manner. So he started by including a new customized component, ColorPickerView. Right next he modified his style sheet with all the colors, sized and looks he wanted for his components, but the result wasn’t what he expected, specially when using a dark theme.

His customized component didn’t apply the changes, so he explained a step-by-step way of modifying each of the internal views using the new library’s resource instead of the standard one, setting up his styles so it’d be possible to customize it via the xml file where it’s implemented.

And to give a dark theme support, he mentioned the elevationProviderOverlay property, which allows us to increase the components elevation, making it increase the background’s brightness levels to highlight the smaller components.

You can see this talk’s slides here.

How Artsy Automates Team Culture Ash Furrow (3:30pm)

Ash furrow on stage

Ash furrow on stage

Ash Furrow’s talk was focused on how they organize the workflow at their company, comprised of 33 engineers working simultaneously.

He introduced the tools they used, focused on the automation of all kinds of processes.

The first is Danger, a tool running during the CI process and that automatizes the most common code review processes. Some rules are previously established and Danger writes comments on the PR about all it detects.

Another tool is Peril, a webhook that’s linked with GitHub and allows us to, for example, when we close a GitHub issue that has an associated Jira ticket, to solve and close that too.

Here you’ll find the slides.

Journey to painless releases: Continuous delivery for Philips Hue Android Jeroen Mols (3:30pm)

In this business oriented talk, Jeroen Mols talked about the evolution experienced at Phillips regarding the development and delivery of their app, Phillips Hue.

He showed the release life cycle they had before implementing Continuous Delivery, which meant it took them about 10 weeks to have a production version ready, including development, testing and beta. This also meant having other versions in different fases, since they were working with a Git Flow environment with multiple features in development.

The first frustrations detected were:

  • Issues were detected too late.
  • The developers were disconnected from the users, since they were working in features way too advanced compared to when the production release took place.
  • The context changed drastically between releases.
  • Doing a release was painful.
  • Friction between developers and testers.

Branching model in early phase

Branching model in early phase

This branching model applied to the releases created additional frustrations:

  • Unstable development branch.
  • Nightmares during the merges.
  • Poor code reviews.
  • Confusion about where to solve bugs.
  • Slow development.

In short, bugs, incomplete development and and dissatisfied development team. To solve that, they established some gals, speed, quality and a more dynamic feedback between developers and users, introducing continuous delivery to the product.

If it hurts, do it more often and bring the pain forward – Jez Humble

To increase the releases‘ speed, Jeroen proposes to reduce the size of the pull requests so they’re faster to verify, meanwhile having the Android libraries up to date. In CI, using git hook alongside git cache, preload the Gradle wrapper in a Docker container. With this, they reduced the builds from 20 to 5.

More rules were established, like features being shorter than 2 days, making sure they got integrated to master as soon as possible.

Also, reduce complexity by deleting the development branch to do the merge directly in master.

Applying Gradle level set ups to the different app versions, Daily, Test and Production, so that the upload of more test oriented versions goes as fast as possible and optimize them via feature flags.

Impact Analysis

After all these changes, now their releases happen every two weeks, and the integration of new changes happens on a daily basis, having more optimized beta versions. All of this through CI/CD, increasing the team’s happiness and the user’s satisfaction.

To see the slides, click here.

Improving Developer Experience through tools and techniques Krzysztof Zabłocki (4:30pm)

The last iOS talk we attended to was by Krzysztof Zabłocki, which focused on the use of multiple techniques and libraries that would make our developers lives easier.

Some of these open source suggestions include Sourcery, Playgrounds and Bootstrap.

Krzysztof Zabłocki on stage

Krzysztof Zabłocki on stage

RxJava & Coroutines: A Practical Analysis Ashley Davies

And the last Android talk was introduced by Ashley Davies, Lead Engineer at ImmobilienScout, and was centered around the use of the popular RxJava library against the Coroutines proposed in Kotlin.

He did an introduction to the scopes used in coroutines and their different applications. 

He suggested that we kept implementing them, since the learning curve is simple, and it’s a first class native functionality, which means it’s very smooth.

He used the chance to talk about some Android history regarding asynchronous operations that went from Runnable/Handler, Asynctask, IntentService, WorkManager… connecting all these options with this strip.

How standards proliferate

He then proceeded to introduce RxJava. Arguing that when it was first released, and since it was a reactive library, all developers got addicted to it, and this paved the way for the almost infinite creation of libraries using RxJava.

rx-libraries

Ashley explained how we developers were using RxJava without any measure, doing countless and complex operations, and so when the vast majority of developers that aren’t experts in its implementation tried to solve complex operations like:

    Observable
      .fromIterable(resourceDraft.getResources())
      .flatMap(resourceServiceApiClient::createUploadContainer)
      .zipWith(Observable.fromIterable(resourceDraft.getResources()), Pair::create)
      .flatMap(uploadResources())
      .toList()
      .toObservable()
      .flatMapMaybe(resourceCache.getResourceCachedItem())
      .defaultIfEmpty(Resource.getDefaultItem())
      .flatMap(postResource(resourceId, resourceDraft.getText(), currentUser, resourceDraft.getIntent()))
      .observeOn(AndroidSchedulers.mainThread())
      .subscribeOn(Schedulers.io())
      .subscribe(
          resource -> repository.setResource(resourceId, resource, provisionalResourceId),
          resourceUploadError(resourceId, resourceDraft, provisionalResourceId)
      );

Became such a huge chain that keeps escalating, eventually getting out of control, turning the benefits we sought from Rx into a double edged weapon.

“If all you have is a hammer, everything looks like a nail” – Abraham Maslow, The Psychology of Science, 1966

After making it painfully obvious that abusing Rx was a bad thing, Ashley did various comparisons about how to do the simpler operations via Coroutines.

    // RxJava2
    getUser()
      .subscribeOn(Schedulers.io())
      .observeOn(AndroidSchedulers.mainThread())
      .subscribe { /* Do something */ }

    // Coroutines
    launch(Dispatchers.Main) {
      withContext(Dispatchers.IO) {
        val user = getUser()
        /* Do something */  
      }
    }

Lastly, he answered some doubts developers might have, like if they should migrate their projects to coroutines or if that was a RxJava replacement, answering “no” to both questions and using the old saying: If it ain’t broke, don’t fix it. Thanks to RxJava complex operations can be treated in a more functional and readable manner.

“If it ain’t broke, don’t fix it” – Bert Lance, Nation’s Business, 1977

That being said, Ashley did recommend everyone to start using coroutines on their new features, as long as that doesn’t affect the production code.

More info + slides here.

Lightning Talks & Closing Ceremony

Before the conference’s end, some participants had the chance to partake in the lightning talks, talks of about 7 minutes to talk about their “second life”: what they liked to do outside of work, which was an interesting way of disconnecting a bit from the massive amounts of data received during the day, and it also made most attendees laugh out loud and relax.

The first participant talked about his triathlon passion, joyously expressing his desire to constantly improve his own records.

Next one practiced slackline, a sport he said helped him manage his mind, since it requires a great deal of concentration.

The third participant “sold” us the best virtual reality game (live action role playing), where you could play a role in a fictional or historical sequence with lots of other people.

The fourth one talk about his love of drawing, introducing an app he had created to that end, and finally, the last participant was a magician who did an actual show, and truth be told, it was mind blowing.

Finally, the CHO thanked all attendees, partners, speakers and participants.

Closing ceremony

AfterParty 😎

Primer speaker presentando su random slides

After the conference there were a couple of activities to promote networking and camaraderie among attendees, like a random slides contest, where some speakers from the event had to defend products made up by the public like the Google Toilet Paper or the Apple Apple, improvising as the slides went on.

Kotlin ketchup

Afterwards, there was a team quiz of 30 questions about tech, software development and geek series in which we participated alongside other local developers.

Quiz team

Without and doubt, mDevCamp has been a fantastic conference for mobile developers, with up to date talks, an excellent organization and a very pleasant atmosphere. It was a great experience, and we’re already counting the days until next year’s edition, which we won’t miss!