Mateusz Stawecki

Thoughts on Mobile, Reactive & Serverless

Posts from the ‘Tech Log’ category

When watching the WWDC2015 Keynote, I’ve noticed that the Newsstand icon wasn’t on any of the screenshots. Hmm… interesting. Shortly after that Apple announced “News”, it was pretty clear Newsstand was getting a “replacement”. iOS9 is still in beta, so I guess anything can happen, but I think it’s time to declare the new world order…

#1 Newsstand is still a Category on the AppStore

Not much changed here, even the covers are still around.

Newsstand - AppStore

#2 Newsstand “shelves UI” and the icon are gone – replaced with a generic app group

Just like any other group, it contains apps and icons. Covers are gone. I guess magazine covers still make sense on the AppStore, if the app uses them internally.

Newsstand - app group

#3 Newsstand apps are finally free to leave the group and exist anywhere on your home screen

Newsstand - freedom

What’s up with News?

News is interesting, because it promotes a completely new format for displaying news content. Interestingly, by taking away the focus from apps, which is a quite unusual move. I’ve got used to Apple being all about Apps. The introduction of “seamless linking” might help our case – following article links inside news would allow you to navigate straight to your app.

So far, it seams that News is much closer to what Flipboard is rather than what Newsstand used to be. I don’t see how News would be a better choice for “magazines” (just to clarify – I mean the “magazine” format – regular bundle of content behind a cover), but maybe the “magazine” format is not right for mobile? Do we all have ADHD and can only handle flicking through streams nowadays?

Personally, I still believe in “magazines”, I still think people should try to run magazines on the AppStore. News might turn out to be a great solution for news portals, but I find it very hard to call “News” a replacement for “Newsstand”, because it’s such a huge shift – maybe an “alternate approach”? Apple hasn’t killed magazines just yet.

I’m eager to see how this plays out.

Leave a comment
During the 2013 WWDC alongside iOS7 Apple announced an exciting addition to its CoreLocation framework – a technology that could finally solve the problem of indoor location detection – iBeacons, by leveraging the under-utilised (at the time) Bluetooth Low Energy. The framework was hard to test at first due to lack of hardware providers for the actual beacons, but several startups and companies soon jumped at the opportunity and we could finally give it a proper shot. However, particularly in early releases of iOS7 the iBeacon tech seemed to disappoint with its poor accuracy and reliability. While the concept got a lot of developers excited, the amazement quickly turned into frustration. So, how well do iBeacons actually work nowadays?

Previous Experiments

Less than a year after release, I took part in making some experimental apps.
One which was a guided tour of an office building – related information was displayed when a new room was entered. The beacon accuracy wasn’t particularly important since the space was large. The demo worked fine, especially when the application was running in foreground.
The other one was done at Úll Conf 2014 and relied on the conference app waking up in background. For the first time we could test the setup across >100 devices. We’ve announced a scavenger hunt: once a device came in range with a beacon installed at one of our secret locations, an achievement badge was unlocked in the app. The experiment results were mixed, some things worked, some didn’t (I’ve summarised them last year). iBeacons seemed a little too young to be more than a curiosity. When iOS7 was updated with further fixes and later iOS8, we finally saw improvement. Apple was clearly updating iBeacons and other features which suffered from similar issues (e.g. multi-peer connectivity which was practically a dummy API in the initial release of iOS7). It’s understandable that these things take time to perfect and need to be tested in live conditions, which for a secretive company like Apple was impossible to do before the announcement. So, how far have we come?

“Well, this is going to be a problem.”

Fast forward to April 2015, I’ve attended Úll Conf again and this time we decided to try out a more ambitious setup. We’ve had a perfect opportunity to put together an audio tour to the Museum feature, which was a small exhibition of Apple devices and memorabilias. We had 12 kontakt.io beacons which we installed on some exhibition items.
In the end it worked out quite well:
 
 —
However, things didn’t start off very well at all. After we’ve setup the beacons, I’ve quickly realised that the app, which was tested against a much simpler setup didn’t behave the way we wanted. This was due to a several problems I’ve observed:

Ranging is far from perfect

On iOS8 I’ve noticed a lot of improvement in the ranging results, but occasional issues still arise:
  • beacons may randomly drop off: don’t be surprised when a ranged beacon disappears only to re-appear on next range
  • When looking at RSSI, be aware that it is equal to 0 when the beacon is in unknown proximity:
    CLBeacon (uuid:…, major:0, minor:1, proximity:0 +/- -1.00m, rssi:0)
  • approximate distances are inaccurate and signal strength reading may fluctuate
When using multiple beacons in a dense setup these inaccuracies will prove particularly difficult.
Solutions:
  • make sure your ranging code compensates for some of these issues: if you’re displaying content for the nearest beacons, don’t trust the result immediately, put a threshold on when a beacon is considered as “the nearest beacon”.

Screenshot 2015-06-11 01.52.13

  • compensate with the user flow. We’ve been very ambitious: the app would display content as soon as a new beacon was considered the closest. On top of that we’ve set the audio to play automatically. This meant that when things went wrong, the current audio track for the item was interrupted with the false-positive result. Why not advertise that a location is available, but allow the user to confirm interaction in a non-intrusive way.
  • compensate with how you structure your information. E.g. you could cluster several  items around a single beacon, instead of having a really dense setup.
The way you compensate will have its trade offs, so you want to pick the right trade off for your use case.

Different devices will give different results

Besides issues with ranging itself, remember that different iPhone/iPad models will have different chipsets and construction. That will lead to inconsistent results.
Here’s a sample i recorded at the Museum, when standing ~50cm from beacon no 1. (iBeacon was behind glass). Each device was in exactly the same spot.
museum

Spot the iBeacons! 😉

iBeacon Ranging Comparison
As you can see, even the loose definition of the three proximity states …Isn’t loose enough!
  • Immediate: Within a few centimeters
  • Near: Within a couple of meters
  • Far: Greater than 10 meters away

Yeah, right!

To avoid fluctuations between beacons, one of the things I’ve tried was to accept only beacons ranged as “immediate” but it was surprisingly rare to observe that state on the old iPad Retina.

Background location monitoring doesn’t work immediately after boot

This is a really important thing to remember when testing background ranging capabilities. Give it at least 10mins for iOS to start looking for your location in background. If you expect for your app to wake up soon after a restart, it won’t work. iOS is taking its time to wake up all of its background services. This is a rare case when the common “have you tried turning it on and off?” approach, actually makes things worse.
Testing iBeacons will require a bit of patience and may require some ingenuity, just ask Ben Dodson and his — clever way to “simulate” entering and leaving regions:

iBeacon testing means lots of tin foil to check what happens when entering and leaving the region!

A post shared by Ben Dodson (@bendodson) on

Conclusion

iBeacons aren’t perfect, but they’ve certainly improved. Simple use cases will work pretty well. More complex use cases just require a bit of extra care. The technology enables a lot of new possibilities, from simple ideas like reminding your conference attendees what the WiFi password is when they arrive at your venue, to an immersive shopping or museum experience.
What worries me a little is that we haven’t seen a lot of real case studies in the wild. Imagination’s the limit, but clearly iBeacons haven’t been fully embraced yet. It certainly may be due to their rough start, but as with any technology, if it’s used for its own sake and doesn’t provide actual value to end users, it’s usage is doomed to fail. Can iBeacons actually add real value to the mobile experience? Are they reliable enough to do so? I think so, but during development, make sure you understand their quirks and limitations.

If you want to play with iBeacons, you can do it easily by building something with Glide – our app creation platform. Check it out here.
2 Comments
Úll Conf iOS app

Úll Conf iOS app

This year at Úll Conf I had the pleasure of working with the organisers on creating the Úll iOS app. In order to build and publish the application we used Glide – an app creation platform, which I’m working on with Chris Harris. While the key feature of Glide is easy content collation via Dropbox – which allowed us to easily publish the schedule, photographs and speaker information – we’ve been recently experimenting with Apple’s iBeacons.

The conference took place at the Lyrath hotel, in charming Kilkenny, Ireland. The venue was quite large and had several interesting facilities, that we wanted to expose to the participants of the conference.

On Tuesday morning we’ve sent out a notification and published several clues linked to each place. In each room we’ve setup a kontakt.io beacon. We configured our content to post a notification when the beacon was ranged and unlock content related to the room, which included beautiful illustrations done by Carolina Buzio.

2014-05-04 21.45.36

Overall, everything went well. A few takeaways from the experiment:

  • detecting another beacon in the same region doesn’t usually wake up the app again. One of the workarounds I’m using is continuing to range beacons in background, by requesting a background task. That obviously only works for a finite amount of time.
    Another solution is to use multiple beacons regions, but rememeber that you can track up to 20. You’ll also need re-programmable beacons! As Apple points out, you could reconfigure which regions you’re tracking based on where you are.
  • make sure people have Bluetooth turned on. Biggest “oops!” of the experiment. The app didn’t inform the users to switch on bluetooth.
  • Beacons.

    We used kontakt.io beacons supplied by @dermdaly

    dissapearing beacon bug: one of the bugs that I noticed was that often ranged beacons dissapeared several scans after they were initially ranged. In our case this wasn’t a huge problem, we just needed to range it once, but if you’re depending on the beacon to stick around on that list (while you’re actually in range), it’s a problem.

  • beacons not working until device reboot: it’s 2014 and some people still had to restart their phones in order for beacons to work. No comments here.

 


All iBeacons aside, I highly recommend both Úll Conf and Lyrath 🙂

 

Lyrath

Leave a comment

I had a little play with different documentation generators recently and it inspired me to write a handy little tool to review all your “//TODO:” comments in code. There’s a lot of criticism around putting “TODO” and “FIXME” etc in code, it does sometimes end up quite badly. However, if you try to grasp it and use it to get a better overview of your progress, it might not be all that bad. As usual… it’s quite cool what you can do with bash.

Very minimalistic shell script, grab it as a Gist: https://gist.github.com/1212539

Leave a comment

I wanted to call this post “Project Cemetery”. Some experiments go bad, some go good. This one went far better than I expected, but besides interesting results, nothing really kicked off. Let me start from the beginning then. Last year (2010) I met a group of awesome people – employees of the OTHER media, who showed off some cool stuff in Mobile. One thing was particularly cool. A 3d app prototype in WebKit showed off by Chris Harris (@_ChrisHarris). Couple months later, I was lucky enough to join the team and work on a web app written with JS and CSS transforms. After that I got really excited about how much rendering power you can squeeze out from a browser on an iPhone, I decided to play a bit more with 3d transforms, see where it takes me.

Experiment #1: 3D Sci-Fi Racing game

(try it on Safari/WebKit nightly)
controls: arrow keys, space, C

I got carried away on this one! It was pretty cool, but runs correctly only on Safari/WebKit nightly. It has a physics engine, collision detection. All graphics using pure CSS3. Some of you may wonder: why not WebGL? Well.. there is one major problem with WebGL – it’s not supported on any mobile devices at the moment! And it might not be for a while, but while experiment no 1 was pretty cool, it failed to run on the iPhone. I’ve tried optimising, but I had to change the concept and do it from scratch. I was scratching my head, if it’s even worth trying, since there isn’t much of a case for such usage of this technology. It couldn’t compete with native 3d games. I finally got convinced by Chris: “iAds. You can use this in iAds.”. It made perfect sense, I then realised that when I saw the iAd keynote, I hated these ads, especially the games. Toy Story 3 puzzle game? :/ Ugh!! Here’s my shot at a game embeddable in iAds:

Experiment #2: 3D Platform game optimised for iOS

(try it on any WebKit browser including iOS)
controls on PC: arrow keys, space.

Boom! By the end of November 2010 it was finished. No-one could believe that this was a Web-app. And it ran on an iPhone 3G! You basically play a penguin who picks up ice cream 😀 I’ve been looking into selling this piece as a framework, but it didn’t work out. Turns out trying to work with ad agencies is quite hard too. If anyone’s still interested, give us a shout. I enjoyed the “journey” and got some cool demos out of it 😉 Gotta keep on trying!

Leave a comment

Ever had this problem? You were so excited to see, if some piece of code works on your live system, that you forgot to change database access configuration and file paths? Probably not, because we’re all respected professionals here *wink* and the case is usually: it’s 10pm, still at the office and x product is launching tomorrow and you accidentally overwritten the configuration, because you didn’t have time to finish the deployment script :P. Or maybe you have to deploy your application to even more than two machines? Well, here’s a small cheat sheet.

The lazy way


switch (php_uname('n')) {
    case 'livedevhost04':
		$dbhost = 'sql.example.com'; $dbuser = 'myapp_user';
		$dbpass = 's7d6y3726ye86'; $db = 'myappdb';
		break;
    case 'Mateusz-Laptop.local':
		$dbhost = 'localhost'; $dbuser = 'root';
		$dbpass = ''; $db = 'testdb';
    	break;
    default:
       echo 'No configuration found for host: '.php_uname('n'); exit;
}

This way is quite nice for most scenarios. Very convenient. Get the machine’s hostname, add a “case” to the switch with server’s configuration and you’re good! If you’re deploying through some sort of SFTP/WebDAV protocol, you can easily upload files without any additional modification before running the script. The same with deployment techniques like Deploy using Git.
The only problem is that you’re slightly exposing configuration settings for all your boxes. If you don’t feel comfortable with this, try a different technique like symlinks to a local configuration file.
Personally, I use it quite often. It’s better and way less annoying than swapping commented settings.

The ‘bash’ way

This can be used for many different scenarios. Not just files, but also directories. Here’s a very nice and readable script for symlinking stuff based on local hostname:

#!/bin/bash

targetfile=webroot/config.php
fromscheme=webroot/config._HOST_.php

fromfile=${fromscheme/_HOST_/`hostname`};

if [ -e $fromfile ]
then
 rm $targetfile
 ln -s $fromfile $targetfile
 echo $fromfile == $targetfile
else
 echo [ERROR] Local configuration file not found: $fromfile
fi

Additionally, you might want to execute a custom script that will do something for you after retrieving a configuration set.
Notice the “webroot/”, please keep sensitive scripts outside your document root, mkaay? Maybe even clean them up after deploy and keep them in repo!

You’re only in trouble, if you don’t have access to a bash shell on your hosting server (use first method) or you’re running Windows (you can try cygwin if you’re mad enough ;] )

A JavaScript Bonus

You’d be surprised how many times, I almost did something very silly on a deployed version of an ajax based application. As a bonus, here’s a script you can put in your app, to help you identify, which build you’re currently working on. Especially useful, when running on iOS in web app mode.

<div style='display:none;color:red;' id='devnotification'>TEST SERVER</div>


var currentHost = location.href.split('/')[2];
if (currentHost == 'localhost' || currentHost == 'dev.example.com')
document.getElementById('devnotification').style.display = 'block';

Enjoy! And remember to run your tests kids!

1 Comment

Getting cross-site content with JavaScript is cool, since it usually requires a tiny bit of extra effort when designing the feeds or deploying a callback proxy. Thanks to Yahoo Pipes it has now become very easy to get any content, even a whole web page and crunch it in your JavaScript web app.
First go to pipes.yahoo.com and Create a new Pipe. You’re going to have to log in.
Drag “URL Input” from “User inputs” to your pipe diagram. Now get back to “Sources”. If you’re planning on fetching a website, drag “Fetch Page”. If it’s a JSON or XML feed “Fetch Data” (all data will be automatically transformed ).
The next step is linking the elements together. Drag a link from the “URL Input” into you source’s URL Attribute and from sources output to Pipe Output.
Your pipe should look something like this:

Click “Save” and “Run Pipe…”. You’ll be taken to the pipe information page, where you can enter the URL which you want to proxy. Submit with “Run Pipe”, after it has loaded, select “Get as JSON”.
You should see some nice JSON with the transformed content. The URL to such pipe looks like this:
http://pipes.yahoo.com/pipes/pipe.run?_id=d53d0d4793aa292d3e02885ba9b22cba&_render=json&fromurl=http://stawecki.com
Now guess how to add a callback 😉
http://pipes.yahoo.com/pipes/pipe.run?_id=d53d0d4793aa292d3e02885ba9b22cba&_render=json&fromurl=http://stawecki.com&_callback=test
Surprise 😉 There is an underscore before “callback” attribute name. (weirrrd) For anyone who is new to XSS, “callback” is basically the name of a JavaScript function that receives the content. To show how it works, here’s a simple script that downloads a website and returns the response’s character length:


	function test(response) {
		try {
			alert( 'Content size: '+
			response.value.items[0].content.length );
			} catch(err) { alert('Invalid response'+err); }
		}

	function getURL(urlstr) {
		var ka = document.createElement('script');
		ka.type = 'text/javascript';
		ka.src =
'http://pipes.yahoo.com/pipes/pipe.run?_id=d53d0d4793aa292d3e02885ba9b22cba&_render=json&fromurl='+
		escape(urlstr) + '&_callback=test';
		var ks = document.getElementsByTagName('script')[0];
		ks.parentNode.insertBefore(ka, ks);
	}

And here’s a live version to try:
Simple Pipes Callback

Here’s a slightly more complicated example. I’m getting HTML content, parsing it internally and listing all links on the website (NICE!):
Link Scraper Demo

These examples used “Fetch Page” in pipes. Here’s an example of reading an RSS feed using “Fetch Data”. This script alerts the most recent news item from an external RSS feed. Notice that Yahoo Pipes conveniently transforms any feed to JSON (or XML if you really really want).


	function test(response) {
		try {
			var newsItem = response.value.items[0].channel.item[0];
			alert( newsItem.pubDate +" - " + newsItem.title +" - " + newsItem.description );
			} catch(err) { alert('Invalid response'+err); }
	}

	function getURL(urlstr) {
		var ka = document.createElement('script');
		ka.type = 'text/javascript';
		ka.src =
		'http://pipes.yahoo.com/pipes/pipe.run?_id=4d625dfe6977e71acb45db4aa51726a6&_render=json&feedurl='+
		escape(urlstr) + '&_callback=test';
		var ks = document.getElementsByTagName('script')[0];
		ks.parentNode.insertBefore(ka, ks);
	}

And here’s a live version to try with BBC News RSS feed:
Simple RSS Callback

Now go and cross site the hell out of the internetz! Soon slightly more practical examples.

1 Comment