Building the mobile app for social network

After events described in my previous post I was busy building a new mobile app for VK in addition to my day job at Visma.

VK is the biggest European social network with about 200 million users, 40 million daily users. As far I concerned there are two countries in the world which Facebook failed to conquer (up to date): China and Russia.

Russian rival VK is in many ways similar to its US competitor, but in addition has its own audio and video services. Across Russia VK generates most of the mobile traffic (in terms of volume). It was a privilege for me to accept an offer from the founder to build a new version of mobile app for Windows Phone.

Situation with Windows Phone (WP)

“We were born to die” phrase from the famous song doesn’t seem to apply to Microsoft mobile platform.  This is my current impression after googling ‘windows phone market share’.

Situation for WP improved (pdf) throughout the last year, maybe due to the release of all new Windows Phone 8 OS version, and according to the forecast in 4 years WP will be comparable to iOS in terms of shipments across the world.

I haven’t found the numbers for Norway, but I’d bet they are low right now. Since most of the people here can afford well established Apple or Samsung flagman devices, they may not consider cheaper entry level WP smartphones, like Nokia 620. I think typical users of WP-based smartphones in Norway are either geeks who try everything new or persons who switch from a feature phone and thus not being spoiled by variety and quality of iOS apps.

For the same reason, in Russia WP has beaten iOS in terms of new sales in the last quarter 2012.

Lack of quality apps for WP was and is the main weakness of the platform. It is improving however with recently introduced new versions of ‘core’ apps: YouTube, Facebook, Instagram (coming soon for Nokia), and now VK. There is a Spotify for WP as well, but it is not impressive comparing to the iOS version.

Mobile client for social network

Currently my app is no.1 in Russian app store for WP and used by 300 000 unique users daily and I expect this number to grow. Bug tolerance of users is very low for this type of apps and every bug can potentially become a major problem. Even if I’m able to provide a fix within one day, getting the new version approved for app store takes about a week.

Because of the reasons above, we released a ‘beta’ version of the app first, made an announcement in the VK community, fixed bugs,  and couple of weeks later substituted the old version of the app with the new one.

Interestingly enough, couple of days after our ‘beta’ release, Microsoft did the same with their Facebook app: released a ‘beta’ version of totally new one. It is just a coincidence, but the approach seems to make sense.

Generally speaking, building a mobile app is easier than building a desktop or Web app. But just like in any form of sport or art, 80% is the routine, 15% is more interesting, while to master the remaining 5% will take 90% of your time, if you want to be good at it.

The 5% for this app was in the News feed functionality.

Newsfeed (Wall)

Newsfeed is a potentially infinite list of news items. News item is a block of text and attachments. Each news item may contain another, reposted, item. Each attachment belongs to a predefined set of attachment types: photo, video, audio, map and some others. If many photos belong to one news item, they arranged dynamically based on the sizes of individual images.

This is how it looks, from my profile (texts in Russian: “Been to Malta. Approved”, “Good video”):

mobApp-611x359

The task is to show the list, keep scrolling smooth and do not compromise performance even on entry level devices. It is not as trivial as it seems.

There is a common approach in WP to create such lists: use a standard component ListBox and provide an xml template used by the system to generate layout for each item. ListBox will correctly instantiate needed news items as you scroll through the list.

The problem with this approach in my case was that the layout of each item was dynamic, so the template would be very heavy, and include sub-lists for each attachment type. In addition to that it would be tricky to generate images layout for each item on the fly.

I invented my own wheel, which would match my needs precisely.

UI virtualization, i.e. loading only needed items while you scroll through a long list, in general is difficult to implement. But I didn’t need a generic solution. It is fair to assume that each News Item shown in the list has a constant height. With this assumption the solution would be to use a huge scrollable area and by tracking scroll position, load only elements currently in view plus a buffer zone above and below. I implemented a small framework, which allowed me to reuse parts of news items, throughout app, for example in news comments. By using my own solution I got some extras, for example animated scrolling in the list. Standard WP ListBox doesn’t support animated scrolling. Here by animated scrolling I mean the ability for me to programmatically scroll to a needed position.

But the problem I hit was scroll smoothness. If you have an iPhone try to scroll a News Feed in Facebook app. It has glitches, but not too bad overall. What I got in my app was much worse at first.

Scroll smoothness is not quantifiable, so after each tweak I made, I had to start the app and manually scroll it and evaluate smoothness. It was an unpleasant experience. After a couple of weeks of such tweaking the only result I got was the moving news feed appearing in front of my eyes each time I closed them. To make matters worse, I was not sure whether it was possible to achieve the result I needed. I evaluated several other apps, including Facebook and Flickr for WP, but the performance they shown was not acceptable, even having in mind that these apps shown smaller pictures in the layout. My app was 90% ready and giving up on my solution would mean to start from scratch.

In this situation I first and foremost needed a proof that my approach is not flawed initially. I couldn’t look under the hood of the standard ListBox control and at some point suspected that it may use low level optimizations which are not accessible for me as an app developer. This would ruin my approach.

Asking on developer forums didn’t help much and it seemed that I’m on my own. In fact, people were sceptical.

I took a step back. First I found that there was a set of commercially available controls for Windows Phone, made by Telerik. I wanted to look in the source code of their implementation of ListBox to see how they implemented it. It took a couple of days of digging deep in thousands of lines of their code, before the ‘eureka’ moment: they used exactly the same approach as I did, with the complexity built around making the solution generic.

Confident that I’m on the right track, I was able to find and solve the problems which I had in my implementation. The most notable was the image loading while scrolling. While for user it seems easy, it is not.

Here is the overview of possible approaches ordered by performance from the worst to the best:

  • Just load all the images as you scroll. This will ruin the performance of fast scrolling if the images are big and connection is slow
  • Load images only for visible area after user stopped scrolling or scrolls slowly. This adds an annoying delay before you see the image.
  • Use an algorithm which manages images loading based on whether image was ever loaded before or not, position of scroll, state of scroll (scrolling or not), and a number of images being loaded at current moment. Based on my tests I found out that if the image is ‘new’ (was never loaded and thus never cached before) I can only load ONE image at a time while keeping scrolling smooth.  Technically, this algorithm is the most complex part of the app.

If you have a Windows Phone, you can download the app here: https://www.windowsphone.com/en-us/store/app/vk/edd920e2-b671-41b5-a9db-b89caccfa69c

System architect in Visma Software International
Connect with Alexander: