Slide 1

Slide 1 text

A story about mobile navigation in Deezer for Windows Christopher Maneu Brown Bag Lunch @ Deezer 16/09/2015

Slide 2

Slide 2 text

Why talking about navigation ? • Complex subject • Few guidances when your app scale (whenever the platform)

Slide 3

Slide 3 text

Our requirements  Views should not navigate to views  Unified way to address a view  Being able to deeplink to a view  Being able to change the view on the fly (gatekeeping, A/B testing, …)  Integrate well in to the framework(s)

Slide 4

Slide 4 text

Our path

Slide 5

Slide 5 text

public void OnAlbumsButtonClicked() { } Windows Phone navigation 101 NavigationService.NavigateTo(new Uri("/Pages/AlbumsPage.xaml", UriKind.Relative)); ×Views should not navigate to views ×Unified way to address a view ×Being able to deeplink to a view ×Being able to change the view on the fly (gatekeeping, A/B testing, …) √ Integrate well in to the framework(s)

Slide 6

Slide 6 text

Deeplink all the things

Slide 7

Slide 7 text

Deeplink all the things • The ViewModel / Activity / Controller is responsible to construct all the navigation URIs • A User control gets this URI and perform navigation on tap • We implement an UriMapper ! dz://mylibrary/albums => /Pages/AlbumsPage.xaml The Windows Phone Frame accepts an UriMapper

Slide 8

Slide 8 text

Deeplink all the things √ Views should not navigate to views √ Unified way to address a view × Being able to deeplink to a view √ Being able to change the view on the fly (gatekeeping, A/B testing, …) √ Integrate well in to the framework(s)

Slide 9

Slide 9 text

Our path

Slide 10

Slide 10 text

public void OnAlbumsButtonClicked() { } Windows 8 Navigation 101 NavigationService.NavigateTo( typeof(AlbumPage) ); ×Views should not navigate to views (WE NAVIGATE TO VIEW CLASS !!) ×Unified way to address a view ×Being able to deeplink to a view ×Being able to change the view on the fly (gatekeeping, A/B testing, …) √ Integrate well in to the framework(s)

Slide 11

Slide 11 text

Windows 8 Navigation, Reinvented dz://mylibrary/albums => typeof(AlbumsPage)

Slide 12

Slide 12 text

Windows 8 Navigation, Reinvented √ Views should not navigate to views √ Unified way to address a view × Being able to deeplink to a view √ Being able to change the view on the fly (gatekeeping, A/B testing, …) √ Integrate well in to the framework(s)

Slide 13

Slide 13 text

Our path

Slide 14

Slide 14 text

The case of unexplained • A bug into Windows Phone navigation Framework • Causes random crashes • Several months of investigation • => WP Nav. Fw. Does not support Absolute URIs navigations within the app… • Dz://mylibrary/albums replaced by /MyLibrary/Albums

Slide 15

Slide 15 text

Our path

Slide 16

Slide 16 text

The union of the deeplinks • One code to handle in-app and out-app deeplinks • A unified way to get parameters (from URI and query parameters)

Slide 17

Slide 17 text

The union of the deeplinks

Slide 18

Slide 18 text

The union of the deeplinks new DeezerUriMapping { UriRegex = DeezerRuntimeSettings.BaseDeepLinkUrlRegEx + "?([a-z]*)?\\/album\\/(?[0-9]*)", MappedUriTemplate = "/Pages/AlbumPage.xaml?id={id}", AutoMapQueryStringParameters = false });

Slide 19

Slide 19 text

The union of the deeplinks √ Views should not navigate to views √ Unified way to address a view √ Being able to deeplink to a view √ Being able to change the view on the fly (gatekeeping, A/B testing, …) √ Integrate well in to the framework(s)  Pass object instances between views

Slide 20

Slide 20 text

Our path

Slide 21

Slide 21 text

Deeplinks & Friends AlbumPageDescriptor PageType: type Mappings: string[] PageToken: PageToken Enum

Slide 22

Slide 22 text

Deeplinks & Friends I want to navigate to a view / an URI _navigationService.Navigate(protocolArgs.Uri.Origina lString, null); I want to navigate to a view, but I already have this object _navigationService.Navigate(PageTokens.AlbumPage, currentAlbum);

Slide 23

Slide 23 text

What’s next ? AOP ? [Deeplink("deezer://album/(?\w+)", "deezer://www.deezer.com/album/(?\w+)")] [PageDescriptor(PageDescriptor.AlbumPage)] public class AlbumPage { }