Mobile Developers Talks: Delve Mobile

  • View

  • Download

Embed Size (px)

Text of Mobile Developers Talks: Delve Mobile

PowerPoint Presentation

Office Delve for Office 365Konstantin Loginov

1About me7 years in Mobile development:Windows MobilewebOSWindows Phone 7/8iOS (native/Xamarin)Android

Current Position: Software Engineer in Microsoft

LinkedIn / email

2Office DelveFlipboard for Office365 Code name: OsloTangled creation story

3Steps towards Delve Mobile

4Steps towards Delve Mobile

Started as a team of twoAndroid firstPivoted multiple times & created various MVPsApplication as an engagement driver for the whole service

5DevelopmentWorking processNon-formal Scrum, 2-weeks-long sprintBi-weekly releasesTeam Foundation Server 2013 for task trackingSlack for team collaboration (love it!)GIT as revision control systemAndroid studio (latest Canary build) as an IDEInternal tool for bug-tracking and code reviewsOneNote as a knowledge baseToday: 4 Android devs & 3.5 iOS devs

7We love opensourceDagger (dependency injection)ButterKnife (view injection)EventBusRetrofitOkHttpPicassoEsty StaggeredGridViewCompatibility libs

Upcoming: Mortar & Flow. (As others, we Square )

Mockito (Testing)AssertJ (Testing)8Design patterns we useDependency injectionPublishsubscribe patternData Access Object

9Dependency Injection

10Dependency Injection - Daggerclass DataProvider { DataSource dataSource = new DelveApi();}class DataProvider { @Inject DataSource dataSource;}

11class DataProvider { private DataSource dataSource; @Inject DataProvider(DataSource dataSource) { this.dataSource = dataSource; }}11Dependency Injection - DaggerStandard javax.inject annotations (JSR-30)Need to declare modules for compile-time validation and code generationSpecifies provider methods@Singleton annotationLists supported classes (which in turn generates code)Supports overrideInject mocks in testsSubstituting back-ends is a one-line change

12Dependency Injection - Dagger 2Just releasedNo reflection, no ObjectGraph/Injector, @Component interfaceWere planning to switch to it soon

13Publishsubscribe pattern - EventBusWe use greenrobot/EventBusPerforms well with Activities, Fragments, and background threadsDecouples event senders and receiversAvoids complex and error-prone dependencies and life cycle issues

14Activity(hosts fragments)

Data Access Layer(Subscriber)Fragment A

Fragment B

DataData SubscriberGet DataError SubscriberERRORNavigation Event SubscriberOpen Fragment BData SubscriberOpen Fragment ADataGet Data15Data Access ObjectDAO isanobjectthat provides an abstractinterfaceto the database. By mapping application calls to the persistence layer, DAO provides specific data operations without exposing details of the database.

UserUser getById(String userId)List queryMatch(String q, int l, int o)SqlLocalStorageUserDaoUser getById(String userId) { /* Getting data from SQLite */}

List queryMatch(String q,int l,int o) { /* Getting data from SQLite */}UserDaoImplDataProvider Layer.localStorage.getUser(userId);.UserDao userDao;

User getUser(String userId) { return userDao.getUserById(userId);}String userId;16





Pinterest-style navigation modelV1

Pros:Gestures between tabsEasy to implement

Cons:3 heavy pages in ViewPagerNo Tab-switching-buttons in Profile/Document pages25


Pinterest-style navigation modelV2

Pros:Still easy to implementPretty effectiveTab-buttons everywhere

Cons:No gesturesNot keeping state of not-selected tab-fragments29


Pinterest-style navigation modelV3 (current)

Pros:Should be familiar for instagram users

Cons:Ugly in implementationBreaking OS design-guidelines34Pinterest-style navigation model Going forwardV4 (future)

Yeah! We like changes in Navigation model

Side nav as the way of switching between pivotsMaterial design35TestingTestingManual testingAlpha & Beta programsUnit tests (Test Coverage 75+%)MockitoAssertJMonkey testing( adb shell monkey -p -v 10000 )Memory profiling37MockitoMocks made easyDont expect before the fact; query object afterwardsSimple to useStages of a testSetup (as necessary)TestVerification

3838Mockito: Verify Interactions// mock creationList mockedList = mock(List.class);

// using mock object; observe that it didn't throw any// "unexpected interaction exception" exceptionmockedList.add("one");mockedList.clear();

// selective & explicit verificationverify(mockedList).add("one");verify(mockedList).clear();

39Mockito: Verify Interactions 2verify(mockedList, times(2)).add("one");verify(mockedList, atLeastOnce()).add("one");verify(mockedList, never()).clear();

40Mockito: Stub Method Calls// you can mock concrete classes, not only interfacesLinkedList mockedList = mock(LinkedList.class);// stubbing; before the actual executionwhen(mockedList.get(0)).thenReturn("first");// the following prints "first"System.out.println(mockedList.get(0));// the following prints "null" because get(999) was not stubbedSystem.out.println(mockedList.get(999));41Mockito: Advanced FeaturesSpy: Partial stubbing of real object through proxyMocking by annotationArgument matching42AssertJ: Readable AssertsRegular JUnitassertEquals( View.GONE, view.getVisibility());AssertJ AndroidassertThat(view).isGone();

43public static final int GONE = 0x00000008;AssertJ: Readable Assert ChainingRegular JUnitassertEquals(View.VISIBLE, layout.getVisibility());

assertEquals(VERTICAL, layout.getOrientation());

assertEquals(4, layout.getChildCount());

assertEquals(SHOW_DIVIDERS_MIDDLE, layout.getShowDividers());

AssertJ AndroidassertThat(layout) .isVisible() .isVertical() .hasChildCount(4) .hasShowDividers( SHOW_DIVIDERS_MIDDLE);

44Analytics & CrashaliticsWe use (on both platforms):Crittercism ( ( (

Data reviewed daily45CrittercismAutomated Crash loggingAutomated network request loggingBreadcrumbsHandled exceptions loggingAlarms & lifetime dashboardlatency error raterequest volume

46Crittercism: casesDelve Mobile crashed 44 times (14-26 April)Our crash rate:Average crash rate:

47Crittercism: our crashesMost popular crash (50+% of total number):

Breadcrumbs we got:

48MixPanelFunnelsUser-eventsMeasure users retention & engagement

49Feedback we got

Feedback we got through feedback-form:Disabling notifications feature-requestEmpty documents feed issues50Things we learnCross-platform design does not workSquare rocksMajority of our users are using Android 5.0+Learn about your users before start: majority of our users are using iOS (~1:3)Fragments are badCrittercism is amazing