The online home of John Pollard

App Store Issues with Watch Update

I’ve been making some minor updates to Count The Days Left

  • Added an optional badge icon so you can see how many days are left without even opening the app
  • Made the app universal so it works better on the iPad, improved the layout so it works in both in portrait and landscape modes, and can be used in Split View

Neither of these improvements are particularly interesting, but what I thought I’d write about was a very irritating bug in either the App Store or Xcode 7.2 (or some combination of the two).

As you can imagine none of the changes are particularly massive, but uploading an archive to iTunes Connect gave some strange errors:

  1. WatchKit 1.0 - Your previous version used an extension for Apple Watch but your current version doesn’t. Users who haven’t updated their Apple Watch to watchOS 2 or later may lose access to their Apple Watch extension.
  2. Invalid Icon Name - The watch application ‘daysleft.app/Watch/daysleft WatchKit App.app’ contains an invalid icon file name ‘daysleft.app/Watch/daysleft WatchKit App.app/WatchAppIcon44x44@2x.png’. Make sure that icon file names follow the pattern “*@x.png" and they match the required dimensions. Please visit developer.apple.com/watchkit for more information.

In particular the 2nd error is strange, as I’ve just used the standard Xcode Images.xcassets template to set the images. There is a 44x44@2x image required which I’ve definitely set to an 88 pixel square image, but it looks like there is a bug setting this in the archive generation.

Screenshot

I’m definitely not the only person seeing this issues, as there is at least one existing Radar bug been opened on the same topic. I also opened a Radar (23871724) - it seems opening duplicates is the best way of making sure Apple know it’s a common problem - which is now closed as a duplicate of yet another one (23859182) - so hopefully this is being addressed by Apple.

My guess is that this became a problem after I upgraded to Xcode 7.2, but I don’t have the energy to revert back to 7.1 to confirm.

I’m not sure if this will prevent the new version being released, so I’ve submitted it and all being well it’ll be available shortly.

Using JIMP to build an iOS icon resizer

Everytime I manually had to create some thumbnails for josiemccoy.co.uk, or a whole set of icons for an iOS app, I thought “next time I’ll write a script to automate this”.

Finally I got around to writing the script, which only took a few minutes which should save me, er, a few minutes each year.

Once I found the excellent JIMP package - a pure JavaScript image manipulation library - it was easy to write a couple of scripts to do exactly what I wanted.

The script to generate all the image sizes required for an iOS app is available on GitHub if you want to try it out yourself.

Daily Optimiser now available for the iPhone

After a pretty long development “sprint”, Daily Optimiser 3.0 has finally hit the App Store.

Apart from lots of under the cover changes and UI improvements, the big news is that the app - previously iPad only - is now available for the iPhone.

The reason it took us so long to release an iPhone version is we always assumed one of the key features of the app is the ability to see both your task list and meetings in one view.

However after a few UX experiments it turns out - not for the first time - I was completely wrong! Having a quick way of switching between the 2 lists is very useful, and the visible timeline pulls together the two views in “task mode” nicely.

Screenshot

One thing I didn’t solve in this version is a reliable way to sync which reminders are “most important tasks” in the cloud. I tried using Apple’s CloudKit, but this proved wholly unreliable in the way I was using it. Unfortunately I had to pull the sync feature from this release, but will almost certainly revisit this topic in later releases.

We’re also trying the “patron model” of funding, where users get all features for free, but if they feel so inclined they can make a one off in-app purchase to support us. In other words, shareware :)

Be interesting how this pans out, whether the (hopefully bigger installed base we’ll get for a free app make up for lost revenue).

I’ve got another idea for an interesting app, and I’m very much looking forward to tackling some new problems for a while.

Problem with underscores in domain names in IE

We found an “interesting” issue at work yesterday regarding IE, cookies and domain names that I thought might be useful to share.

At FindMyPast - where I’m currently contracting - we heavily use GitHub Flow which involves multiple development branches being worked on at once.

By convention we use underscores in our branch names e.g. “dev_feature_branch”, and have recently automated hosting of feature branches for test purposes. For example for the above branch we’ll setup a host for dev_feature_branch.findmypast.com

For a feature I was working on, everything worked great on Chrome and Firefox, but for some reason we couldn’t login properly using IE.

After much head-scratching, we fired up Fiddler which gave us the answer.

!! WARNING !!: Server hostname contains an underscore and this response sets a cookie. Internet Explorer does not permit cookies to be set on hostnames containing underscores. See http://support.microsoft.com/kb/316112

The obvious solution is not to use underscores in the domain name used for the virtual host, either by convention of stripping them out when setting everything up.

Hopefully if you see a similar issue, this may help you debug it quicker than we did!

watchOS 2 Complication Update Issue

Unfortunately there was a bug in v2.0.0 of Count The Days Left where the watch complication wasn’t reliably updating itself.

Fortunately the issue was interesting enough to blog about :)

What I believe was the issue - not 100% sure but it appears fixed now - is that a watchOS 2 app only has a limited budget of time where it’s allowed to update itself.

In the getNextRequestedUpdateDateWithHandler function in my complication data source class, I was telling the watch to update once an hour. This seemed a reasonable compromise (without thinking much!) where the watch would update itself once an hour automatically, even if the options for the countdown didn’t change - which forces a complication refresh.

However I believe that once an hour is too frequent. If you read the Apple Documentation closely, it says:

At the end of a scheduled update, ClockKit calls the getNextRequestedUpdateDateWithHandler: method to get the time for the next scheduled update. Specify a date as far into the future as you can manage. Do not ask the system to update your complication within minutes. Instead, provide data to last for many hours or for an entire day. If your budget is exhausted, the next scheduled update does not occur until after your budget is replenished.

Now obviously my count only updates once a day, so I can return in getNextRequestedUpdateDateWithHandler to next update itself at the start of tomorrow, which means it will only automatically update once a day (but should be correct all that day!)

It appears to have worked on my watch overnight, so I’m sending a v2.0.1 to the app store today (Wed 21 Oct 2015). The last version made it past review and into the store in about 2 hours(!), but it’s unlikely to be that quick again.

Update (2015-10-29)

Turns out it was more complicated than I thought :)

Even after the fixes above the complications still intermoittently failed to update overnight. I just think the “automatic updating” is just a bit flaky.

Anyway, I’ve much improved things by putting in an additional call to update watch complication every time the iPhone app, today widget or watch app is access. I also added a background app refresh handler in the iPhone app to call the same update method when ever it is intermittently called.

All of these calls shouldn’t be too frequent - so should have a neglible effect on battery life I hope - and guarantee as much as I can the complication is up to date.

Another version has been submitted to the app store, and hopefully this one will fix the issue.

N.B. All code can be seen on GitHub