Xamarin Evolve 16 – Training Day 2

Time flies! The second day of training at Xamarin Evolve is over already and I just came back from the awesome opening party in the Darwin Lounge.

The main conference starts tomorrow. I’m honored to be on stage with some industry giants at the Evolve Mobile Leaders Summit track in a panel discussion about The Unique Challenges of Mobile DevOps. But that’s tomorrow!

About today: before the training, the day started at 6:15am (!) with a 5k test run with for the first Mini-Hack tomorrow morning. I spot an orange Xpirit T-shirt 🙂

The training part was another intense day from 9am-6pm, but it was a good day. I’d say the content of today was a bit better and deeper than what we learned yesterday, at least for me personally. We covered three major topics:

Securing local data
This part was all about dealing with data locally on the device, especially sensitive data in terms of privacy and security. We had a look at what the Xamarin.Auth component has to offer for local storage of sensitive data. This component (you can find it on GitHub and on Nuget) uses the platform specific facilities for storing data in a secure container, i.e. the KeyChain on iOS and a secure KeyStore inside the app’s sandbox on Android.

Be sure to get the latest 1.3.0 version of the Xamarin.Auth component though, as this is a bait-and-switch PCL library that also offers support for the Windows platform, whereas the older 1.2.x version doesn’t.

warning-stamp.png

There’s one caveat with the Xamarin.Auth component though… The KeyStore file on Android is locked with a hard coded password. The Android app in one of my previous projects was actually flagged in a security audit because they extracted the Xamarin.Auth DLL, decompiled it and found the hard coded key. Pretty iffy, because this means that the KeyStore data in every app that uses this library can be easily opened and read by extracting the file from the sandbox and using the key that’s publicly available on GitHub!

I made a pull request about 2 years ago that fixes this problem, at least in a way that you can provide your own key. But somehow Xamarin didn’t get around to merge it yet, so the vulnerability was still there, also in the 1.3.x version. The funny thing was that as we were doing the training, one of the Xamarin developers was actively working on this component. We pulled him into the training, explained the problem and he immediately went to work to see if he could merge my fix. How awesome!

FullSizeRender 4.jpg
How awesome is this: Xamarin Developer DNA… everyone could add their own string, picking the pegs that fit with their preference. The result is this awesome, unique “Xamarin DNA” sequence. A work of art!

The other part of this chapter was about the awesome PCL.Crypto component. This component is also a bait-and-switch PCL library, which means that the PCL portion contains nothing more than the API definitions for your shared code to compile against (the bait), but uses the actual device specific implementation at runtime (the switch). This means that PCL.Crypto can use the platform specific crypto API’s developed by Google, Apple and Microsoft themselves instead of relying on its own security implementation. Much the same as the Xamarin.Auth component solves its local storage issues. For developers familiar with the WinRT crypt API’s for example, there is a special WinRTCrypto API that you can program against, but PCL.Crypto will map this to the underlying native API’s. Pretty clever. For example: a method for encrypting some data could look like this:

public static byte[] Encrypt (byte[] plainText, byte[] keyMaterial)
{
  var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider
    .OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);

  var key = provider.CreateSymmetricKey(keyMaterial);
  var IV = WinRTCrypto.CryptographicBuffer.GenerateRandom(16);
  var cipher = WinRTCrypto.CryptographicEngine.Encrypt(key, plainText, IV);

  var cipherText = new byte[IV.Length + cipher.Length];
  IV.CopyTo(cipherText, 0);
  cipher.CopyTo(cipherText, IV.Length);

  return cipherText;
}

PCL.Crypto can be used quite easily in combination with Xamarin.Auth to encrypt or hash data before storing it. At least as long as your app is using the not-so-secure version of Xamarin.Auth – with the hard coded key – using something like PCL.Crypto to secure the values that go into the secure storage is a real necessity! But it’s good practice to do it anyway.

OAuth
Next we went into OAuth for authorizing access to an API from a mobile app. OAuth in itself is a pretty broad topic and enough to fill tens of blogposts. One of the important points here is that for mobile apps, basically there are only two OAuth flows that are really usable:

Screen Shot 2016-04-26 at 22.50.26

The Implicit flow or the Authorization Code flow. The other flows aren’t really suitable for mobile apps (or browser apps involving JavaScript code), since this means that there will be client secrets hidden inside the app, and they involve dealing with a user’s password in the app itself instead of handing that off to an Identity Provider. The Client Credentials flow is typically used for service-to-service communication, usually on behalf of the user.

Xamarin.Auth provides some nice API’s to easily initiate a login sequence, using a web view that follows all the redirects that are part of the OAuth flow, to obtain an access token (or authorization code).

Memory Management Issues
The most interesting part of today was about diagnosing and dealing with Memory Management Issues. I actually learned a lot about how both the Xamarin.iOS and Xamarin.Android frameworks work in terms of memory allocation. It’s important to understand that in both cases, you are always dealing with native objects, managed peers and a binding layer in between, provided by Xamarin. At least, for those objects that are actual native platform classes.

Under the hood, there are some intricacies to be aware of. For example: in order for iOS’s reference counting mechanism to work, you have to be very careful to release references to native objects, for example by making sure to always unsubscribe from event handlers. For Android, it’s important to realise that you’re working with two Garbage Collectors: the Mono one and the one in the Android Java VM. There are a lot of details, but there is some nice guidance up on the Xamarin Developer site about this [iOS] [Android].

You can prevent a lot of memory issues by following a couple of important guidelines. Also the Xamarin Profiler is a great tool for diagnosing possible memory leaks.

Lots of excitement for the opening of the Darwin Lounge at #XamarinEvolve

A post shared by Roy Cornelissen (@roycornelissen) on

 

Darwin Lounge
As for the (other) fun part of Evolve: the Darwin Lounge was opened this evening, accompanied by a huge buffet and a nice range of tasting stands for artisanal chocolate, local beers and hipster coffee 🙂 This tweet sums up how I felt this evening:

It’s no secret that I’m an avid foodie, so suffice to say that I was in seventh heaven when it comes to the food that was served here. This means that you have to sit through my Instagram food porn pictures now:

Excellent chocolate. The Phillipines one is a clear winner #food #XamarinEvolve

A post shared by Roy Cornelissen (@roycornelissen) on

 

I expected to visit a mobile dev conference but instead I've come into food discovery heaven. #XamarinEvolve #coffee

A post shared by Roy Cornelissen (@roycornelissen) on

 

Great hipster pour-over coffee at #XamarinEvolve

A post shared by Roy Cornelissen (@roycornelissen) on

 

Hmm, macarons #XamarinEvolve #food

A post shared by Roy Cornelissen (@roycornelissen) on

 

Beer tasting at #XamarinEvolve. Local beer from Orlando Brewery. Good stuff.

A post shared by Roy Cornelissen (@roycornelissen) on

 

 

So… Xamarin sure knows how to throw a party 🙂 Of course, the Darwin Lounge at Evolve is mainly about cool geek stuff and tech inspiration. There’s lots of that going on as well. Lots of IoT stuff, drones flying around, etcetera. Check out the Twitter timeline for #XamarinEvolve for a great impression of the fun things out there.

IMG_0946
Great buzz and lots of hacking going on in the Darwin Lounge
IMG_0944
These robot spiders are pretty creepy!
IMG_0943
LEGO Mindstorms, totally cool! Their official iPad app for programming the Mindstorms robot was built with Xamarin

Be sure to tune into the Evolve keynote tomorrow at 9am EST. Rumours are that it’ll be spectacular! 😉

Xamarin Evolve 16 – Training day 1

Hi there from Orlando, FL! Yesterday was the first day of the Xamarin Evolve 16 pre-conference training. And man, we’re already having a blast here. Evolve 16 is even bigger than the previous one, and on the pre-conf training alone, there are more people than there were at the original, legendary Evolve 2013; in total! Impressive.

Finally it's happening! #XamarinEvolve

A post shared by Roy Cornelissen (@roycornelissen) on

My mobile peer at Xpirit, Geert and I arrived on Saturday, together with a bunch of fellow Dutchies including some of my former colleagues from Info Support. It’s nice to catch up and hang out.

In the training, we’re doing the Intermediate track, which offers some more advanced topics. I have to say that most of the topics are already familiar, but for us this is also a great opportunity to get to know the Xamarin University material. We’re working towards certifying ourselves for delivering the official Xamarin University training curriculum at Xpirit to be the first Dutch Xamarin Training Partner! How awesome is that? Stay tuned for more news!

The main topics we covered were:

Asynchronous programming with async/await
For this module we dove into the mechanics behind the Task Parallel Library in .NET and the async/await keywords. This stuff is so important to get right as it’s crucial for quality apps to make sure that you’re not wasting the main UI thread by doing expensive work like heavy CPU-bound work or (network) I/O. The course went into some of the mechanics of async/await – with the compiler generated state machine that ends up in the generated IL.

The problem with async/await is that the syntactic sugar makes it almost too easy to make work inside your app asynchronous. The point is that making things asynchronous isn’t always necessary and using async/await the wrong way may actually hurt the app in the sense of complexity and possibly performance more than it helps. Understanding the state machine that the compiler generates, the effects of ConfigureAwait(false), working with the Dispatcher, etcetera is crucial if you want your apps to be responsive.

Patterns for reuse
A topic that’s dear to my heart. Marcel and I actually did a pretty popular talk about it at Evolve 2013. IMO, this stuff all still holds true, however we have progressed a bit when it comes to the maturity of the Xamarin platform. With the advent of Xamarin.Forms, more and more code sharing techniques are possible and go right up to the top UI level. On the other hand, Xamarin.Forms already takes away a lot of the hard work of bridging platforms. Very nice, but – my pet peeve – beware of the abstractions! 🙂

It all comes down to keeping things as simple as possible. In the training, we talked through using the Factory and Service Locator patterns, but our common conclusion was that they involve a fair amount of Yak Shaving.

front

In the end, Dependency Injection is a relatively clean way of dealing with dependencies that have per platform implementations. In my experience, using a light weight DI container like SimpleIoC is sufficient for most apps. Let’s be honest, in an average app, you don’t really need much sophisticated lifetime management or other things. You just want to be able to swap in per platform implementations of some components to use them from shared code. But before you start building your own components, head over to Xamarin’s plugin repo on GitHub because a lot of plugins are already available. And they generally use DI to set up.

Testing
We talked about the techniques that are at our disposal for validating the quality of your app. Of course using unit tests should be a no-brainer to developers, and there are actually some nice scenarios for testing the behaviour of your ViewModels and other logic in your app. These unit tests, being independent and mostly having their dependencies stubbed (another advantage of using DI is that it makes stubbing a bit easier), can give you the quickest feedback during your development cycle.

But an important part of your app will be the UI and that actually runs on the device. This has always been hard to test and we had a look at what Xamarin Test Cloud has to offer and the UITest API’s that you use to drive those tests. In a recent talk, I used this test pyramid diagram to show the stack I like to use for testing mobile apps:

mobile-test-stack.png

Note that I still think that there will always be a certain amount of manual testing involved for the more complex cases. And specifically those cases where you want to check the behaviour of your app under different circumstances, such as actually being on the move through tunnels or other low connection situations, or being out in the field to make actual pictures with the camera. Manual field tests by the team and beta test platforms like HockeyApp, Apple TestFlight and Google Play Beta are excellent tools for this.

Xamarin sure knows how to throw a party… #XamarinEvolve

A post shared by Roy Cornelissen (@roycornelissen) on

After the training it was time for some relaxation at LaFayette’s. Excellent food and great Southern style live music, and all the familiar faces from the Xamarin community there. Great to see everyone again! Really looking forward to the next few days!

To infinity, and beyond!
On Sunday, we had some spare time, so we spent the day at the NASA Kennedy Space Center. Wow what an amazing trip! It was incredible to see the huge rockets, it’s impossible to fathom how big they are until you see them. The same goes for the Space Shuttle. The Atlantis Space Shuttle is on display and you can see it up close. Super cool!

Awesome, the Atlantis Space Shuttle #nasa

A post shared by Roy Cornelissen (@roycornelissen) on

Rocket science

A post shared by Roy Cornelissen (@roycornelissen) on

The biggest surprise came when we went on the bus tour to the actual launch site. Again, it’s impossible to fathom the scale of the site and the equipment there that’s used for space travel. At the end we got a great show about the Apollo missions. The actual control center used for the Apollo mission is there on display. And then there’s the overwhelming and HUGE replica of the Apollo rocket.

Appollo Control Center #nasa

A post shared by Roy Cornelissen (@roycornelissen) on

And the coolest thing was: our Uber driver who took us back to the hotel was an engineer on the Space Shuttles for 30 years! So he could give us some fun behind-the-scenes insights. Did you know for example that there was an actual Coca Cola machine installed in one of the shuttles? That was to test the effects of carbonation in space. But since Coca Cola is a commercial company, NASA was not allowed to talk about that 😉

Oh and don’t you just love these vintage posters?

Love these vintage graphic posters #nasa

A post shared by Roy Cornelissen (@roycornelissen) on

NASA is recruiting #nasa

A post shared by Roy Cornelissen (@roycornelissen) on

Everybody gets a Xamarin!

This week at Microsoft’s //build/ 2016 conference in San Francisco, Scott Guthrie shared more details about the Xamarin acquisition and what this means for developers on the Microsoft stack. The keynote is worth checking out, also for the great Azure content. More interesting details about what Xamarin has in the works can be found in Miguel de Icaza’s session. Or you can watch the distilled announcement here:

In short, Microsoft has made the Xamarin tools available to everyone. If you have a Visual Studio Professional or Enterprise edition, Xamarin is included at no extra cost. Moreover, it’s also available as a completely free Community Edition, under the same Microsoft license terms (small teams, OSS developers and students). Wow!

Even though the technology is widely regarded as excellent, as Miguel states in his talk: Xamarin used to be a bit of a niche product because of the pricing. And let’s be honest, they were steep and it turned people off, even though you could easily build a solid business case in terms of money and time saved due to higher developer productivity. But this means that Microsoft has removed a big barrier for a lot of companies and developers to adopt Xamarin! Not only that, but the fact that Microsoft is fully behind the Xamarin approach is very beneficial for customers who were betting their mobile development approach on Xamarin.

This interview with Nat Friedman on TechCrunch is an interesting read if you want to learn more about the acquisition.

Open source FTW
One of the most notable changes within Microsoft lately is their big support for open source. Microsoft emphasised this by open sourcing their .NET Framework, which has received many pull requests and active contributions since. This lead to .NET being revamped to a cross platform runtime and framework which runs on Windows, Mac and Linux as well (my colleague Alex Thissen wrote an interesting article about .NET Core in the second issue of Xpirit Magazine). This is something that Mono and Xamarin have already been pioneering over the past years. It’s nice to see these things come together and the teams combining forces to move things forward. It’s a bit soon to tell what will happen with Mono in the future and whether it will merge with .NET over time, but for now it’s important to know that Mono has been re-lincensed under the MIT license, which is a pretty big deal in itself.

Moreover, Nat Friedman also announced that the whole Xamarin framework, their customized Mono runtime and Xamarin.Forms will be contributed to the OSS .NET Foundation. How cool is that!

Full cycle mobile DevOps
With the acquisition of Xamarin and – earlier – HockeyApp, Microsoft now has a pretty strong full cycle DevOps story for mobile development. Obviously the development story with cross platform C# already was strong, integration into VSTS for continuous integration is very powerful and continuous deployment to HockeyApp for internal enterprise apps is also quite easy. Check out my colleague Geert’s blog series on this topic. TestCloud remains an excellent way to mitigate test risks with their vast array of devices.

Over time, we’ll see Xamarin Insights integrated into HockeyApp for .NET native crash reporting and analytics. Xamarin Insights is a very nice product and their native support for .NET exception stack traces and ability to use the SDK in a shared PCL project is pretty powerful. I expect that after merging with HockeyApp, the pricing model for the analytics part will be much more attractive as well.

It would be cool to see more seamless integration of tools like Fastlane for easy and automated submission to public AppStores, etcetera.

Everyone can do Xamarin now! (?)
This all means that every .NET developer can do mobile development with Xamarin now.

Or at least, technically… Moving into mobile development – especially iOS and Android – coming from a Windows, ASP.NET, back-end development background isn’t as easy as 1-2-3.

To me the beauty of Xamarin has always been that they provide unrestricted access to every native API that is also available to Swift, Objective-C and/or Android Java developers. In my opinion, this still yields the highest quality apps while still being able to reuse a good portion of your code across platforms. The power lies in the fact that you can play with the level of reuse vs. native platform specific code as it suits you as opposed to going all in with UI abstractions and reuse all of your code. Abstraction in software development is a slippery slope and Xamarin allows you to stop abstracting if you feel it goes too far. I sincerely hope that this direct-access-to-native-API’s approach will remain a core feature of the Xamarin product, and we won’t be forced into a “UWP for all platforms” model.

Having access to all the native API’s lets you leverage the unique capabilities of the underlying OS-es. Apple Pay, Touch-ID, etcetera. But this requires deep knowledge of how these OS-es work and how to use their API’s. iOS and Android are very different beasts when it comes to their architecture and solutions for problems. This means that in my opinion, there will still be iOS developers, Android developers and Windows Developers, even though they’re all working with the same language. Sure you can master them all, but I think a good mix of specialism and multi-disciplinary teams are the way to go. Mobile devs are just like normal humans, and can be pretty biased about their platform of preference. This sometimes makes for great and interesting discussions on how to solve a particular use case on all platforms, aside from the occasional fun banter about the Windows Mobile app gap, not being able to open links on iOS, or the immense device and OS fragmentation in the Android world.

Rohancharge

In any case, there will be a whole army of .NET developers coming to the Xamarin platform and there will be a huge demand for knowledge. Xamarin’s Developer Center has been revamped and it looks very nice. It’s a great resource for learning how to build apps with Xamarin and they do an excellent job explaining the native API’s and how to leverage them from C#. But over the years I have found that presenting at user groups and conferences and delivering in-person training is also a great way to share knowledge.

Both Marcel and I at Xpirit have been heavily invested in Xamarin since the early days and we’ve had the opportunity to fly around the world to speak about Xamarin. I look forward to continue sharing our knowledge. Our team was recently enforced with Geert joining Xpirit,  and we’re dedicated to helping developers and customers do professional mobile development with Xamarin and Microsoft.

Come meet us and dive in head first with us at one of the following opportunities:

My hopes and expectations
It surely looks like Microsoft is invested in making the Xamarin tools a first class citizen in the .NET developer stack and Visual Studio ecosystem. We can expect deeper integration of Xamarin into Visual Studio, and Miguel already showed a glimpse of that with an iOS Simulator running on Windows. This sparked some debate about whether or not this is an actual simulator running natively on Windows, but if you listen carefully, Miguel explains that it is a simulator window remoted to a Mac. I think this trick is similar to how Xamarin does it’s build & app packaging for iOS with a remote build host over SSH:

FullSizeRender 2

I’ve seen a setup like this at many companies, where Windows PC’s were the standard developer setup, and Mac’s are considered “exotic”. Using a Mac Mini as a remote build host works ok, but if you wanted to test and debug, you needed to switch to that Mac physically or access it via VNC. That was sub-optimal and this solution is pretty sweet.  I don’t think we’ll be able to have a native iOS developer story without a Mac because of Apple restrictions regarding their SDK but this promises to make the developer experience for a Windows based developer a whole lot smoother. I think Marcel will be happy 🙂

It’s no secret that I’m more biased towards iOS and developing on the Mac. Using Xamarin Studio, sometimes switching to Xcode for the Interface Builder and the pleasant experience with the much less bloated Xamarin Studio IDE has become more natural to me than working from Windows and I’ve come to prefer it. With Microsoft pushing towards developer tools for Linux and Mac (VS Code), it looks like Xamarin Studio is also here to stay, and hopefully with the same level of investment to push the product ahead. Who knows, maybe Xamarin Studio might become the official Visual Studio IDE for the Mac one day 🙂

In his //build/ session, Miguel showed off Xamarin Workbooks, which is based on the Xamarin Inspector. It looks very sweet as a test-bench for C# code and documentation tool. But even better: it can now be used to inspect and play with a live running app on the simulator! That is awesome as it shortens the dev/build/run/debug cycle tremendously. I hope that it will become a core part of the developer experience from within Xamarin Studio / Visual Studio but for now it has already saved me a lot of time this week while trying it out.

I also have good hopes that the original character of Xamarin’s approach (full access to native API’s) will remain intact. UWP sounds like a good idea for the Windows platform but Xamarin has always stressed that Xamarin.Forms has very specific use cases. It’s not a one-size-fits-all solution, and frankly that’s the main thing I’ve been arguing against ever since I chose to go with Xamarin as opposed to Cordova, Titanium or others. So while I do expect that there will be something like a UWP for Windows, iOS and Android, it cannot be the only way to develop native mobile apps.

More dots to come…
Evolve 2016 promises to be a fantastic conference and a big party to celebrate the future of Xamarin at Microsoft. I hope to see you there.

Nat Friedman wasn’t kidding when he replied to my Instagram musing:

#Xamarin timeline. Proud to have been along for the ride since even before that first dot 👍

A post shared by Roy Cornelissen (@roycornelissen) on

Here’s to more dots!

GMImagePicker ported to Xamarin.iOS

TL;DR
I ported GMImagePicker to C#. Code here, Nuget here. Happy coding!

This past week I was working on a Xamarin project where we need support for selecting multiple images and/or taking pictures and uploading them to a backend service. The default UIImagePicker control in iOS is ok but not very versatile. It can take a picture with the camera, or lets you select a single image from your gallery but that’s about it. Furthermore, working with the resulting images is quite cumbersome as you’re working with large UIImage objects in memory. A lot of performance and memory issues can happen if you’re not careful.

In order to deal with photos and videos more efficiently and in a much richer manner, Apple introduced the PhotoKit API in iOS 8. Mike Bluestein has written a nice introductory post on this API on the Xamarin blog, so I’m not going to repeat this.

In short, PhotoKit works with the notion of PHAsset objects, which are basically descriptors for media files on the device. There are API’s to query different photo galleries, etcetera. Only once you actually need the image for display or other purposed do you have to retrieve the image using the PHAsset descriptor. Very efficient.

Many apps, such as the Facebook app, allow users to select multiple images in a user friendly manner, and maybe even add pictures on the go by providing access to the camera while they are browsing their gallery. This is something that we also wanted to add to our app. Luckily, there are some nice open source projects around that implement just that. One of the nicest ones is the GMImagePicker component by Guillermo Muntaner Perelló, which uses the PhotoKit API under the hood. The user experience looks like this:

gmimagepickerdemo

That’s slick! You can browse through several collections, and the control is highly customizable, and even contains localized texts for labels, buttons and dialogs. Only, it’s written in Objective-C…

I had two options: bind the API using Xamarin’s Objective Sharpie or port it verbatim to C#. I chose to port it, mainly to have full control over the inner workings of the control and to not have to pull in a “foreign” language into the project. The port has complete feature parity with the Objective-C version and I tried to iron out as many issues as I could. It seems to be working pretty smoothly in my Xamarin app.

The code is up on GitHub and you can use the control by either downloading the code and including the .csproj in your project, or install the Nuget package in your Xamarin.iOS app:

Install-Package GMImagePicker.Xamarin

As I said, the GMImagePicker control is highly customizable. You can change its appearance by specifying colors for different parts of the UI, and you can provide custom titles and confirmation prompts. It’s also possible to filter and limit the types of assets you want the user to select. The whole range of options can be found in the sample app that comes with the control. Here is an overview:

var picker = new GMImagePickerController {
Title = "Custom Title",
CustomDoneButtonTitle = "Finished",
CustomCancelButtonTitle = "Nope",
CustomNavigationBarPrompt = "Take a new photo or select an existing one!",
ColsInPortrait = 3,
ColsInLandscape = 5,
MinimumInteritemSpacing = 2.0f,
DisplaySelectionInfoToolbar = true,
AllowsMultipleSelection = true,
ShowCameraButton = true,
AutoSelectCameraImages = true,
ModalPresentationStyle = UIModalPresentationStyle.Popover,
MediaTypes = new [] { PHAssetMediaType.Image },
// Other customizations to play with:
//ConfirmSingleSelection = true,
//ConfirmSingleSelectionPrompt = "Do you want to select the image you have chosen?",
//PickerBackgroundColor = UIColor.Black,
//PickerTextColor = UIColor.White,
//ToolbarBarTintColor = UIColor.DarkGray,
//ToolbarTextColor = UIColor.White,
//ToolbarTintColor = UIColor.Red,
//NavigationBarBackgroundColor = UIColor.Black,
//NavigationBarTextColor = UIColor.White,
//NavigationBarTintColor = UIColor.Red,
//PickerFontName = "Verdana",
//PickerBoldFontName = "Verdana-Bold",
//PickerFontNormalSize = 14.0f,
//PickerFontHeaderSize = 17.0f,
//PickerStatusBarStyle = UIStatusBarStyle.LightContent,
//UseCustomFontForNavigationBar = true,
};

// You can limit which galleries are available to browse through
picker.CustomSmartCollections = new [] {
PHAssetCollectionSubtype.SmartAlbumUserLibrary,
PHAssetCollectionSubtype.AlbumRegular
};

// Event handling
picker.FinishedPickingAssets += Picker_FinishedPickingAssets;
picker.Canceled += Picker_Canceled;

// Other events to implement in order to influence selection behavior:
// Set EventArgs::Cancel flag to true in order to prevent the action from happening
picker.ShouldDeselectAsset += (s, e) => { /* allow deselection of (mandatory) assets */ };
picker.ShouldEnableAsset += (s, e) => { /* determine if a specific asset should be enabled */ };
picker.ShouldHighlightAsset += (s, e) => { /* determine if a specific asset should be highlighted */ };
picker.ShouldShowAsset += (s, e) => { /* determine if a specific asset should be displayed */ };
picker.ShouldSelectAsset += (s, e) => { /* determine if a specific asset can be selected */ };
picker.AssetSelected += (s, e) => { /* keep track of individual asset selection */ };
picker.AssetDeselected += (s, e) => { /* keep track of individual asset de-selection */ };

// The GMImagePicker can be treated as a PopOver as well:
var popPC = picker.PopoverPresentationController;
popPC.PermittedArrowDirections = UIPopoverArrowDirection.Any;
popPC.SourceView = gmImagePickerButton;
popPC.SourceRect = gmImagePickerButton.Bounds;

await PresentViewControllerAsync(picker, true);

The extensibility is very convenient. For example: if you want to set a maximum to the total size of the images you want to allow the user to select, you can handle the AssetSelected event, keep track of the total size selected, and handle ShouldSelectAsset, to prevent selection if a maximum threshold has been reached. This is exactly what we wanted to have in our app.

Once the user has finished selecting assets, you can use a PHImageManager to retrieve the actual images in whatever size you like:

void FinishedPickingAssets (object s, MultiAssetEventArgs e)
{
  PHImageManager imageManager = new PHImageManager();

  foreach (var asset in e.Assets) {
    imagePreview.Image = null;

    imageManager.RequestImageForAsset (asset, 
      new CGSize(asset.PixelWidth, asset.PixelHeight), 
      PHImageContentMode.Default, 
      null, 
      (image, info) => {
        // do something with the image (UIImage), e.g. upload to server
        // you can get the JPEG byte[] via image.AsJPEG()
      });
  }
}

Very nice, and it’s now available for Xamarin.iOS developers as well 🙂

photo-1437419764061-2473afe69fc2
Photo by Andrew Illarionov (https://unsplash.com/photos/-WW8jBak7bo)

Many thanks to Guillermo for letting me port his excellent code and publish it. I’d love to hear your feedback on the code and would love to see your PR’s for improvements.

Microsoft’s mobile future is cross platform with Xamarin

Yesterday Microsoft and Xamarin announced that Xamarin will be acquired by Microsoft. Pending approval, the Xamarin team and products will become part of the Microsoft development ecosystem.

This is an interesting move and big news in the Xamarin community, but frankly not an unexpected one. People have been speculating for years about Microsoft buying Xamarin, especially since Miguel appeared prominently in the Microsoft //build keynotes these past few years. For both parties, it seems the best possible way forward.

It’s no secret that Microsoft has been struggling to keep up in the mobile space, with Windows Phone/Mobile. Dramatic reports about Windows Phone’s “demise” were all over the blogs and forums in the past few months. It still remains to be seen wether Windows 10 Mobile can make a dent in the universe. If Continuum takes off and gets some good apps in the Store, it might play a nice role for knowledge workers in the enterprise. Still, in these modern times, employees expect consumer grade experiences and that includes being able to bring the mobile device of their own choice to the workplace: Bring Your Own Device. And frankly, that market is taken by Android and iOS.

Microsoft acknowledged this when CEO Satya Nadella announced their new Cloud First, Mobile First strategy last year, immediately followed by the introduction of Office Mobile… for iOS!

Azure is the most important horse Microsoft is betting on and that platform is shaping up quite nicely. Just last Tuesday we did a deep dive on Azure Service Fabric with the Xpirit guys and wow, it’s a nice platform. For mobile apps, there have been some interesting gems in the platform for years as well.

In order to push Azure forward, Microsoft has to make it dead simple to make apps for all platforms and connect them to their cloud. What better way than with the Xamarin stack? Quality native apps with one the most productive programming languages in the industry! Not to mention the rich ecosystem of Nuget packages and .NET API’s out there to bootstrap your app development. If I can leverage Azure yet still target the most relevant mobile OS-es in the market, than that’s awesome. And that is what counts for both developers and companies targeting employees en consumers with their apps. And maybe, just maybe, this may even help push developers to leverage the tools and programming model to start targeting their apps for Windows Mobile as well, giving that platform another push.

It’s as if Microsoft is saying “OK, we’ll leave mobile to the pros, we have the cloud and tools pros” 🙂 And why not? This is a perfectly fine execution of the Cloud First, Mobile First strategy. Mobile can mean iOS and Android just as well, as long as the Cloud is still in Azure as far as Microsoft is concerned. They set the example themselves by delivering a top notch iOS version of the Office suite.

177H

All of this is an interesting culmination of some of the things that have been happening in the Microsoft ecosystem. After Nadella took the helm, Microsoft has become more open and collaborative towards other technologies and platforms. We can develop and run ASP.NET on a Mac nowadays using the new .NET Core and Visual Studio Code. In that regards, Mono has always lead the way that Microsoft is now following, and thats a good thing. To think that those same Mono guys are now the ones to bring Microsoft to a true cross platform mobile world is just great.

What to expect?
So what’s next? Well, here’s my take…

Better Xamarin adoption
First of all I expect this to remove a lot of constraints that we sometimes encounter with enterprises that are looking to do mobile. Should we trust a relatively small vendor like Xamarin? This was a huge problem in the early days, and has gotten better as Xamarin built up their track record. The technology sells itself easily, but what about the risks? And then the pricing… sure you can make an easy calculation that shows how quickly you earn back the license costs due to the increased developer productivity, but frankly Xamarin Platform, Xamarin Insights and Xamarin Test Cloud were perceived as pretty expensive. I expect that the Xamarin tools will be incorporated into the MSDN suite and included in the price. For Xamarin, their license fee was their bread and butter. MSDN is a means for Microsoft to push their cloud offering, so the tables are turning in that regards. Good news for developers, especially the independent ones!

Test Cloud and Xamarin Insights will be incorporated in the Azure offering. Given the much bigger scale at which Microsoft can operate, prices can be much more affordable which make these tools almost a no-brainer. My one pet peeve with Xamarin Insights has always been that it focuses on the mobile app, and doesn’t cover end-to-end (server side) monitoring. But the dashboard is much more comprehensive and mobile optimized (obviously) than what Microsoft’s Application Insights has to offer. With HockeyApp on board, and now Xamarin Insights, the best of multiple worlds can be brought together.

Synergy
Furthermore, I expect a lot from the Mono and .NET teams joining together. Microsoft is already dipping its toes in cross platform development, and Xamarin now brings a full blown development stack for .NET (well, Mono) for native iOS, native Android, native Mac AND Linux! Microsoft can leverage the Mono experience to push .NET ahead and over time, that same .NET framework will be what’s under the hood of the Xamarin tool chain.

IDE
Xamarin Studio, Xamarin’s IDE on the Mac is shaping up to be a pretty solid tool. It’s still my favourite IDE when building mobile apps. Visual Studio feels too bloated to me compared to Xamarin Studio and doesn’t give me the best performance when I’m developing inside my Windows image in Parallels. At the same time, Microsoft is working on their Visual Studio Code offering, the cross platform development IDE. It’s still pretty limited, but if they can leverage the Xamarin Studio foundation to make it a full blown Mac based IDE for mobile apps, I’m all for it!

Given their efforts on Visual Studio Code, I don’t think Microsoft will discontinue Xamarin development on the Mac and force users to Windows/Visual Studio.

DeathtoStock_Wired7
I still love my Mac 🙂
Xamarin.Forms and UWP
At Xpirit we’ve been contemplating about what Microsoft’s strategy would have to be in order to stay relevant in Mobile, and push their Azure cloud. UWP is an interesting application model and Xamarin.Forms has a similar premise for delivering universal but native apps on all platforms. I think it would be natural if UWP and Xamarin.Forms are brought together to make a truly universal application model for native apps. In that sense, Xamarin.Forms can be seen as the groundwork for future editions of UWP. I do hope however, that it will still be possible to target the native SDK’s and API’s as is the case with the Xamarin Platforms. Sometimes you just want to make a Storyboard and hook up your outlets to a UIViewController 🙂

And frankly, as Xamarin.Forms itself has already proven, you just can’t get away with just the UI abstractions in order to deliver quality apps. Knowledge of the underlying platform is still relevant and flexibility to reach out into native code is still needed. Only making UWP available as a programming model will be just as bad as the Cordova/PhoneGap type offerings.

Microsoft Bridges for Android and iOS
Microsoft has two initiatives out there, announced at //build last year: Microsoft Bridge for iOS (WinObjC) and the Microsoft Bridge for Android. Both technologies enable developers to run native iOS/Android apps on Windows. I’ve blogged about this at the time, and I still think this is a bad idea for the user experience. I understand where Microsoft is coming from but I have good hope that they are now turning around and facing their development platform towards iOS and Android instead of trying to bring iOS and Android into their own OS in order to fill the app gap.

Wrapping up
With all these tools and technologies coming together, Microsoft’s offer for full stack application development an a holistic end-to-end continuous delivery cycle looks very promising for developers and businesses.

It’s exactly for this reason why the pillars we founded Xpirit on in 2014 are Cloud, Mobile and ALM. Cloud first, Mobile first and an all encompassing vision on Application Lifecycle Management around that. We have deep knowledge about architecting and building systems for Azure, and mobile apps using Xamarin. We’ve been working with Xamarin since even before they were Xamarin.

#Xamarin timeline. Proud to have been along for the ride since even before that first dot 👍

A post shared by Roy Cornelissen (@roycornelissen) on

I’m looking forward to all the new challenges that will come our way.

One thing I do hope though, is that this won’t be the end of the Xamarin style conferences… Evolve is a real joy and I’m looking forward to this year’s edition. Let’s hope this is not the last one, or at least that Xamarin brings their fun and coolness to Microsoft.

My Miguel
This has been a long time coming…

Don Box tried to persuade Miguel de Icaza in 2003 to come to Microsoft in his rendition of the classic Beatles song “Michelle”, now dubbed “My Miguel”. Miguel played hard to get for 13 years but as Clemens Vasters tweeted yesterday:

Partly true I guess… I think the mission has only just begun…

NSBCon 2015 Recap

This past week I’ve been in Dallas,TX for the second edition of NSBCon 2015, the official NServiceBus conference.

[TL;DR]
It was a blast, I found the quality of the sessions and the activities very good and I met some nice and highly competent people. Oh, and great food!

As soon as the slides and videos are available online, I will add links.

Pre-Con Workshop
The week started out with a full day Advanced Saga Masterclass by Andreas Øhlund. Although most of the content was already familiar to me, I still had some nice takeaways from the day. The most important one is around integration patterns with external non-transactional resources. When dealing with non-transactional resources like web services in an NServiceBus architecture, it’s wise to place the interaction in a separate endpoint, and handling a command that you send from the Saga.

My takeaway was that you should leave the technical details of the web service interaction inside that integration endpoint. If an error occurs, just let NServiceBus handle it so you get First Level Retries and Second Level Retries for free. Only report back to the Saga with a functional reply, such as a Tracking# in case of a shipping provider. This way the Saga stays clean and functional, as does the integration handler.

FullSizeRender 6

Another important lesson is that a Saga are a good fit when there’s an aspect of Time in your domain logic. For example: a buyer’s remorse policy (the ability to cancel an order within x minutes). For logic like this, the RequestTimeout feature of a Saga really shines. You could state that if a Saga does not contain at least one timeout, you probably shouldn’t be using a Saga; instead you could just as well put it in a regular message handler.

The day ended in great company at Casa Rita’s Mexican Restaurant with a fantastic Briskett Burrito. (Hey, I’m a foodie)

 

Conference day 1
The first day of the regular conference was already packed with nice sessions. Udi’s keynote was sort of a State-of-the-Union on what Particular has been up to for the past year. Lots of work has been done on the internals of NServiceBus, more on that later. Most striking was probably the announcement that – a year after being introduced at NSBCon 2014 – ServiceMatrix is being discontinued.

To be honest, I am not really surprised and also not sorry for it. I’ve never believed in dragety-droppy modelling tools for building software and frankly I felt Particular was trying to go with that craze a little bit too much. As Udi explained, a tool like that will get you 80-90% there, but it’s the nitty gritty details in that last 10% that will break you up. So it’s back to the model of development that I’ve always liked so much about NServiceBus: put the developer in the driver’s seat.

That’s not to say that there is no demand for visual tools. Some of the efforts that have gone into ServiceMatrix are now being transformed into another form of visualisation, one that I much prefer: visualisation of your finished system as it runs. In other words: living documentation. I’ve always been a bigger fan of using simple tools for modelling: PowerPoint (yes I said it, I’m a PowerPoint architect), or much rather even: pencil & paper or a whiteboard. No modelling tool has ever really appealed to me, not the UML ones and especially not the “graphical coding” ones (looking at you Windows Workflow Foundation and BizTalk). Just stick with boxes and arrows and start coding, is my style.

NServiceBus V6
After Udi’s keynote, Particular solution architect extraordinaire Daniel Marbach took us through the new NServiceBus V6 release. V6 is all about embracing async/await, which means that an important chunk of NServiceBus Core was rewritten from the ground up to be async all the way.

Daniel did a great job of explaining why Particular did this. Ever since the introduction of the TPL and the async/await keywords, Microsoft has been pushing towards async code more and more. This is most apparent in the cloud, where all IO operations (Azure Storage Queues, Azure Service Bus, SQL Azure, etc) have an async API. Up till now, handlers in NServiceBus were synchronous, and made you implement a single method:

void Handle (MessageType message);

This makes it hard to consume async API’s for IO, because marking a void method as async is evil. Furthermore, the NServiceBus Core is not aware of any async code, so strange things can happen if you’re not careful. This lead the team to the decision that V6 should be a breaking change in order to go fully async. The interface for a handler now looks like this:

Task Handle(MessageType message, IMessageHandlerContext context);

You must now return a task (or Task.FromResult(0) if your implementation does not require async), and you receive an IMessageHandlerContext implementation that you can use to send or publish messages. No more public IBus Bus { get; set; }. This is done so that there is no more dependency on state across multiple threads. NServiceBus will make sure that you have the correct instance. It is also important to note that the use of ThreadLocal for caching is dangerous because of the introduction of async/await. All in all, an excellent talk by Daniel, who wrapped his lessons in a story about a Swiss Chocolate Factory. Gotta love the Swiss.

More interesting info on async/await and ThreadLocal can be found here:

[https://www.youtube.com/watch?v=4uWzIM1U-VA] Presentation about the pitfalls of async/await and the SynchronizationContext. Highly recommended, even if only because of the creative format.

[http://www.particular.net/blog/the-dangers-of-threadlocal] The dangers of ThreadLocal

IMG_9776

Akka.NET
Andrew Skotzko from Petabridge did a riveting, high octane presentation about Akka.NET and the Actor Model. I’ve briefly looked at the actor model before and am interested in exploring it more, especially after this session. One of the things I’ve been wondering about for a longer time is how the actor model fits in with NServiceBus.

In his session, Andrew mentioned that Akka could be a great producer or consumer for NServiceBus. In Andrew’s words: “Akka is about Concurrency, NServiceBus is about Reliability”. I’d have to explore this some more but frankly I don’t really see a great fit as of yet. One of my main concerns with Akka is that remote messaging between actors is not reliable. It is supposed to be light weight and location transparent, but the model compromises on reliability. Akka has an “at most once” delivery guarantee, which doesn’t exactly guarantee anything. For communication between actors, Akka provides location transparency, i.e. you just use an interface to send a message, and the receiving actor can be either in memory or on a remote machine. Hmm, where have we seen this fail before? At least NServiceBus is always clear on the fact that when you send a message, it’s inherently remote. And NServiceBus has your back in making sure the message arrives.

So, I’m not yet really seeing the point of using an actor model inside, or alongside NServiceBus services, but it requires more investigation.

This seems to be the best place to start: http://LearnAkka.net

I must say though, both Andrew and Aaron Stannard from Petabridge are both extremely passionate and helpful. They’re very nice guys and we had good fun over a couple of beers.

Death to the Distributor
Sean Feldman
from Particular talked us through a preliminary version of a new routing component in the NServiceBus plumbing which allows them to eliminate the Distributor component when you’re on MSMQ transport and want to scale out. A nice and short talk in which Sean showed a promising solution for decentral routing, with a pluggable strategy (you could write your own distribution logic if you’d like). With that basis, combined with realtime health info from endpoints, dynamic routing and commissioning and decommissioning of nodes will become possible. Interesting stuff that’s in the works.

There were also two interesting case studies on the first day: Building the Real-Time Web with NServiceBus and SignalR by Sam Martindale and a more high level session called Decomposing the domain with NServiceBus by Gary Stonerock II

Combining SignalR with NServiceBus has been a hobby of mine for a longer time, so the idea was already familiar to me. It was nice to see the application that Sam and his team put together: a multi-user graphical web application for “composing” and budgeting luxury homes that relies on SignalR and NServiceBus for on-the-fly budget calculation and distribution to multiple users at once. Sam was so nice to do a shout out of my earlier blogpost about the NServiceBus backplane for SignalR. With thanks to Ramon Smits of Particular, the sample has now been upgraded to the latest stable versions of both NServiceBus and SignalR. Thanks Ramon!

Gary’s session was interesting as well, sharing his journey designing a system for Medical Trials on a logical architectural level. Some key takeaways for me were:

  • In modelling your domain logic, make sure that you model it for success (i.e. Logical Success Modelling). Try to factor out the edge-cases and exceptions by asking more questions about the business logic. You will end up with much simpler domains.
  • Defer naming things; Don’t name services, domains or classes until you are more clear about its responsibilities. You will end up with much clearer names. Udi calls this “Things Oriented Architecture” in his ADSD course.

Hackathon!
Then it was time for the Hackathon! The assignment: come up with the most over-engineered Hello World application based on the NServiceBus building blocks. I teamed up with Anette, Daniel and Adam and after a couple of beers we came up with project Ivory Xylophone:

FullSizeRender 14
See? Pencil & paper FTW!

By sending a tweet with hashtag #ivoryxylophone, we set off a system that sends a message to a Saga that converts all the characters in the message to Morse code, gathers the characters, converts them back to plain text and sends the message to a handler that tweets out the message on Twitter. All NServiceBus message would go over a transport based on Git commits (…). Apart from the Git transport, we got it working end-to-end.

IMG_9745
Mob programming

We got second place, just after the awesome Slack transport by Mark Gould.

IMG_9770
Demo time for Ivory Xylophone

Conference day 2
Ted Neward kicked off day 2 with his keynote session “Platform Oriented Architecture“. He opened by establishing that the software industry has been through several cycles of inventing the same wrong solutions for the same problems multiple times. We’ve seen other people speak about that and frankly, he’s right. The nice thing about Ted’s talks was that he did a shot at how the future of architecture should look. He concludes that most of us are building a platform of some sorts. And in order to succeed, you need all of the good things that we’ve established: the 4 tenets of SOA are still a good idea, we still need to mind the 8 fallacies of distributed computing, but the most important thing is that a platform should have a clearly defined Domain and Context. Meetup, Uber, Yelp, AirBnb are all platform but each has its specific domain and give meaning to technology choices in their own context.

All About Transports
Swedish Chef Andreas Öhlund gave a great talk comparing the different transport options that NServiceBus gives, packed in a tasty tale of a Swedish Meatball company. I really liked his stylish slides, kudos! His message was important: different transports have very different characteristics and you should choose wisely. Do you choose a decentralised model with MSMQ or a broker style transport like SQL Server, Azure Service Bus or RabbitMQ? Talking about RabbitMQ – one does not simply install RabbitMQ and be done with it. It takes care to make RabbitMQ reliable (clustering) and you must be careful when you send messages inside a transaction that might fail, or you’ll end up with ghost messages. Andreas’ talk could be a great blogpost in itself. I hope Particular puts it on their blog soon.

Other interesting talks were Jimmy Bogard‘s Integration Patterns With NServiceBus where he shared some lessons learned about integrating legacy systems with newer NServiceBus systems, dealing with big files and his interesting Routing Slip Pattern.

Kijana Woodard had a funny and insightful talk about Things Not To Do With NServiceBus. I like seeing a talk like this as it shows that Particular isn’t just shoving NServiceBus down everyone’s throat as the end-all solution for everything. It’s not a golden hammer, so there are definitely cases where it doesn’t fit.

IMG_9760 2
Beef ribs!

Again, a great day, which ended in the fantastic Brazilian Steakhouse Boi Na Braza. Did I mention I’m a foodie?

Day 3: Unconference
One of the things I enjoyed the most was the Unconference day. A day where participants set the agenda and get to do the talking. We collaborated on an agenda for the day and ended up doing multiple parallel tracks of discussions and knowledge sharing. I participated in discussions about Security & NServiceBus, UI Composition. Akka.NET & the Actor Model, Saga & Domain Concepts and Microservices. Got a ton of new insights. My sketchy notes might not be as meaningful to you as they are to me, but still…

All in all, NSBCon was well worth the trip to Dallas. All the Particular folks are very approachable, hospitable and helpful, the participants were great discussion partners and the quality of the sessions was very good.

Xamarin, NServiceBus, Microservices and Enterprise Mobility – my sessions at Microsoft TechDays NL

Last Thursday and Friday, Microsoft TechDays NL 2015 was held at the World Forum in The Hague. TechDays is the biggest Microsoft related software conference, with over 2100 attendees. For us at Xpirit, the conference was a big success, fortunate to be selected to present a total of 21 sessions with a crew of 6 Xpiriters. This blogpost contains some reflections on the conference and the slide decks for my own sessions.

TechDays 2015 was great fun. I think Microsoft managed to pull of a nice conference. I made a Storify overview of Xpirit’s activities at TechDays.

James WhittakerWith an awesome, energising keynote by ex-Google employee and now Microsoft Distinguished Engineer James Whittaker, TechDays was off to a great start. James took us on a journey about how the web has evolved into the way we now consume data through apps, and how the app model might evolve into newer experiences in the future. It’s all about data consumption and intelligent software that gets that data into our hands the moment we need it. The Internet of Things will work for us and obsolete whole industries over time, leaving time and room for humanity to explore the world, the seas, science and the galaxy. Inspiring and very funny.

Xpirit magazine We chose to accompany our sessions with an in depth, 44 page magazine, handed out to all attendees. It covers some of the topics we spoke about at TechDays, as well as new technologies like Ionic and the cool new Hololens.

If you were unable to obtain a copy, you can also download it from our website. If you’d like a hard copy, give me a ping.

Being a hobby sketch-noter/cartoonist/graphics fanatic, I really appreciated seeing the live sketchers from Wandverslag create a beautiful drawing with details from the sessions and discussions in the hallways.

Wandverslag

TechDays NL speaker gift In the same style, all conference speakers got a nice personalised gift, our own cartoon.

As Xpirit, we chose to take on the topic of Microservice architecture, demystify some of its aspects and provide possible approaches for building microservices. I had the opportunity to talk about two of my favourite topics: mobile development (Xamarin!) and distributed systems architectures (NServiceBus!). Here are my sessions:

Lessons learned: migrating an N-tier web application to microservices with NServiceBus
In this session, I explained how I transformed an existing N-tier web application to a more scalable and manageable architecture in the microservices style. I presented the reasons for migrating and a 5-step migration plan. This session is not specifically about NServiceBus, but rather about the architectural approach.

Foodie for life

Microservices with NServiceBus in Particular
In this session, I showed how you can build a loosely coupled, message driven microservices architecture with the NServiceBus framework and the tools from the Particular platform.

NServiceBus

Enterprise Mobility & Cross Platform Development from the Trenches
This session is about some hard lessons learned while developing cross platform apps in an enterprise environment. The colliding worlds of EMM platforms and cross platform tools can give you some headaches if you’re not careful.

Building out-of-the-ordinary UI’s with Xamarin.Forms custom renderers
Xamarin.Forms is a powerful framework that uses UI abstractions to enable 100% code reuse for UI code whilst still delivering 100% native user experiences. In general, for simple data driven apps, Xamarin.Forms is a good fit. But what if you need to build a UI that is a little less ordinary? Can you still do that with Xamarin.Forms? This session explains how you can use Custom Renderers to go beyond standard.

Check out the blogs of my other Xpirit colleagues for their TechDays sessions: Rene, Marcel, Patriek and Marcel.

Thanks to everyone for attending my sessions, the great conversations and feedback! See you next year?