Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Productive Mobile Development for Engineers

Productive Mobile Development for Engineers

Tips and Tricks for Productive Mobile Development. Given in Droidcon Egypt on October 21st, 2022.

Ahmed El-Helw

October 21, 2022
Tweet

More Decks by Ahmed El-Helw

Other Decks in Programming

Transcript

  1. Ahmed El-Helw October 21, 2022
    Productive Mobile Development
    Tips and Tricks for Productive Mobile Development

    View Slide

  2. Source

    View Slide

  3. Factors affecting Speed
    Things to Consider
    • Distractions

    View Slide

  4. Source

    View Slide

  5. Factors affecting Speed
    Things to Consider
    • Distractions

    • Communication Problems

    View Slide

  6. View Slide

  7. Factors affecting Speed
    Things to Consider
    • Distractions

    • Communication Problems

    • Con
    fl
    icting Priorities

    View Slide

  8. View Slide

  9. Factors affecting Speed
    Things to Consider
    • Distractions

    • Communication Problems

    • Con
    fl
    icting Priorities

    • Technical Debt

    View Slide

  10. View Slide

  11. Factors affecting Speed
    Things to Consider
    • Distractions

    • Communication Problems

    • Con
    fl
    icting Priorities

    • Technical Debt

    • Production Fires

    View Slide

  12. Source

    View Slide

  13. Factors affecting Speed
    Things to Consider
    • Distractions

    • Communication Problems

    • Con
    fl
    icting Priorities

    • Technical Debt

    • Production Fires

    • Hardware

    View Slide

  14. Source

    View Slide

  15. Process Bottlenecks
    Mobile Bottlenecks
    • Company release process

    • Application store review process

    • Application store rejections

    • Adoptions take time

    View Slide

  16. Experiments and Toggles

    View Slide

  17. Tim Campos
    “Data wins Arguments”

    View Slide

  18. Customer Behavior
    Understanding and Monitoring Customer Behavior
    • Dashboards

    • critical business statistics

    • conversion funnels

    • Slice by application version

    • Alerts

    View Slide

  19. Dealing with Problems
    How to React to Problems
    • Ignore it for now

    • Hot Fix in Production

    • Release takes time

    • Adoption takes time

    • Risky

    View Slide

  20. Source

    View Slide

  21. What if we just turn it off?

    View Slide

  22. Other Considerations
    Things to Keep in Mind
    • Be mindful about:

    • The e
    ff
    ect of experiments on each other

    • The e
    ff
    ect of feature
    fl
    ags on each other

    • Dead Experiments increase Technical Debt

    • Can tooling help here?

    View Slide

  23. Data

    View Slide

  24. Data
    Some odds and ends about Data
    • Building trust with Customers

    • Compliance

    • App Stores

    • Governments

    View Slide

  25. Policy Changes are often a
    Surprise

    View Slide

  26. MetaFilter via Forbes Article
    “If you're not paying for it, you become the
    product”

    View Slide

  27. As a company grows, so too
    does the value of its data

    View Slide

  28. Structuring Code

    View Slide

  29. Modularization
    Structuring Code
    • Have a set of rules and guidelines

    • Split APIs and Implementation

    View Slide

  30. Modularization
    Structuring Code
    / /
    in profile-api module


    interface Profile {


    fun isLoggedIn(): Boolean


    fun currentCustomer(): Customer?


    fun editCustomerIntent(context: Context): Intent?


    }


    View Slide

  31. Modularization
    Structuring Code
    / /
    in profile module


    class ProfileImpl constructor(


    private val profileRepository: ProfileRepository


    ) : Profile {


    override fun isLoggedIn(): Boolean = currentCustomer()
    !=
    null


    override fun currentCustomer(): Customer? {


    return profileRepository.provideCustomer()


    }


    override fun editCustomerIntent(context: Context): Intent {


    return Intent(context, EditProfileActivity
    :
    :
    class.java)


    }


    }

    View Slide

  32. Modularization
    Structuring Code
    / /
    in profile-noop module


    class ProfileNoop : Profile {


    override fun isLoggedIn(): Boolean = true


    override fun currentCustomer(): Customer =


    Customer(123L, "Test")


    override fun editCustomerIntent(context: Context) = null


    }

    View Slide

  33. Modularization
    Structuring Code
    fun provideProfile(): Profile {


    return if (isDebug) {


    ProfileNoop()


    } else {


    ProfileImpl(ProfileRepository())


    }


    }

    View Slide

  34. Benefits of Modularization
    Structuring Code
    • Better isolation of Features

    • Easier sharing

    • Easier and faster testing

    • Ability to stub implementations

    • Standalone apps

    View Slide

  35. Sharing Code Across Platforms

    View Slide

  36. How do we Save Time?

    View Slide

  37. Options
    Sharing Code Between Platforms
    • Frameworks that handle Everything

    • Do it yourself Tooling

    View Slide

  38. React Native

    View Slide

  39. 5 Part Series
    React Native at Airbnb

    View Slide

  40. Flutter

    View Slide

  41. Frameworks that Handle Everything
    Sharing Code Between Platforms
    • Pros

    • Potentially easier to hire for

    • Write once, use everywhere

    • Faster development (hot reload, etc)

    • Potential for hot loading code

    View Slide

  42. Frameworks that Handle Everything
    Sharing Code Between Platforms
    • Cons

    • Need to explicitly build separate UI for iOS and Android

    • Doesn’t “feel” native irrespective

    • New platform features are di
    ffi
    cult to adopt - need to wait

    • Overhead on binary size

    • Rejections Likely

    View Slide

  43. C/C++

    View Slide

  44. C/C++
    Sharing Code Between Platforms
    • Pros

    • High performance

    • Easier to obfuscate code

    View Slide

  45. C/C++
    Sharing Code Between Platforms
    • Cons

    • Di
    ffi
    cult

    • Still have to handle di
    ff
    erences between platforms

    • Custom development environment

    View Slide

  46. Dropbox Blog Post
    The (not so) hidden cost of sharing code
    between iOS and Android

    View Slide

  47. Kotlin Multiplatform

    View Slide

  48. Kotlin Multiplatform
    Sharing Code Between Platforms
    • Pros

    • Completely native

    • Easy to learn for engineers writing Swift

    • Lots of third party libraries

    • Backed by JetBrains and Google

    • Supports a plethora of platforms

    View Slide

  49. Kotlin Multiplatform
    Sharing Code Between Platforms
    • Cons

    • iOS inter-op with Objective-C instead of Swift

    • Convincing iOS Engineers is Di
    ffi
    cult

    • Tooling

    • Still in the process of maturing

    View Slide

  50. Alternatives

    View Slide

  51. Alternatives
    Sharing Between Platforms
    • Code generation

    • Annotation processors

    • Compiler plugins, Gradle plugins

    • Templating code generators (Stencil, …)

    View Slide

  52. Sharing Code
    Generating Code
    component:


    name: Car


    fields:


    make: string


    model: string


    vin: string


    vendor: string

    View Slide

  53. Sharing Code
    Generating Code
    data class Car(


    val make : String,


    val model : String,


    val vin : String,


    val vendor : String,


    )

    View Slide

  54. Sharing Code
    Generating Code
    struct Car {


    let make: String


    let model: String


    let vin: String


    let vendor: String


    }

    View Slide

  55. Sharing Code
    Generating Code
    data class {{ component.name }}(


    {% for key, value in component.fields %}


    val {{ key | lowerFirstLetter }} : {{ value | upperFirstLetter }},


    {% endfor %}


    )


    View Slide

  56. Sharing Code
    Generating Code
    struct {{ component.name }} {


    {% for key, value in component.fields %}


    let {{ key | lowerFirstLetter }}: {{ value | upperFirstLetter }}


    {% endfor %}


    }

    View Slide

  57. What to Share

    View Slide

  58. Things to Share
    Sharing Between Platforms
    • Analytics

    • Business Logic

    • Vocabulary

    • Architecture

    • Design System

    • Versioning

    • Release Process

    View Slide

  59. CI/CD

    View Slide

  60. Catching Mistakes Early Saves


    Time and Money

    View Slide

  61. First Lines of Defense
    Catching Issues Early
    • The build process itself

    • Automated checkers

    • Lint

    • Code styling enforcers

    • Code smell detection

    • Coverage

    • Code Review helps catch issues early

    View Slide

  62. Tests
    Catching Issues Early
    • Tests

    • Unit Tests

    • Integration Tests

    • On-Device Integration Tests (“UI Tests”)

    • Screenshot Tests

    • Maestro Tests

    View Slide

  63. Expose Hidden Changes
    Catching Issues Early
    • Transitive Dependencies

    View Slide

  64. Dependency-Diff-Tldr
    Exposing Hidden Changes
    Upgraded Dependencies

    com.squareup.moshi:moshi-adapters:1.14.0, (changed from 1.13.0)

    org.jetbrains.kotlin:kotlin-stdlib:1.7.20, (changed from 1.7.10)

    org.jetbrains.kotlin:kotlin-stdlib-common:1.7.20, (changed from 1.7.10)

    org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.20, (changed from 1.7.10)

    org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.20, (changed from 1.7.10)

    View Slide

  65. Expose Hidden Changes
    Catching Issues Early
    • Transitive Dependencies

    • Binary Size

    View Slide

  66. Diffuse
    Exposing Hidden Changes
    │ compressed │ uncompressed


    ├───────────┬───────────┬──────────┼───────────┬───────────┬──────────


    APK │ old │ new │ diff │ old │ new │ diff


    ──────────┼───────────┼───────────┼──────────┼───────────┼───────────┼──────────


    dex │ 11.6 MiB │ 11.6 MiB │ -107 B │ 29.4 MiB │ 29.4 MiB │ -336 B


    arsc │ 1.8 MiB │ 1.8 MiB │ -992 B │ 1.8 MiB │ 1.8 MiB │ -988 B


    manifest │ 5.6 KiB │ 5.6 KiB │ +1 B │ 27.6 KiB │ 27.6 KiB │ 0 B


    res │ 1.1 MiB │ 1.1 MiB │ -3 KiB │ 1.3 MiB │ 1.3 MiB │ -4.8 KiB


    asset │ 404.2 KiB │ 404.2 KiB │ 0 B │ 678.6 KiB │ 678.6 KiB │ 0 B


    other │ 173.6 KiB │ 173.1 KiB │ -550 B │ 336.9 KiB │ 335.7 KiB │ -1.3 KiB


    ──────────┼───────────┼───────────┼──────────┼───────────┼───────────┼──────────


    total │ 15.1 MiB │ 15.1 MiB │ -4.6 KiB │ 33.5 MiB │ 33.5 MiB │ -7.4 KiB


    View Slide

  67. Expose Hidden Changes
    Catching Issues Early
    • Transitive Dependencies

    • Binary Size

    • Binary compatibility breaking changes

    View Slide

  68. Binary Compatibility Validator
    Exposing Hidden Changes
    FAILURE: Build failed with an exception.


    * What went wrong:


    Execution failed for task ':miniapp:apiCheck'.


    > API check failed for project miniapp.


    --- /bitrise/src/miniapp/api/miniapp.api


    +++ /bitrise/src/miniapp/build/api/miniapp.api


    @@ -16,6 +16,7 @@




    public abstract interface class com/careem/superapp/lib/miniapp/
    IntegrationDependencies {


    public abstract fun provideEventBus ()Lcom/careem/
    superapp/lib/eventbus/EventBus;


    + public abstract fun provideLocationPickerSdk ()Lcom/
    careem/globalexp/locations/api/LocationPickerSdk;


    }




    You can run :miniapp:apiDump task to overwrite API declarations

    View Slide

  69. Expose Hidden Changes
    Catching Issues Early
    • Transitive Dependencies

    • Binary Size

    • Binary compatibility breaking changes

    • Permissions

    View Slide

  70. Expose Hidden Changes
    Tooling
    • di
    ff
    use

    • dependency-di
    ff
    -tldr / dependency-guard

    • metalava-gradle / binary-compatibility-validator

    View Slide

  71. Releases
    Catching Issues Early
    • Beta program

    • Staged rollouts to production

    • Release early, release often

    • Release should be a train, not a bus

    View Slide

  72. Dashboards and Data
    Catching Issues Early
    • Do not hide crashes

    • Handled exceptions and breadcrumbs are useful

    • Developer and performance metrics

    • Development Tooling

    • Chucker

    • LeakCanary

    View Slide

  73. Engineering Culture

    View Slide

  74. Engineers are Humans
    Engineering Cultures
    • All humans make mistakes

    • Blame is bad

    • Blame is the enemy of ownership

    View Slide

  75. When Issues Arise
    Engineering Cultures
    • How could this have been prevented?

    • Why was this not caught earlier?

    • Combine
    fi
    xes with veri
    fi
    cation tests.

    • Post mortem

    View Slide

  76. Keep Learning and Improving

    View Slide

  77. Focus on Impact

    View Slide

  78. Android Mid Level Roles Android Senior Level Roles
    We are hiring! 🤖

    View Slide

  79. Thank You

    View Slide