Aleksandar • Vacić

iOS bits and pieces

WatchKit 1.0 redux

At recent Code Conference, Jeff Williams, Apple’s VP of Operations, announced that on WWDC 2015 Apple will present what is colloquially called WatchKit 2.0, a set of SDK to create “native”1 Watch apps.

My first reaction was: “WTH..? Already?!” That’s way, way too fast.

WatchKit 1.0 was presented last November, but devices using it started arriving to owners a mere month ago and there’s still a significant backlog of orders. Thus I’m sure there are many users and more importantly developers who don’t have the watch yet. I got my watch due to lucky set of events on Apr 27th and since then I spent almost 3 full weeks trying to get Run 5k’s watch app to work reliably and with a bit of flair in the UI. It’s now waiting for review and you can see this short demo on Vimeo:

Creating watch apps in 1.0 is an exercise in patience, to say the least. There has never been a larger gap between working on the Simulator and with real device. I can pretty confidently say that Simulator is good only for the layout and basic workflow but all other development should be done using the real device. You simply don’t see many of the possible issues in the Simulator.
Some examples: in the Simulator there’s no way to even try a very real scenario where customer exists your app down to the app grid then immediately goes back to the app. Or the screen goes black and once you tap it you are on the watch face, not in your app. Or “activate on wrist raise” scenario. Etc.

I was more than a little embarrassed just how unreliably original Run 5k watch app works in various usage scenarios. All of those scenarios worked perfectly in the Simulator.

Thus this upcoming version is about 90% new code. This post summarizes what I learned and we’ll see was this all for nothing when WatchKit 2.0 is presented.

Removing CADisplayLink from run loop

Do not use this

1
2
[self.displayLink removeFromRunLoop:NSRunLoop.mainRunLoop
                            forMode:NSRunLoopCommonModes];

Instead use this:

1
[self.displayLink invalidate];

Reason, from documentation:

Removing the display link from all run loop modes causes it to be released by the run loop. The display link also releases the target.

It safely releases all references and removes itself.

I was recently chasing a very strange rare crashes in Run 5k, my app with 1000s of daily users. It would SIGSEGV crash inside the CADisplayLink’s selector for about 100 or them during the week. Making the code change above solved all those issues.

My guess is that removeFromRunLoop:forMode: would enter a race condition with the call to the target’s selector method in some obscure situation. Who knows.

Attending conferences

There are so much good conferences around the world, technical and not, that I would like to attend, especially in spring and autumn. I want to go either to learn valuable new skills or just to meet people from my industry. However, living and making an earning in Serbia makes going to foreign conferences a big deal, financially and in some cases logistically.

Conference tickets are rarely below several hundred euros, prior to local taxes which you can’t refund back. Then there’s the cost of travel as most conferences are not in neighboring countries. Again few to several hundreds. Plus accommodation and food.

Logistical problem is related to entry visas. For mainland Europe, things are now fine, as EU has removed entry visa requirements for Serbia. Thus I can travel anywhere on moments notice.

For UK and Ireland though, I still need to plan my travels very carefully as I need to apply and get entry visa for both. Ireland’s visa is 60€ but it still takes about 10 days to get it. Just this March, I applied for it to go to Úll; then got swept up in day to day work and it slipped my mind. Several days later I packed myself to go to Hungary for short trip until I realized I don’t have my passport yet. Really annoying.

In the case of UK, there’s double trouble. First, visa is very expensive: 120€ for 6 months, 460€ for 2 years, 800+ for 5 years or more. The larger problem is that it takes 2-3 weeks to get the visa during which time your passport is somewhere in embassy or in transit and you can’t go anywhere. As I heard, British Embassy in Belgrade is no longer issuing visas so all passports are sent to Poland.

Another example: to get into Canada, I need to send my passport for a month to Vienna which is the nearest office and that’s the time they advise you to plan with. This alone is the reason I never went to Çingleton, to my eternal disappointment as the conference has now retired.
Both Canada and US still have another problem – they are pretty expensive to travel to, unless you can get your ticket months in advance. (Don’t get me started on WWDC and insane SF hotel prices).

All in all, it’s a considerable investment. This makes it hard to justify going to conferences just for the fun and socializing. Which is exactly the kind of conferences people are most excited about.

It’s head-scratching Catch 22. To advance in your business you need to get around, meet people, gain valuable leads – conferences are the place to be. But to attend them you need to have a business that will pay for it. Going to just one conference will not cut it (unless you are very, very lucky) thus you need to plan long-term.

After years of avoiding this problem, I decided to risk it. In 2015, I plan to attend as much conferences I can.

Let’s just hope in 2016, I will look favorably to this decision. :)

Automatic image creation for WatchKit animated progress bars

Image-based animation is the thing in WatchKit 1.0.

Making them manually is real pain though and there are already multiple ways to create them automatically, from Photoshop scripting to web pages using advanced CSS to some nice iOS hacking.

I feel most at home with iOS thus I did some quick coding few days ago and published WatchRingGenerator. It uses excellent M13ProgressSuite to actually draw the rings.