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

How not to fuckup with building mobile SDK and make clients happy

How not to fuckup with building mobile SDK and make clients happy

Presentation from GDG DevFest Nantes 2017
More information at: https://devfest.gdgnantes.com/

Abstract:
Are you working on the client library? Or design a public API for the module that is going to be used by other team or department?

In this session, Vitality will share his experience and key learnings from building a mobile SDKs for last 4 years.

Vitaliy Zasadnyy

October 19, 2017
Tweet

More Decks by Vitaliy Zasadnyy

Other Decks in Technology

Transcript

  1. @zasadnyy
    With building the mobile SDK
    How not to Fuck Up
    Vitaliy Zasadnyy
    Head of Mobile @ GetSocial

    View Slide

  2. @zasadnyy
    Integrated SDK.
    But it doesn’t work.

    View Slide

  3. Developer.
    GDG Lead.
    Public Speaker.
    @zasadnyy

    View Slide

  4. View Slide

  5. View Slide

  6. View Slide

  7. SDK Lifecycle

    View Slide

  8. @zasadnyy
    SDK Lifecycle
    Develop
    1

    View Slide

  9. @zasadnyy

    View Slide

  10. @zasadnyy
    SDK Lifecycle
    Develop
    1

    View Slide

  11. @zasadnyy
    SDK Lifecycle
    Develop
    1
    Integrate
    2
    Support
    3
    Update
    4

    View Slide

  12. Develop
    1

    View Slide

  13. @zasadnyy
    Start shaping your API
    Use Cases
    Examples
    Integration Tests

    View Slide

  14. @zasadnyy
    Cost of fixing API

    View Slide

  15. @zasadnyy
    Cost of fixing API
    Spend 10x more time
    on line of examples
    comparing to
    production code

    View Slide

  16. @zasadnyy
    NOT SURE?
    DROP IT!

    View Slide

  17. @zasadnyy
    IS BETTER
    LESS CODE

    View Slide

  18. @zasadnyy
    Boilerplate ➡ Copy/Paste ➡ Bugs
    Why?

    View Slide






  19. android:name="im.getsocial.sdk.invites.ImageContentProvider"
    android:name="im.getsocial.sdk.AppId"
    android:value="LuDPp7W0J4"/>









    GetSocial.init()

    View Slide






  20. android:name="im.getsocial.sdk.invites.ImageContentProvider"
    android:name="im.getsocial.sdk.AppId"
    android:value="LuDPp7W0J4"/>









    View Slide

  21. @zasadnyy
    How to solve?
    AndroidManifest merging
    Gradle plugin
    Android Studio plugin

    View Slide

  22. @zasadnyy
    Gradle plugin
    apply plugin: 'im.getsocial'
    getsocial {
    appId "LGa80P9790xsg4"
    }

    View Slide

  23. @zasadnyy
    Auto initialisation
    android:name="im.getsocial.AutoInitContentProvider"
    android:authorities="..."
    android:exported="false" />

    View Slide

  24. @zasadnyy
    IS BETTER
    LESS CODE

    View Slide

  25. @zasadnyy
    API SURPRISES
    AVOID

    View Slide

  26. @zasadnyy
    Avoid API surprises
    Thread.interrupted()
    Returns the current interrupted status
    and then clears it

    View Slide

  27. @zasadnyy
    Avoid API surprises

    View Slide

  28. @zasadnyy
    Avoid API surprises
    Thread.interrupted()
    Returns the current interrupted status
    and then clears it

    View Slide

  29. @zasadnyy
    Make API of your library
    as boring as possible
    - Chris Sells, Google

    View Slide

  30. @zasadnyy
    ?
    Library is crashing
    you app?

    View Slide

  31. @zasadnyy

    View Slide

  32. @zasadnyy
    CRASH HOST APP
    NEVER

    View Slide

  33. @zasadnyy
    GetSocial approach
    Rx
    Development Mode
    @Nullable / PMD / FindBugs / Lint

    View Slide

  34. @zasadnyy
    Rx chains
    Observable
    .just(MetaDataKey.APP_ID)
    .map(ValidateAppIdFunc.create())
    .flatMap(TrackInstallFunc.create())
    ...
    .subscribe((result) -> { ... },
    (throwable) -> {
    // all exceptions end up here
    }
    );

    View Slide

  35. @zasadnyy
    Rx chains
    Observable
    .just(MetaDataKey.APP_ID)
    .map(ValidateAppIdFunc.create())
    .flatMap(TrackInstallFunc.create())
    ...
    .subscribe((result) -> { ... },
    (throwable) -> {
    // all exceptions end up here
    }
    );

    View Slide

  36. @zasadnyy

    View Slide

  37. @zasadnyy
    INTERNALS
    HIDE

    View Slide

  38. @zasadnyy
    Hide internals

    View Slide

  39. @zasadnyy
    Hide internals
    Use .internal package
    Keep everything private by default

    View Slide

  40. @zasadnyy
    There is much more!

    View Slide

  41. Integrate

    View Slide

  42. @zasadnyy
    ?
    What is important
    to developers?

    View Slide

  43. @zasadnyy
    SIZE

    View Slide

  44. @zasadnyy
    List information about
    Library size
    Method count
    Proguard rules

    View Slide

  45. @zasadnyy
    COMPATIBILITY

    View Slide

  46. @zasadnyy
    Keep compatibility
    Select minimum supported platform version.
    After detailed market research
    Update maximum supported version.
    Continuously

    View Slide

  47. @zasadnyy
    SUPPORT

    View Slide

  48. @zasadnyy
    Give a voice to your users
    GitHub issue tracker
    Intercom
    Support email

    View Slide

  49. @zasadnyy
    Get ready to repetitive
    questions

    View Slide

  50. @zasadnyy
    DOCS

    View Slide

  51. @zasadnyy
    Documentation is like sex.
    Even bad is better than nothing

    View Slide

  52. @zasadnyy
    Key parts
    Step by step tutorials
    Product guides
    API Reference

    View Slide

  53. @zasadnyy

    View Slide

  54. @zasadnyy

    View Slide

  55. @zasadnyy

    View Slide

  56. @zasadnyy
    What is wrong with snippet?
    CurrentUser user = getSocial.getCurrentUser();

    View Slide

  57. @zasadnyy
    What is wrong with snippet?
    CurrentUser user = getSocial.getCurrentUser();

    View Slide

  58. @zasadnyy
    ALL SNIPPETS MUST
    COMPILE

    View Slide

  59. @zasadnyy
    Better snippet
    import im.getsocial.sdk.GetSocial;
    import im.getsocial.sdk.CurrentUser;
    ...
    CurrentUser user =
    GetSocial.getInstance().getCurrentUser();

    View Slide

  60. @zasadnyy
    There is more
    GitHub Wiki, MkDocs, Jekyll
    Google Developer Documentation
    Style Guide

    View Slide

  61. @zasadnyy
    ?
    Favourite source
    of copy / paste code?

    View Slide

  62. @zasadnyy

    View Slide

  63. @zasadnyy
    DEMOS

    View Slide

  64. @zasadnyy
    Demo apps
    Make demos well documented
    Keep SDK integration code separated

    View Slide

  65. Support

    View Slide

  66. @zasadnyy
    ?
    You’ve got support request.
    Now what?

    View Slide

  67. @zasadnyy
    Two types of problems
    Integration time
    problems
    End-user side
    problems

    View Slide

  68. @zasadnyy
    Solving integration time problems
    Easy way to get SDK version
    Unique log tag
    Debug SDK configuration
    Actionable errors

    View Slide

  69. @zasadnyy
    Debug SDK configuration
    adb shell setprop \
    debug.getsocial.sdk.app com.demo

    View Slide

  70. @zasadnyy
    Actionable errors
    public class GetSocialException
    extends RuntimeException {
    private final int _errorCode;

    }

    View Slide

  71. @zasadnyy
    Actionable errors
    public class GetSocialException
    extends RuntimeException {
    private final int _errorCode;

    }

    View Slide

  72. @zasadnyy
    Solving end-user side problems
    Comprehensive logs
    Errors analytics

    View Slide

  73. @zasadnyy
    Solving end-user side problems
    void trackError(GetSocialException exception) {
    ...
    AnalyticsTrackManager.trackAnalyticsEvent(
    AnalyticsEventDetails.Name.SDK_ERROR,
    eventProperties);
    }

    View Slide

  74. @zasadnyy

    View Slide

  75. @zasadnyy

    View Slide

  76. @zasadnyy
    s
    THINK ABOUT SUPPORT
    AHEAD

    View Slide

  77. Update

    View Slide

  78. @zasadnyy
    ?
    Why developers update
    SDKs?

    View Slide

  79. @zasadnyy
    Update. Build. And…

    View Slide

  80. @zasadnyy

    View Slide

  81. @zasadnyy
    UPDATES
    SMOOTH

    View Slide

  82. @zasadnyy
    Backward compatibility
    Use @Deprecation cycle
    /**
    * @deprecated use {@link #getAllIdentities()} instead.
    * Method will be removed in SDK v5.0.0.
    */
    @Deprecated
    public List getIdentities() { ... }

    View Slide

  83. @zasadnyy
    Semantic versioning
    v4.5.1
    Major Minor Bugfix

    View Slide

  84. @zasadnyy
    Versioned packages
    import okhttp3;
    import im.getsocial.sdk6;

    View Slide

  85. @zasadnyy
    Versioned packages
    import okhttp3;
    import im.getsocial.sdk6;
    Partial transition
    A/B testing

    View Slide

  86. @zasadnyy
    Changelog
    Fixed issues
    New features
    Deprecations
    Upgrade guide

    View Slide

  87. @zasadnyy

    View Slide

  88. To sum up

    View Slide

  89. @zasadnyy
    PER APP
    17 SDKs
    Source: Safe SDK

    View Slide

  90. @zasadnyy
    SDK Lifecycle
    Develop
    1

    View Slide

  91. @zasadnyy
    SDK Lifecycle
    Develop Integrate Support Update
    1 2 3 4

    View Slide

  92. @zasadnyy
    API can be you biggest asset
    of liability
    - Joshua Bloch
    Put yourself
    in your customer’s shoes
    - Cesare Rocchi

    View Slide

  93. @zasadnyy
    Happy dog
    Make developers
    happy again.

    View Slide

  94. @zasadnyy
    @zasadnyy / zasadnyy.com
    Questions?
    Merci!

    View Slide