Share

engineering

7min read

“Walking the Dark Valley” - An iOS Developer’s journey into Web programming

“Walking the Dark Valley” - An iOS Developer’s journey into Web programming

The story

My platform of choice is iOS and I don’t hide it. If you, dear reader, had the opportunity to talk with me about this, you already should know that I have my reasons. Performance, control and stability are only the beginning of the list of arguments for going native. But at times, one needs to step out of his preconceived opinions. And lately I find myself developing apps more and more based on web-technologies. Let’s start from the beginning, shall we?

In early 2014 I had the pleasure to co-organise Mobile Central Europe conference. A conference made by developers for developers, like no other. Just like with our Mobile Warsaw events, we put a lot of emphasis on networking. This left us with a problem to solve. How to make people stay in touch after the conference is over, and make it fun in the process? So the idea of a networking game was born.

Finding a story idea matching the theme of the conference wasn’t hard. Take a dark desolate planet (Poland during winter), add a crew (the conference attendees) of a crash-landed ship (the saucers seen in much of the material), and you have a perfect fit for a game. The target would be to “recruit” other players by means of a identifier found from their conference badges. “Recruiting” being a nice coverup for sharing social media contacts.

picture picture

The requirements

We had an initial idea. It was time to write down some requirements:

  • “Recruitment” needs to be as easy and fast as possible: In the beginning we wanted to use QR codes. But after visiting WebSummit we picked the idea of badge ids. It turns out typing three letters is faster than taking a QR scan.
  • Users must have fun while playing the game: They must see the progress they make. Comparing the progress with peers is also fun. Points are perfect for that. And achievements. Everybody loves achievements!
  • The game needs to handle low quality internet connections: We all know how hard it’s sometimes to get a decent Wi-fi access in a public space and a “big” conference tends to be even trickier.
  • We need to protect the privacy of the users: Simply put, it should be impossible to extract the full details of all participants without some kind of consent from the players. To balance between UX and security we decided that only the first name, and Gravatar URL would be accessible publicly. More information (surname, social media contacts, etc) of a user would only be available to its recruits.
  • The game should cover as much devices as possible: Android and iOS may have dominated the smartphone market. But then there are those who want to stand out of the crowd (or simply enjoy a longer battery life). Who are we to condemn them?
  • Anticipate we will be hacked: Let’s face it, our attendees are mostly software developers. It was obvious from the beginning they will try to cheat the system just for fun. And so we needed to make it a little bit harder (more fun) for them.

The sad reality

It was mid-November, MCE was nearing with big steps. We had a nice concept, and a huge dilemma. Can we really afford to allocate enough developers to write the game natively for the three main smartphone platforms? We were already out of time. Application reviews for iOS tend to take around 3-4 weeks at the end of the year. To make it until the conference we would had needed to submit almost immediately.

The dilemma was the ages old native vs hybrid vs mobile web app discussion. At Polidea we strongly support the native way. It is our belief that under normal circumstances, native implementation delivers a far better experience to the users. But this time we wanted to do something very simple, and at low cost. We decided to give mobile web a try. A single developer would be able to write it and with no review times to hold us back. And thanks to some newer web-technologies it should be possible to fulfil most (if not all) of the requirements. That was promising at the very least.

The implementation

And we had a winner! I took the responsibility of development work. That’s why the app was architected in a very iOS-ish way. A variation of MVC of sorts. All the actual “code” gets downloaded by means of HTML offline cache on the first run of the application. Then, all the necessary data gets fetched, placed into offline storage and rendered using a JavaScript client-side template engine. In such a way the application is able to work for prolonged time periods without internet access. It turned out to work just fine. With an important exception of Internet Explorer up to version 9 (including the one running on Windows Phone 7).

“Recruiting” was performed in a similar fashion. A badge id is first stored in the local database, for later submission to the backend at the first possibility (e.g. when Internet access is available). Points and achievements were awarded afterwards. Functionally, this is an ideal solution. But from a UX perspective, there is a possible delay between entering a badge id, and receiving any feedback (e.g. typing mistakes do happen). To mitigate this, the game performs an initial verification on the client side. This requires data and so a slimmed down (only first name, avatar and badge id) version of the user database is stored into the client.

Player connection graph

The ugly parts

In the beginning I thought the ugliest part would be JavaScript. It quickly turned out that it was CSS. Full control of layout is something I’m used to in iOS. To my great surprise I discovered that achieving even basic constructs (e.g. vertically centred text) in CSS is a pain. For more complex approach, there are “templates” like the Holy Grail (http://alistapart.com/article/holygrail). The word “hack” is on my lips when I think about them. Tools like Foundation ease the pain a little bit, but at cost of polluting your HTML with additional wrapper ‘divs’ and similar: something CSS was supposed to prevent in the first place. On the bright side there are modern tools like SASS (Syntactically Awesome Style Sheets). They compile CSS out of a more expressive language. Variables, functions, inheritance and embedding, all suddenly are possible.

And then there is fragmentation. Each platform has some (even iOS). But what happens in the mobile web space is just madness. It’s like the sum of all fragmentations for each platform multiplied by the choice of browsers. For example: one, rather funny bug was caused by a difference in behaviour between IE and WebKit based browsers. In zepto.js (a hipster remake of jQuery) that we use, there is a flag for ajax cache control $.ajaxSettings[‘cache’], which is true by default. From what I understand on WebKit based browsers, this adds automatic cache-buster flags to the url. As our backend didn’t implement a cache for API calls, this was working fine. On IE it actually uses some kind of built-in request cache, and so it didn’t sync the state of the game. The blame was on me for not testing on Windows Phone during development.

Hacked by design

As already mentioned, we anticipated there would be attempts to hack us. We even predicted the standard attack. It’s enough to take the identifiers from the local database and send them to the right endpoint. That’s actually the way most of the 20+ users that tried to hack us. I think only one person tried to brute-force on all of the 18k+ combinations. But a hack is worth of nothing, if you get caught. And we have plenty ways of knowing.

Our first line of defence was rate-limiting on the backend for the recruitment endpoint. Reasoning here: there is a limit on how many recruitments a normal person can do in a given time. Let’s say 2 per minute. Recruiting all the 400+ conference attendees would easily take 3+ hours of constantly hitting the backend. By tracking the number of times a person hit the limit, we get most of the cheaters on a silver platter.

Second, there are statistics! A normal user is expected to have recruits evenly distributed among all conference participants. If someone has too many users recruited in a row (following badge ordering) then we can be sure he is just going over the user set without giving any thought about it. Similarly we can look at the timestamps of recruitment events, and search for more evidence there. In the end, a clever hacker would take the included database, and slowly, with random delays and in random order, go over it one user at a time and stopping at a reasonable amount of recruits.

It is a completely different matter how to handle the users caught of cheating. Instead of banning them (standard response in most games) we simply changed the way the game treats them:

  • They are not counted in the statistics: There are some achievements that are based only on the amount of recruited users.

  • Re-recruit function is disabled: There is a feature in the game allowing users to re-recruit a user who has recruited them before. To protect the data of users simply doing this for everyone, we had to do something. If a user is caught of cheating, he can’t be re-recruited in this way. The normal recruitment method by entering the code manually stays unchanged.

The conclusion

The web world is finally catching up. Some important new HTML5 technologies have been proposed to solve current headaches (CSS flex layout, anybody?) and the example of Internet Explorer 10 sparks hope that cross browser compatibility is also improving. But how long will it take to be finally usable? I fear it will be another 3 years. Or am I too sceptic? Even then, I fear the performance and quality won’t stand on equal ground with the native implementation.

One last question remains. Was it a good decision to go with web? I think yes. The game worked, more or less for all the attendees. Those devices the game didn’t work were mostly rather obsolete Android and Windows Phones. I think for next year’s (it’s almost sure there will be MCE 2.0) game, if we decide to have one, will also be web based.

Share

Antoni

Principal Software Engineer

Did you enjoy the read?

If you have any questions, don’t hesitate to ask!

Did you enjoy the read?

If you have any questions, don’t hesitate to ask!