Xamarin has been a great way to build cross platform apps. But issues such as transient exceptions crashing your app, persisting data cross platform and the stacks of boilerplate code are enough to scare away devs, old and new alike. In this session, Chris Briggs will show you how to tackle these painful problems, effortlessly by adding 3 must have libraries to your Xamarin project!
In this presentation you’ll learn how to use:
- To make handling transient exception childs play!
- To simplify persisting data across Android, iOS and Windows Phone!
- To reduce the amount of boilerplate code you’ll write!
- Xamarin Hack Day
- Pasted : 19/09/2015 - Brisbane, Australia
- Xamarin Hack Day
- Pasted : 26/09/2015 - Sydney, Australia
So we’re going to talk about Supercharging Your Xamarin Application. So hi, my name is Chris Briggs, I’m a senior software dev at SSW and I’m really head up into IOT push. So first up, we’re going to thank our sponsors. So UNSW for this room, SSW for recording and pizza, and DevExpress for coffees. Now, if you want these slides, just text this to the number and like Gerard said, a message will send to you with the link.
So we’re going to have three main points today and they’re going start off with talking about transient exceptions, we’re going to move into persisting data and then talking about asynchronous error handling, but those three things seemed really desparent, so let’s talk about the stages of an app just to get an idea where this all fits.
So apps were they start off is just an idea. You’ve formed a problem you’re trying to solve, you think anything is possible and public enemy no. 1 is scope creep. And then we managed to make the proof of concept, we build it, the core functionalities working, it’s very buggy and we still fleshing application out. At this point, we think we are ready to go. We think we are ready to move into beta testing and we’ve really only tested the application in our own dev environment or in our own dev space which normally has really good Wi-Fi or a simulator that has no networking kind of issues. So we think, “Awesome. Time to go out there.” And I’ve seen this happened in a number of times, the application that works great in the lab falls over horribly in the beta testing phases. So we start gathering data. We start listening to feedback. We realised, well, the application is really fragile and that’s where everything we’re talking about comes in today. We’re going to talk about the libraries you can use to add the robustness to your app, to supercharge it so that if you put in stage one, when you go to beta testing, you’re gathering useful feedback because improving the application it sometimes it crashed and it only just crashed because we lost internet connection, that’s not really useful. But sometimes it crashed because I’ve got some weird error that pops up in our business logic then we know we have things that we can really fix.
So then moving along what happens after that is we set it loose, we’re releasing it into the apps store, we continue to gather data, we’re listening to our user’s feedback especially through the store reviews and we’re continuing to improve the app. At this point, it’s market validation, it’s all sink or swim and we realised that if the application survives, we’re going to get to this point here.
So the stage 4, we got the data and basically the apps has been out for a while and we’ve instrumented it so we have the tools to let us know what parts of the application are being used to see exceptions happening in real time and effectively we get to this point where we can say, “Feature X is an okay feature” but it’s used 75% of the time by users so therefore, we should really invest a few sprints into really improving that.
So why did we go through all those stages? Xamarin Hack Day is run for the community, we run it for you guys and we just really want to understand where you’re at with Xamarin with app dev. So if you guys can either tweet your stage at me or sometimes during the day just come up, tap me on the shoulder and say, “I’m at stage 2, 3, 4” that’d be awesome, that was we know where the target and content at.
So we’ll start off apps have got this great trends that’s been happening which says that really it’s more and more and more they’re consuming a web resource. Apps feel they’re part of the internet and it acts as natural extension, but what we come to realise is that this internet connections that they’re consuming in the wild they’re horribly unreliable. So the solution for that is to use a library called Polly. So what Polly does is it lets us express transient exceptions policies in a fluent manner. Effectively it lets us put strategies in place such as retry, retry forever in circuit breaker patterns, so that when we get these networking hiccups, our application doesn’t fall over, it will respond to degrade state, work itself out and move on. And how do we do that? Well, this is a common example of a method that will work perfectly in the lab and will cause you a world of hurt in the real world, a simple get the data and deserialize it.
Now, if we want to make this method resilient, we can express a policy using Polly, and how policy work is we work from left to right, so we say we’re going to create policy to handle exception and when the exception occurs, we’ll retry the method and in this case, we’re going to retry it three times and then we come down here and we actually execute the policy.
So this seems really ham-fisted. Why did we just wrap a policy around an entire method? Does anyone know looking at this method why I’ve gone and wrapped it? HttpClient, when it goes and gets the resource, it just goes off and fetches it. If the resources actually fallen over or you’ve got a 500 on your server, it actually says, “Hey, I completed successfully no exception was found” and then you’ll get down to the deserialization and your method will still fall over. So you have to be really careful especially around stuff like HttpClient that they’re doing the behaviour you expect them to do.
So what happens if I users don’t have any internet connection and I’ve actually been caught by this by for myself. There are really two ways we get around this problem, one, the application is going to fail, it’s going to crash, it’s going to fall over and say, “Sorry, I can’t do anything. Please reopen me up when you have Wi-Fi.” which is not a bad strategy but if we have to look at the really popular apps such as, you know, Facebook, Twitter and others, they’ll at least they’ll degrade and say, “Hey, I can’t talk to the Internet but I have the data from your last session, let me reserve it up to you.” So the application obtained some level of usability even though it’s in a disconnected state.
Now, there are many ways you can do this and I really like the library Akavache and really what it is in asynchronous assistant key value storage that sits on top of SQLite and effectively it just makes handling the persistence to a SQLite database really simple because it’s written quite well and allows us to write to that database without locking up the UI if you’re having to really think about it.
Now, it’s awesome for just caching. So, okay, I’ve got a web request, I’ll go spin asynchronous thread, further results in, keep moving on. It’s great for that. But what it’s also really good for is storing important data, so you can have a key value pair like user preferences and just store that inside your blob and it’s good to go. So it makes it really simple persisting data, so I kind of recommend if you’re going to try this out, you can use it for both stories, the caching and the long term storage.
So how do we use Akavache? First up, we’re going to go and we set up a blob name and then all we do is simply call insert object, we give it the keyname and we say the object we want to insert and that’s all there is to it. By calling this line of code, the UI won’t lock up on us, and what will actually happen is it will go straight from the background, dump it into storage. So in that way, in this situation where we’ve got retry policy, the policy has fallen over, we can actually return back the object we would’ve cached earlier one. So as we see here, we’re able to combine these libraries and make use of them quite effectively.
But just to write that code, you wouldn’t believe how many of these catastrophic areas I ran into. Try to get your head around all these asynchronous calls, okay, I’m calling off the storage but I’m also calling off to a web resource, you’re going to see something like this regularly, maybe not as colourful and what can you do?
You have two options, pull you hair out and cry or add something like Fody asynchronous error handler. So Fody is an extensible tool and what it does is it sits in the build pipeline and it waits until it sees a place holder it recognises and as soon it sees that place holder, it swaps it over with a predefined block of code. And so one of these extensible tools that I use for Fody is called the async error handler which basically means you place in a placeholder and it looks for it and when it sees it, it replaces the code, it means that it’ll very easily handle any TPL or async errors occurring.
So first up, we’re going to add a new package, we come up and we set up the Fody weavers XML file. So with Fody, you’re not limited to using one weaver on your project. You can use all the weavers or only one of them, it’ll depends on what you just stepped in this XML file and then we have to step a little bit a boilerplate code for Fody when it finds its placeholder to replace with.
So all this code is basically serving and you’re saying, “When we hit the async error and what I get called, I’m just going to log to the right line the exception” and of course you can change this if you’re using something like Serilog or Log4Net. Whatever logging tool you’re using, it can be swapped out with that debug.writeline.
As we see here, now what’s happening is we’re going to go and make that call again to data and, okay, the call will fall over somehow and instead of it actually just dropping the debugger or getting lost in the shuffle, we’re going to see in output box, we’ll actually see the exception gets printed. This one line of code will save you so much pain and suffering because the way the debugger works, it gets very easily confused by async and finds it really hard to actually serve up those errors nicely. So by putting something like this, we’ll be able to actually see the areas when they happen. Now if you’re using, our earlier example, if you’re using Fody, you will need to re-throw the error, otherwise you’re going to swallow the exception and you won’t get the retry policies nicely.
So as I said earlier, Fody gives you a ton of different options and needed some other great weavers we can use. So PropertyChanged, will make putting MVVM in, a lot simpler and lastly it’s also CryptStr. So when you’ve got that application you did as a proof of concept, it’s probably going to be riddled through a string literals and sometimes you can decide, “Well, actually I don’t really want people to be extract those directly out my app package” so you can just drop in CryptStr which will make it encrypted for you.
So in summary, we’ve covered these three areas and as you see, it’s actually really straightforward to make your app nice and robust at the early stages before actually sending it out into the wild. Awesome. Thank you.
Feel free to tweet me comments, feedback or questions to @ChrisBriggsy.