Slide 1

Slide 1 text

From Objective-C to Xamarin First impressions and common pitfalls Alexander Dodatko 2015

Slide 2

Slide 2 text

Xamarin == C# for Mobile

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

Xamarin's Promise One Codebase — Many Platforms

Slide 5

Slide 5 text

Native UI and UX

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

http://bit.ly/ 1xV1ATx

Slide 8

Slide 8 text

PCL - Portable Class Libraries A standard by M$ and Xamarin

Slide 9

Slide 9 text

Your Code Runs Everywhere If a platform has .NET

Slide 10

Slide 10 text

CI requires NO Simulator

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

Binary Packets

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

● Closures ● Optionals ● Namespaces ● Generics ● Type Safety ● Functional As Good as Swift

Slide 17

Slide 17 text

You can use exceptions And you should do so

Slide 18

Slide 18 text

Callback Hell http://bit.ly/ 11suEXP

Slide 19

Slide 19 text

http://bit.ly/ 1ryzV4Z

Slide 20

Slide 20 text

Async/Await

Slide 21

Slide 21 text

public class RestApiCallFlow { public static async Task LoadRequestFromNetworkFlow ( TRequest request, IRestApiCallTasks stages) { string requestUrl = await stages.BuildRequestUrlForRequestAsync(request); // TODO : check cache THttpResult serverResponse = await stages.SendRequestForUrlAsync(requestUrl); TResult parsedData = await stages.ParseResponseDataAsync(serverResponse); return parsedData; } } Async but Looks Linear

Slide 22

Slide 22 text

public class RestApiCallFlow { public static async Task LoadRequestFromNetworkFlow ( TRequest request, IRestApiCallTasks stages) { string requestUrl = await stages.BuildRequestUrlForRequestAsync(request); try { TResult parsedDataFromCache = await stages.LoadDataFromCacheForRequestAsync(request); return parsedDataFromCache; } catch { // Load from network code } } }

Slide 23

Slide 23 text

public interface IRestApiCallTasks { Task BuildRequestUrlForRequestAsync(TRequest request); Task SendRequestForUrlAsync(string requestUrl); Task ParseResponseDataAsync(THttpResult httpData); Task LoadDataFromCacheForRequestAsync(TRequest request); }

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

Is this lib portable?

Slide 27

Slide 27 text

Same API may Work Differently

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

Xamarin is Slow and has Lots of Memory Leaks From some holy war

Slide 30

Slide 30 text

using (var webclient = new WebClient()) { var imageBytes = webclient.DownloadData(url); return UIImage.LoadFromData(NSData.FromArray(imageBytes)); } http://bit.ly/ 1rMJL3B Image Loading : A Typical Implementation

Slide 31

Slide 31 text

No content

Slide 32

Slide 32 text

using (var webclient = new WebClient()) { var imageBytes = webclient.DownloadData(url); return UIImage.LoadFromData(NSData.FromArray(imageBytes)); } http://bit.ly/ 1rMJL3B Synchronous

Slide 33

Slide 33 text

using (var webclient = new WebClient()) { var imageBytes = webclient.DownloadData(url); return UIImage.LoadFromData(NSData.FromArray(imageBytes)); } http://bit.ly/ 1rMJL3B Leaks

Slide 34

Slide 34 text

http://bit.ly/1 cay6bO

Slide 35

Slide 35 text

http://bit.ly/1 cay6bO

Slide 36

Slide 36 text

What If I Told You...

Slide 37

Slide 37 text

All Obj-C/Java bindings are IDisposable

Slide 38

Slide 38 text

UIImage, NSData, sockets, threads

Slide 39

Slide 39 text

byte[] data = null; using (Stream response = await session.DownloadResourceAsync(request)) using (MemoryStream responseInMemory = new MemoryStream()) { await response.CopyToAsync(responseInMemory); data = responseInMemory.ToArray(); } BeginInvokeOnMainThread(delegate { using ( NSData imageData = NSData.FromArray(data) ) { using ( UIImage image = new UIImage(imageData) ) { this.ImageView.Image = image; } } }); http://bit.ly/ 1ukw1ii

Slide 40

Slide 40 text

byte[] data = null; using (Stream response = await session.DownloadResourceAsync(request)) using (MemoryStream responseInMemory = new MemoryStream()) { await response.CopyToAsync(responseInMemory); data = responseInMemory.ToArray(); } BeginInvokeOnMainThread(delegate { using ( NSData imageData = NSData.FromArray(data) ) { using ( UIImage image = new UIImage(imageData) ) { this.ImageView.Image = image; } } }); http://bit.ly/ 1ukw1ii

Slide 41

Slide 41 text

byte[] data = null; using (Stream response = await session.DownloadResourceAsync(request)) using (MemoryStream responseInMemory = new MemoryStream()) { await response.CopyToAsync(responseInMemory); data = responseInMemory.ToArray(); } BeginInvokeOnMainThread(delegate { using ( NSData imageData = NSData.FromArray(data) ) { using ( UIImage image = new UIImage(imageData) ) { this.ImageView.Image = image; } } }); http://bit.ly/ 1ukw1ii

Slide 42

Slide 42 text

No content

Slide 43

Slide 43 text

Xamarin.Forms

Slide 44

Slide 44 text

Aiming for a Single Codebase

Slide 45

Slide 45 text

Break their own Principles

Slide 46

Slide 46 text

Unlike other cross-platform mobile frameworks that only offer lowest common denominator experiences through UI abstraction libraries, we make 100% of the iOS and Android APIs available through our native bindings.

Slide 47

Slide 47 text

No content

Slide 48

Slide 48 text

Per Seat Per Platform

Slide 49

Slide 49 text

No content

Slide 50

Slide 50 text

Try it!

Slide 51

Slide 51 text

Test on All Platforms

Slide 52

Slide 52 text

Dispose Native Objects Aggressively

Slide 53

Slide 53 text

Build Dedicated GUI for Each Platform

Slide 54

Slide 54 text

Try it!