Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

Source

Slide 3

Slide 3 text

Factors affecting Speed Things to Consider • Distractions

Slide 4

Slide 4 text

Source

Slide 5

Slide 5 text

Factors affecting Speed Things to Consider • Distractions • Communication Problems

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

Factors affecting Speed Things to Consider • Distractions • Communication Problems • Con fl icting Priorities

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

Factors affecting Speed Things to Consider • Distractions • Communication Problems • Con fl icting Priorities • Technical Debt

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

Factors affecting Speed Things to Consider • Distractions • Communication Problems • Con fl icting Priorities • Technical Debt • Production Fires

Slide 12

Slide 12 text

Source

Slide 13

Slide 13 text

Factors affecting Speed Things to Consider • Distractions • Communication Problems • Con fl icting Priorities • Technical Debt • Production Fires • Hardware

Slide 14

Slide 14 text

Source

Slide 15

Slide 15 text

Process Bottlenecks Mobile Bottlenecks • Company release process • Application store review process • Application store rejections • Adoptions take time

Slide 16

Slide 16 text

Experiments and Toggles

Slide 17

Slide 17 text

Tim Campos “Data wins Arguments”

Slide 18

Slide 18 text

Customer Behavior Understanding and Monitoring Customer Behavior • Dashboards • critical business statistics • conversion funnels • Slice by application version • Alerts

Slide 19

Slide 19 text

Dealing with Problems How to React to Problems • Ignore it for now • Hot Fix in Production • Release takes time • Adoption takes time • Risky

Slide 20

Slide 20 text

Source

Slide 21

Slide 21 text

What if we just turn it off?

Slide 22

Slide 22 text

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?

Slide 23

Slide 23 text

Data

Slide 24

Slide 24 text

Data Some odds and ends about Data • Building trust with Customers • Compliance • App Stores • Governments

Slide 25

Slide 25 text

Policy Changes are often a Surprise

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

Structuring Code

Slide 29

Slide 29 text

Modularization Structuring Code • Have a set of rules and guidelines • Split APIs and Implementation

Slide 30

Slide 30 text

Modularization Structuring Code / / in profile-api module interface Profile { fun isLoggedIn(): Boolean fun currentCustomer(): Customer? fun editCustomerIntent(context: Context): Intent? }

Slide 31

Slide 31 text

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) } }

Slide 32

Slide 32 text

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 }

Slide 33

Slide 33 text

Modularization Structuring Code fun provideProfile(): Profile { return if (isDebug) { ProfileNoop() } else { ProfileImpl(ProfileRepository()) } }

Slide 34

Slide 34 text

Benefits of Modularization Structuring Code • Better isolation of Features • Easier sharing • Easier and faster testing • Ability to stub implementations • Standalone apps

Slide 35

Slide 35 text

Sharing Code Across Platforms

Slide 36

Slide 36 text

How do we Save Time?

Slide 37

Slide 37 text

Options Sharing Code Between Platforms • Frameworks that handle Everything • Do it yourself Tooling

Slide 38

Slide 38 text

React Native

Slide 39

Slide 39 text

5 Part Series React Native at Airbnb

Slide 40

Slide 40 text

Flutter

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

C/C++

Slide 44

Slide 44 text

C/C++ Sharing Code Between Platforms • Pros • High performance • Easier to obfuscate code

Slide 45

Slide 45 text

C/C++ Sharing Code Between Platforms • Cons • Di ffi cult • Still have to handle di ff erences between platforms • Custom development environment

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

Kotlin Multiplatform

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

Alternatives

Slide 51

Slide 51 text

Alternatives Sharing Between Platforms • Code generation • Annotation processors • Compiler plugins, Gradle plugins • Templating code generators (Stencil, …)

Slide 52

Slide 52 text

Sharing Code Generating Code component: name: Car fields: make: string model: string vin: string vendor: string

Slide 53

Slide 53 text

Sharing Code Generating Code data class Car( val make : String, val model : String, val vin : String, val vendor : String, )

Slide 54

Slide 54 text

Sharing Code Generating Code struct Car { let make: String let model: String let vin: String let vendor: String }

Slide 55

Slide 55 text

Sharing Code Generating Code data class {{ component.name }}( {% for key, value in component.fields %} val {{ key | lowerFirstLetter }} : {{ value | upperFirstLetter }}, {% endfor %} )

Slide 56

Slide 56 text

Sharing Code Generating Code struct {{ component.name }} { {% for key, value in component.fields %} let {{ key | lowerFirstLetter }}: {{ value | upperFirstLetter }} {% endfor %} }

Slide 57

Slide 57 text

What to Share

Slide 58

Slide 58 text

Things to Share Sharing Between Platforms • Analytics • Business Logic • Vocabulary • Architecture • Design System • Versioning • Release Process

Slide 59

Slide 59 text

CI/CD

Slide 60

Slide 60 text

Catching Mistakes Early Saves Time and Money

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

Tests Catching Issues Early • Tests • Unit Tests • Integration Tests • On-Device Integration Tests (“UI Tests”) • Screenshot Tests • Maestro Tests

Slide 63

Slide 63 text

Expose Hidden Changes Catching Issues Early • Transitive Dependencies

Slide 64

Slide 64 text

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)

Slide 65

Slide 65 text

Expose Hidden Changes Catching Issues Early • Transitive Dependencies • Binary Size

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

Expose Hidden Changes Catching Issues Early • Transitive Dependencies • Binary Size • Binary compatibility breaking changes

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

Expose Hidden Changes Catching Issues Early • Transitive Dependencies • Binary Size • Binary compatibility breaking changes • Permissions

Slide 70

Slide 70 text

Expose Hidden Changes Tooling • di ff use • dependency-di ff -tldr / dependency-guard • metalava-gradle / binary-compatibility-validator

Slide 71

Slide 71 text

Releases Catching Issues Early • Beta program • Staged rollouts to production • Release early, release often • Release should be a train, not a bus

Slide 72

Slide 72 text

Dashboards and Data Catching Issues Early • Do not hide crashes • Handled exceptions and breadcrumbs are useful • Developer and performance metrics • Development Tooling • Chucker • LeakCanary

Slide 73

Slide 73 text

Engineering Culture

Slide 74

Slide 74 text

Engineers are Humans Engineering Cultures • All humans make mistakes • Blame is bad • Blame is the enemy of ownership

Slide 75

Slide 75 text

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

Slide 76

Slide 76 text

Keep Learning and Improving

Slide 77

Slide 77 text

Focus on Impact

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

Thank You