Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

Betclic Feedback Xamarin Hugo Mercier Laurent Dutrillaux

Slide 3

Slide 3 text

• Business context • Technical context • Our Xamarin journey • Some figures • 4 technicals bullet points – Webview – Performances – Xamarin test cloud – Monitoring • What’s our feeling right now ? Agenda N° 3

Slide 4

Slide 4 text

Contexts

Slide 5

Slide 5 text

Business Context Multi , multi, multi , … N° 5 Multi-brand Multi-device Multi-law

Slide 6

Slide 6 text

Technical context We love microsoft, but … N° 6 • Sites Web • ASP.NET MVC 4 • Web Apps • Angular Js • Web API • Asp.Net webapi Mvc REST • Mobile Apps legacy

Slide 7

Slide 7 text

we could talk about one hour N° 7 V S V S

Slide 8

Slide 8 text

• Better than the legacy + new features • Same UI between Android and iOS • Share code, copy/paste forbidden • 100% dynamic data • Auto-refresh on all pages • Custom controls • No knowledge in native frameworks The Mission N° 8

Slide 9

Slide 9 text

• Xamarin native • MvvmCross • Xamarin university & MvvmCross tutorials • 7 to 10 developpers + 3 skilled Xamarin contractors • 2 years • 45876 cups of coffee ➔ 8 apps on the market !! Our Xamarin Journey N° 9

Slide 10

Slide 10 text

Demo N° 10

Slide 11

Slide 11 text

Some figures

Slide 12

Slide 12 text

Some figures Code metrics, target repartition N° 12

Slide 13

Slide 13 text

Some figures Multi-branding N° 13

Slide 14

Slide 14 text

Webviews

Slide 15

Slide 15 text

Advantages : • No migration required to native app • Always up-to-date Webview Why ? N° 15

Slide 16

Slide 16 text

Webview Sharing data N° 16 Webvie w Native • Cookies : authentification, current language • Localstorage (only iOS) : ressources

Slide 17

Slide 17 text

Webview Interaction web to native N° 17 Webview Native Intercept javascript events ● Login / Logout ● Deposit / Withdrawal

Slide 18

Slide 18 text

Webview Optimization N° 18 Webview Native Intercept out-going ajax request Data already available ?

Slide 19

Slide 19 text

Webview Debug Android with Chrome N° 19

Slide 20

Slide 20 text

Webview Debug iOS with Safari N° 20

Slide 21

Slide 21 text

Resilience and Quickness

Slide 22

Slide 22 text

The best App is: ● Fast ● Resilient ● Stable / Always up Your App could be the best one or appears like the best one. User eXperience will be the same but the underlying implementation (paradigm) will be different. Resilience and Quickness N° 22

Slide 23

Slide 23 text

Detect what is taking time : External data/resources access ● Reduce the number of Http calls ○ Grouping http requests into batch requests Custom implementation of batch request in PCL ○ Scenario Driven Design API Resilience and Quickness N° 23

Slide 24

Slide 24 text

Detect what is taking time : External data/resources access ● Catching network ○ Avoid useless network calls MVVMCross Connectivity plugin ● Anticipate user navigation / Use speculative requests ○ Bootstrap your Apps ○ Load in background the screens the user should see Resilience and Quickness N° 24

Slide 25

Slide 25 text

Detect what is taking time : External data/resources access ● Don't ask for data you already get ○ json - Cache Web Api response ○ Images - Cache downloaded resources ● Caches ○ Local instance of noSQL databases like SQLite (Beware of Android N) ○ file storage like MVVMCross plugin : DownloadCache Tips : Customize cache durations Beware of space usage and clean carefully Resilience and Quickness N° 25

Slide 26

Slide 26 text

Multi-Tasking : async / await ● To parallelize asynchronous traitements ● To release the UI thread when accessing an external resource Tips : ● error handling ● Fire and forget mode Resilience and Quickness N° 26

Slide 27

Slide 27 text

To be resilient, you need to handle specific states in lifecycle of Apps depending of the platform you target ● Deshydratation ● Tombstoning ● Killed Resilience and Quickness N° 27

Slide 28

Slide 28 text

Lifecycle of Apps Resilience and Quickness N° 28

Slide 29

Slide 29 text

Stability Dispose() or not Dispose() ○ Weak references ○ Beware of the System objects ○ Depends of the platform Defensive code ○ null pattern ○ null test Resilience and Quickness N° 29 Multiple version ○ API versions ○ Apps versions

Slide 30

Slide 30 text

Stability Handle errors ○ Managed errors ○ Unmanaged errors ○ Android - handle JVM errors ○ iOS - handle OS errors ○ TPL - TaskScheduler.UnobservedTaskException Predict the worst case and handle it ○ avoid UI Thread errors Resilience and Quickness N° 30

Slide 31

Slide 31 text

Xamarin Test cloud

Slide 32

Slide 32 text

• Cloud based solution to run UI tests on multiples real devices • Website interface • Write tests in C# • Xamarin.UITest is the automation library • Require a dedicated build for iOS to include Calabash Xamarin Test Cloud N° 32

Slide 33

Slide 33 text

Xamarin Test Cloud How it works ? N° 33

Slide 34

Slide 34 text

XTC N° 34

Slide 35

Slide 35 text

XTC N° 35

Slide 36

Slide 36 text

XTC N° 36

Slide 37

Slide 37 text

XTC N° 37

Slide 38

Slide 38 text

XTC N° 38

Slide 39

Slide 39 text

[Test] public void I_Can_See_Popular_Bets_On_Home_Page() { SportApp.HomePage.Go().GoToPopularBetsPage(); } XTC Write tests N° 39

Slide 40

Slide 40 text

XTC Write tests N° 40 Fluent Page Object Pattern in Automated Testing public HomePage Go() { Phone.Tap(NavigationBarHome); Phone.Screenshot("on home page"); return this; } public HomePage GoToPopularBets() { Phone.ScrollDownTo(PopularMarketsGroupHeader, HomeMainList); return this; } Xamarin UiTest FrameWork Ids

Slide 41

Slide 41 text

Android : Id iOS : AccessibilityIdentifier txtView.AccessibilityIdentifier ="sport_popular_header_item"; XTC Add Locators N° 41

Slide 42

Slide 42 text

Monitoring

Slide 43

Slide 43 text

• Blindness is failure • Needs to collect crash reports • Needs to know the path to reproduce the crash Features • Crash reporting • Custom report Xamarin Insight N° 43

Slide 44

Slide 44 text

Xamarin Insight Create your repositories • Per environment • Per Apps N° 44

Slide 45

Slide 45 text

Adding data to reports Xamarin Insight N° 45

Slide 46

Slide 46 text

Aggregated reports by call stacks Filtering functionalities Xamarin Insight N° 46

Slide 47

Slide 47 text

Xamarin Insight Call stack with threads details Evolution on timeline User path to the crash Status of the issue N° 47

Slide 48

Slide 48 text

Cross platform call stacks Xamarin Insight N° 48

Slide 49

Slide 49 text

Xamarin Insight When the issue arises, I have the tools to do the autopsy ○ Report ○ User path ○ Call stack ○ Trends ○ Status ○ Version ○ Additional data I’m able to reproduce the issue so I can fix it ! N° 49

Slide 50

Slide 50 text

Do you need to report all issues ? ● Functional issues ○ API evolution not compatible (should not happen) ● Technical issues ○ Corrupted local database ○ Disk full ● Mobility issues ○ Network issues (Subway) Xamarin Insight N° 50

Slide 51

Slide 51 text

VNext … Ongoing merge N° 51

Slide 52

Slide 52 text

Conclusion

Slide 53

Slide 53 text

Negative points ○ Solid training required ○ Difficult performance Monitoring Good points ○ Convergence / Code sharing ○ Dev C # => native Dev ○ Sharing communities C #, Android, iOS If we had to do it again ○ Keep Xamarin ○ Stay closer as possible to iOS and Android paradigms ○ Increasing complexity step by step, start simple Conclusion N° 53

Slide 54

Slide 54 text

N° 54

Slide 55

Slide 55 text

Xamarin • https://xamarin.com/ • https://insights.xamarin.com/ • https://xamarin.com/university MvvmCross • http://mvvmcross.com/ • https://mvvmcross.wordpress.com/ • https://github.com/MvvmCross/MvvmCross links Betclic • Site Web : https://www.betclic.fr/sport/ • Web App : https://m.betclic.fr/sport/ Expekt • Site Web : https://en.expekt.com/sport/ • Web App : https://m.expekt.com/sport/

Slide 56

Slide 56 text

Intervenants Betclic Hugo Mercier – [email protected] Laurent Dutrillaux – [email protected]

Slide 57

Slide 57 text

Code samples

Slide 58

Slide 58 text

Authentification, contexte (langage courant, devise,…) • Android • iOS Webview - cookies CookieManager.Instance.SetCookie(webviewUrl, "mon_cookie=ma_valeur"); NSHttpCookieStorage.SharedStorage.SetCookie(new NSHttpCookie("mon_cookie", "ma_valeur"));

Slide 59

Slide 59 text

Stockage d’un dictionnaire de labels traduits • Android • iOS Webview - Localstorage webView.AddJavascriptInterface (myDictionary, "androidLocalStorage"); Pas encore disponible

Slide 60

Slide 60 text

Connexion / déconnexion, dépôt / retrait • Android Webview - Communication web ➔ natif webView.AddJavascriptInterface(myInterfaceAndroid, "Android"); … [Export("mon_evenement")] [JavascriptInterface] public void monEvenement() { Execute(); }

Slide 61

Slide 61 text

• iOS Webview - Communication web ➔ natif myWebView.ShouldStartLoad = (webView, request, type) => { var url = request.Url.AbsoluteString; if (!url.StartsWith("ios://")) { return true; } ReactToWebViewMessage(url); return false; };

Slide 62

Slide 62 text

Utiliser des données déjà présentes en mémoire • Android Webview - Interception des requêtes sortantes public class MyViewClient : WebViewClient { public override WebResourceResponse ShouldInterceptRequest(WebView view, IWebResourceRequest request) { var urlString = request.Url.ToString().ToLower(); if (IsDataAlreadyInMemory(urlString)) return DataInMemory(urlString); return base.ShouldInterceptRequest(view, request); } }

Slide 63

Slide 63 text

• iOS Webview - Interception des requêtes sortantes public class MyInterceptor : NSUrlProtocol … [Export("canInitWithRequest:")] public static bool CanInitWithRequest(NSUrlRequest request) … public override void StartLoading() … NSUrlProtocol.RegisterClass(new ObjCRuntime.Class(typeof(MyInterceptor)));