Set the stage. What we’ll talk about in this session: how to start building an app like this: considerations, focus, scope creep; some architecture; lots of tips; a bit of code.
So what is MINE for Facebook?- A facebook client- With a focus on the fb essentials: viewing your news feed, liking, commenting, sharingThat tries to stand out by offering customization options that aren’t available on FBAnd Which leverages the W8 traits
Summer. Had been giving some W8 trainings, had been playing with the SDK, W8 XAML, WinRT, … so I figured: time to make an app.First thing I did: I looked at what was missing from W8. Quickly, I decided on Facebook; the stuff I could do & see through the people app wasn’t enoughSo there we go: I was going to build a FB app. That was my first mistake :)I started out with some preliminary tests with the Facebook API. That looked good. So I started planning, decided on scope, deadline, etc, keeping in mind that I only had evenings & weekends to work on this. I figured I would be able to build in quite a lot of FB’s functionality. That was the second mistake :-) Once you start looking into it, Facebook is huge. Really, really huge. Planning was quite ok. Started out with wireframing, and then onto some more extensive tests.That was when this happened: FB API.
This meant a lot of time would go into working around potential problems with the FB API. And I do mean A LOT of time – it’s easy enough to get started, but it becomes very, very hard after a while. So, I needed a few other things. I needed focus, for one: focus on the essential: story feed. I also figured I needed something else: something that made the app stand out: customization.
Just to be clear, all I’m going to tell and show you from now on comes after running into problems & finding solutions for them. Prepare to restructure your application throughout development, and don’t be scared of some refactoring. Structures changed, libraries were tested, components were added and/or moved.
In the end, I ended up with some kind of “mission statement” about MINE for Facebook:So what is MINE for Facebook?- A facebook client- With a focus on the fb essentials: viewing your news feed, liking, commenting, sharingThat tries to stand out by offering customization options that aren’t available on FBAnd which leverages the W8 traits, and focusses on design/looksI decided to focus on the essential rather than trying to implement everything all at once => scope creep. That translates to: viewing your feed, liking, commenting - and of course, being able to do that from anywhere in windows or even from other apps through the share contracts. The other thing that translates to = the unique selling point, customization of the feed.The rest: to be added later.
Important: whitespace. Read from top to bottom => follow eye
Reliability is … lots of things. Your app shouldn’t crash, of course, but it’s more than just that: your app should act as your user expects it to act. A button should be a button. A click on an item in your news feed should always take you to that item in that feed. Snapping the app should keep your app in the same context => if your app behaves consistently, this in itself improves reliability. Your user must trust your application – if he doesn’t trust it, why would he keep on using it, assuming there are lots of alternatives?Trust = consistency. In UI as well: an inconsistent UI has a negative influence on your user trusting your app.So there’s a design component about reliability, but there’s also the technical components. It starts with your app’s architecture. Start by thinking about what components your application will need. Don’t ever start with coding before you know about those components, and then tie those together.
Schema: hoeverschillendecomponenten met elkaarpratenItalic = WinRTComponentRest = Windows tore app/class libCommon = common stuff specific for this appFramework = common stuff, non-app specificReliable? Reuse of components tnx to MVVM => write once, test once, reuse
Use proven components. You do not want to have to bother too much with the latest new fancy thing (although I must admin it’s always nice to play with those), you need something you can trust.Why? I need a pattern – not “for the sake of the pattern” (tend to take a pragmatic approach), but for the advantages it offers, mainly: separation of concerns, a lot easier to refactor afterwards, and the ability to use “semi-sample data” in Blend (though this is not yet fully supported, I can use it to easily bind from Blend). Yes, it also offers testability & easy reuse of my VM’s, but those things aren’t really used in this project. So: MVVM => prefer MVVM Light: easy, lightweight, proven. Remember that you’re using the pattern not for the sake of the pattern, but for the problems it solves/advantages it offers. Pragmatic approach is chosen.JSON.NET: faster than regular built-in JSONSerializer, more fine-tuning.Facebook C# SDK: proven. Makes great use of dynamics to ensure low rate of failure in the component itself, which is very important when working with FB.
WHY is this so important? You might forget extra conditions that should result in fail, but are treated as ok. => picture sample.From the app: let’s have a look at the news feed. FB often changes this – it often changes the data that comes back, it sometimes fails in sending back the data we need, it’s notoriously unreliable as far as sending the “type” of post back to your appEx: pictures. Facebook sends back pictures as pictures (good), collections of pictures (still good), as links (bit worse), as stories coming from an app (another type), which in turn can be... a picture, a bunch of pictures, links, ... Sometimes, pictures are sent without type information. And next to that, these types are different between when you ask for a news feed vs when you ask for a users’ profile feed. How was this solved? Well, first of all, I needed a translation layer. Letting the app speak directly to Facebook was a no go – there was no way I could take all those things into account & keep using the databinding engine. Something like that would have ended in an endless loop of converters and terrible performance. Hello, translation layer (so it’s immediately obvious why you need this architecture thingie thought out well).We all write code the other way around – it’s how we’re wired to think actually; it’s not even a coding/programmer thing, it’s a human thing: we prefer to assume success, rather than failure. And we even have the perfect excuse for this. Imagine your own projects for a customer: hey, this service layer I’m using doesn’t give me back the type I need => that’s an error in the service layer, fix it – not my responsibility. Hey, this service layer provides me with pictures, but they seem to come randomly, using a variety of types => that’s a badly modelled service layer, not suited for the client we’re building. Fix it – not my responsibility. Well, when you’re dealing with Facebook, or Twitter, or a bunch of other API’s, some reliable, some not, that’s not an option. Coding like this will help with that – and it’s actually a good idea to do this by default, even if you’ve got full control.
http://blogs.msdn.com/b/windowsappdev/archive/2012/04/03/how-to-improve-performance-in-your-metro-style-app.aspxThreadingCancellationMake use of the consumer/producer patternCode for grouping of callsThink about XAML performance
DEMO: cancellation = off. Friends => profile page, 5-8 times => fiddler => you’ll see requests keep pouring in.DEMO: turn on cancellation (onnavfrom) => requests don’t pour in anymore (except the ones we expect: bg tasks etc)Now, show cancellation: initstorybroker by passing in a token, call cancel on that token on onnavfrom. Cancellation => check for operationcancelledexception in storybrokerprefetch => if cancellation, return “null” or empty list, depending on how you’ve organized your code. How do you do that? Code from brokerHow do you do that with your own tasks? Separate code sample => don’t show, explain
DEMO: show working code. Then, show producing (prefetch story). Set breakpoint in fetchstory => this will wait until one is available. Show by adding a task delay of 10 seconds.Problem: data is needed throughout my app, randomly, but in a certain order. I want to avoid having to refetch the data all the time, to reduce calls for that data, but I do need my data in the correct order. Ideally, I need a collection which gets filled by, for example, a call to a service, and I need to be able to take items from that collection. In a simple case, this is a service call, wait ‘till after the call, return the items, and done. That has a few disadvantages though. It doesn’t enable us to prefetch data. It’s not thread-safe. It doesn’t allow multiple parts of my code to access that collection in a multithreaded environment.What I need is a way in which multiple parts of my code, from different threads, can ask “some component” for data. I do not know what part will ask for an item when. I do not know if the “some component” will already have fetched that data. Solution is the producer-consumer pattern, in which you have one component producing items & putting them in a queue. One or more other components can then take items from that collection. This allows the news feed scenario: app starts, data starts to be fetched, eg: it’s being produced. User navigates to news feed => consume stories. User navigates to another part of the app => consume stories. In the background, those can even run at the same time.In .NET, there’s a collection type for this: BlockingCollection. Collection that implements the producer/consumer pattern. Thread-safe. TryAdd will try to take add an item to the collection (“produce”). TryTake will try to take one from it (“consume”) and will wait until the producer-part has actually added one. You can also use CompleteAdding to notify consumers that no more items will be added to the collection (so: TryTake shouldn’t wait anymore). This allows any part of my code, on separate threads, to fetch data from that collection (eg: await GetStories => other thread)http://msdn.microsoft.com/en-us/library/dd997371.aspxExample: news feed, in different views, started by prefetching. Eg: you’ve got one part of your application which is fetching data, and you’ve got different parts of your application which need access to that data. You need to ensure they can access it in a thread-safe way AND in the correct order. How do you solve this?Next to that,
Typical example: file uploads
Show story feed. What happens here to improve performance, or at least: the perception of performance?What could we do? User scrolls, fetch next 20 items, and return them. That’ll work. But there’s better options.Items are prefetched: tnx to producer/consumer, this is a breezeWhen the user scrolls, the next bunch of items are returned. However: often, these are already waiting in my backing collection => fastBut that’s not enough. Instead of asking for twenty items at once, the consumer asks for these items one by one, and adds them one by one. => even though you might think this is slower in the end – and it probably is – it creates an illusion, a perception of faster performance.
I ran into a problem. FB is huge, people use it in different ways, I don’t know how, I don’t know what to expect. I don’t have a huge team of testers – this is a one man show. I don’t have the money to buy all types of devices to test this on. So what can you do? Use the rest of the world Of course, first of all you ensure your app is as reliable as possible, by incorporating the things I’ve shown before. But you can’t account for everything. Therefore, logs are important. If an error happens, you need to know about this so you can fix it.
In on_launched => initAttach to frame: in ext splashIn unhandledexception: MarkedUp.AnalyticClient.LogLastChanceException(e);
Focus: rather focus on being best at one thing vs good at a lot of things. Find a USP.Looks: importance cannot be overestimated: hire a designerReliability: part design, part architecture, part how you programPerformance: profile your app, think about task cancellation & threading, use consumer/producer, think about the illusion of performance & about XAML performanceStatistics & Logs: ensure you capture this – Marked Up is my favourite.
What does it take to make Mine for Facebook: learn and apply to your next Windows Store app