December 2019

HeyClock is Live!

Late Saturday night, after nearly five months of development time, HeyClock and HeyClock Free went up for sale on the iOS App Store!

I’ll admit, I was nervous about the Apple submission process. In order to keep my app functioning in the background, I basically only had three methods available to me: background audio, background location services, or push notifications. You see, Apple *really* doesn’t want any app running in the background of a phone for more than a few seconds; if it doesn’t have an extremely good reason to be doing so, it gets suspended and is unable to run any sort of code or functions until the user brings it back to the foreground. Anyone keeping up with the slew of iOS 13 updates might remember the bit where the operating system suddenly became super aggressive when it came to dumping background apps, and what a problem that caused for everyone. That’s basically what I was up against, trying to create an app that is designed to run from the background.

Background audio is what most other alarm clocks use, under the guise of monitoring the quality of the user’s sleep. By recording audio in the background, the app basically isn’t allowed to become suspended, and so the app can keep a running tab on what time it is, and whether it’s time to set off an alarm. Of course, that will drain the bejesus out of a phone battery, but most people typically plug their phone in for the night anyways, so it’s not a major concern. However, that really wouldn’t work for HeyClock- it’s supposed to be an “out and about” app, that you keep active while your phone guides you through your day, reminding you of all the things you need to get done.

I considered push notifications very strongly, but not only does it lead to privacy concerns, that method would require setting up some sort of client/server architecture that would be far more complex than what I had originally set out to do. Push notifications come from a server- it’s just a simple signal sent to a device with a small payload. In order to make that work, I’d have to have the user’s phone send information to the server regarding when and how often alarm notifications need to be sent, and then the server sends the notification after the proper amount of time. While I doubt HeyClock will ever become a large-scale international phenomenon, I wanted to make sure that, whatever I ended up with, it wouldn’t be too difficult to scale up to a large number of users. Having a program running on a server that collects thousands (hundreds of thousands? Millions?) of users’ information to send them notifications at the proper time would get extremely complex. In addition, though I couldn’t find any solid limit in Apple documentation (no surprise there), the general consensus in online development forums seems to be that Apple devices only allow a particular number of push notifications per hour, per app. If someone wanted (for whatever reason) an alarm that would go off every couple minutes, I might not be able to use a push notification after all.

Location services seemed to be the only option. All I needed to do was flag the app as using “background location services,” set up a listener to watch for GPS pings, and then tell the device what sort of GPS accuracy I wanted. A little bit of experimentation let me know what sort of ping frequency I could expect out of the different GPS accuracy settings, so then I just had to adjust the frequency based on the time until the next expected alarm. If the next alarm is more than five minutes away, I could go with the lowest accuracy. Once I’m between 1 minute and 5 minutes, I can go with a medium accuracy, and when it’s 1 minute or less, I increase the accuracy to something much higher to get pings once per second, until the alarm goes off.

The problem with using location services, though, is that it’s a very obvious hack. Just like “sleep quality monitoring” for audio, I needed a justification to enable background location services in my app. Even adjusting the GPS ping frequency, I expected the battery drain to be noticeable (any app running in the background periodically is bad for the battery, let alone one that depends on a radio receiver). So, to kill two birds with one stone, I implemented a “home address” system- the user sets up to three different locations with a a radius of about 500 meters inside which routines will go off like normal. When the user exits that geofence, the GPS mode is changed from regular pings to “significant location change,” and the code that would normally run after a ping is paused. I’m not sure how much of an advantage it ended up being to the battery (at least some, I’m sure, but there’s really no good way to measure how much of an impact a single app has on battery life like that), but I personally though the idea of preventing apps from going off outside of designated areas was more useful. Imagine being in an extra-early business meeting, and suddenly your phone shouts at you from your pocket “Hey, get up, doofus! It’s already 7:30, don’t be late!”

Luckily, whoever was responsible for validating my app decided that was justification enough, and in what has to have been the speediest I’ve ever seen or heard of having an app approved, my HeyClock and HeyClock Free was available on the iOS App Store about an hour and a half after I submitted them!