hmb_admin

HeyClock v2 and Waking Dream

You might notice a new block under the “Projects” listing on the HMB-Tech homepage- I’ve officially decided to add the point-and-click RPG I’ve spent the past 10+ years working on under the HMB-Tech umbrella!

After finishing up the Android HeyClock, I started immediately on the version 2 modifications- things like tagging different routines to allow you to sort and filter on the “home” page, and adding in new options to the message so you could include things like “time until the routine ends” or “time since the routine started.” That would let you build messages that sound like “Hey! It’s 7:45, you’ve only got fifteen minutes left before you need to leave for work!” I started out making pretty good progress, but I think a year of staring at the same code finally just wore me down- I needed something else to work on.

I’ve toyed around with the other two mobile projects- I started on the pokey-swipey game in Xamarin, as a sort of proof-of-concept for getting something like that to work in a cross-platform engine (so I wouldn’t have to completely rebuild it from scratch in Android once finishing in iOS, like with HeyClock). I also put a little bit of effort into the bluetooth methods needed for my party game app to communicate across a bunch of different devices at the same time, but in the end, I really just wanted to work on something fun, something just for me. So I dragged out my in-progress game, blew the dust off, and set about updating Unity. In the last week, I’ve made a lot of progress in it, and decided that I’d like to merge my development blog for that game with the HMB-Tech site (which you can now get to from the “projects” blocks, or at www.hmb-tech.com/wakingdream).

So, what is Waking Dream? First of all, that’s only a working title- at the moment, I’m leaning more heavily towards “Forge of Asha,” but I’d already bought the domain www.wakingdreamgame.com way back in the day for that blog (which now redirects to the HMB-Tech version; thankfully I’ve finally managed to escape from Godaddy’s laggy clutches). If you poke around in the blog, you’ll see entries going back to 2010, though it looked extremely different back then, both in style and content. The storyline has gradually evolved, and as it became more complicated the game style had to change with it. The current form is going to be like the traditional point-and-click games from Sierra, but with some extras thrown in for various special circumstances (JRPG-style combat, a Persona-similar time-and-event management system, and probably some kind of zoomed-out world map for international travel).

But what is it actually about? Without giving too much away, the current story is takes place in the near-future, and focuses on the player working with a small group of folks thrown together through circumstance to help rescue a girl from a possibly nefarious organization.  Doing so ends up having long-reaching effects on the entire world, and the group will have to come to terms with the consequences of their actions.

I don’t expect to be finished with this at any point within the next couple years (especially considering the rate of accomplishment over the last ten years), but it’s sort of a passion-project of mine, and I find it necessary to inject a little bit of passion into my programming from time-to-time to help ward off burnout.

HeyClock- Android vs iOS

Work on the Android version of HeyClock is still running full steam ahead. However, I’ve definitely been presented with some head-scratchers when it comes to scheduling the alarms. Who would have thought that it would be easier to get a recurring event triggered from the background in iOS than in Android?

In iOS, the only reasonable way for me to trigger events regularly was to monitor the current time by watching the pings from the phone’s location services. When the timestamp matched the scheduled time of an event, I ran the code necessary to make the event happen. The location services monitoring code is allowed to run in the background, and so even with the phone in some sort of OS sleep mode, it still sees everything.

I’ve been spending time matching the Android data and layout to the iOS version- since working with iOS’s constraints system took up about 80% of the development time on HeyClock, I expected the Android version to go much more smoothly. And it did, in that aspect. I still need to tweak a couple things visually, but the layout is mostly finished.

HeyClock on iOS:

HeyClock on Android:

Back when I first started working on HeyClock, I read a little bit about scheduling events in Android, and it didn’t seem too difficult. In fact, it seemed like it was going to be WAY easier than in iOS- there were specific functions for scheduling an event to happen, and a special function specifically for making the events cut through a phone’s “sleep mode.”
Now that I’m actually working on it, though, I’m finding some issues. The test device I’m working with runs the oldest version of Android that HeyClock will run on (API 22, Android Lollipop), and I wasn’t expecting any issues at all getting scheduling to work since that version of Android didn’t even have the “Doze” sleep mode. However, it’s a Samsung Galaxy S5 Mini, and I guess it has some sort of manufacturer-specific power savings mode, because it’s definitely going out of its way to prevent certain services from starting until the phone’s screen has turned on- namely the Android Text-To-Speech service.

I went around and around, trying out different methods of starting the text-to-speech function in its own service, its own process, its own service AND process, and configuring those services and processes in different ways. Between that, and the fact that “Doze”-enabled phones only allow scheduled events to take place within particular “maintenance windows” (sort of defeats the purpose of scheduling them, doesn’t it?) it took some doing, but it looks like I’ve finally settled on a combination that works.

I’m using the AlarmManager setAlarmClock() function to use the phone’s built-in alarm clock manager to execute code at a given time (pretty close to that time, anyways; I don’t need millisecond precision). When it does, it automatically lets the app handle 10 seconds worth of execution before “putting it back to sleep” if it was in Doze mode. As soon as the alarm goes off, I start a foreground service with a wake-lock, and use that service to execute the Text-to-Speech stuff (since the TTS initialization sometimes takes a few seconds, it might not have finished by the end of the alarm clock’s 10-second window). I’ve tested this one after letting the phone sit motionless for 10 hours, which should have been plenty of time to force whatever internal Samsung sleep mode was preventing it from operating before- works perfect! Now, the real test will be to run it on a modern Android device (running at least API 28) to see what happens once Doze mode comes into play. I’ve got a used Motorola Moto G7 Power in the mail- being able to test it out in the oldest possible and newest possible Android versions will be absolutely necessary.

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!

Hey, Listen!

HeyClock is the current app “on the workbench” for HMB Tech. I’ve got the basic layout finished (which was a lot more frustrating than it should have been; if Apple thinks their app development process and interface is intuitive, they need to go check out a few dozen other languages and IDEs first to see what “standards” look like) and have started working on the “tidying up” of small features before I move on to the next major phase- the timing and recall of events.

One thing I’ve spent far too long on is the actual speech itself. iOS provides the AVSpeechSynthesizer class to let you convert speech to text without any real effort- you simply instantiate an instance of the class, and start passing it AVSpeechUtterance objects (basically strings with a few extra options baked in so you can tweak things like playback speed and pitch) with the speak() function. And that’s it.

Or so the documentation claimed. I had a hard time getting the “Hey” part of the speech to sound natural- rather than what sounded like a lady robot disinterestedly reading the word off of a cue card, I wanted it to sound more like someone trying to legitimately get your attention. Hey! The first thing I discovered was that you can use a NSMutableAttributedString instead of a normal string when creating an utterance, and give it AVSpeechSynthesisIPANotationAttribute as an attribute. This lets you assign pronunciations in IPA format to describe exactly how you want it to sound. Unfortunately, (per usual, as I’m slowly discovering) Apple didn’t think it’d be important to document any specific information when it came to this feature, notably regarding which unicode symbols it will actually accept when it comes to IPA. After spending close to an entire day trying out hundreds of different combinations, I discovered that the answer is “not many.” I was really hoping to use some of the tonality IPA symbols to make the “Hey” sound a little more urgent, but the AVSpeechSynthesizer seemed to mutate all of my attempts that contained unrecognizable symbols into “Hurr.” How appropriate.

After giving up on the IPA pronunciation route, I started messing around with playback speeds and pitches, until I found something that sounded slightly more realistic than the chipmunk-esque results of my first attempt. That was all well and good, but you can’t change pitch or rate partway through an utterance; it’s all or nothing. So now I had to break the message up into two utterances- the “Hey!” and the actual message itself.

I then spent the next several days trying to figure out why, despite everything the Apple documentation and plenty of online tutorials and forums claimed, the AVSpeechSynthesizer object wouldn’t queue up a second utterance.

let synthesizer = AVSpeechSynthesizer()
let utterance1 = AVSpeechUtterance(string: "first")
let utterance2 = AVSpeechUtterance(string: "second")

synthesizer.speak(utterance1)
synthesizer.speak(utterance2)

This, pasted inside a button push, resulted only in “first” being spoken. If I commented the first speak() out, I got the second one. As far as I could tell, the documentation just straight-up lied about the queuing functionality. Nobody else seemed to be having my problem, though. Of course, it didn’t help that there were hardly any hits in the first place for use cases similar to mine; just about everyone else out there was using the delegate feature to sense when an utterance was finished before doing something else. I wanted to stay away from that, though, since my ViewController is already a delegate for a dozen other things, and I’m trying to cut down on its complexity.

Have you spotted my error yet? Maybe not, because you might be making the same sort of assumptions I did about garbage collection here. I don’t see why you wouldn’t; they’re perfectly intuitive assumptions to be making. But, as I’ve already complained about several times, “intuitive” and “iOS development” don’t really intersect anywhere in this reality.

I was assuming that, as long as there were still utterances left in the AVSpeechSynthesizer queue, the garbage collector would keep from discarding it even after the program execution left the scope of my button push. It finishes speaking the first utterance, doesn’t it? I figured there would be only two options- either the synthesizer gets trashed as soon as the button-press event is over (in which case I probably wouldn’t even hear the first utterance) or it would wait until the synthesizer’s queue was empty before discarding it. In reality, it seems to wait for a “break” between utterances before trashing the synthesizer. As soon as I moved my AVSpeechSynthesizer out of the local scope of the button-push function and created it as a global in the view controller, it worked just fine.
Scope. It’s more than just a mouthwash.

This brings my “tidying” phase to a close, and now it’s time to get serious about finding a good method for scheduling an “alarm clock” style of notification, which I’m sure will lead to another blog post at a later date.

Welcome to Hold My Beer Technologies!

This website is basically the last step I still needed to take to “legitimize” the app development company I conceived of almost two years ago, and officially got a license for just a few weeks ago.

The site itself, you might notice, looks a little goofy- I’m trying to walk a fine line between “We are a professional software development company” and “Hey guys, let’s not take ourselves so seriously, right?” The company itself isn’t likely going to be a full-time venture on my part for at least several years, if at all, and so I don’t want to sink too much manpower and resources into it. I still want something fun to show off, though! Plus, now that I have an actual website for the company, I can start looking in to things like trademarks and copyrights (since, in the USA, you have to show that you’re using a trademark in order to actually register it).

For now, I only have one main project in the works- HeyClock, which I’ll go over in more detail in a later blog post. The “unnamed party game app” listed in the main site’s projects is really the inspiration behind the company’s name- I don’t have a single line of code written for it yet, but I’ve got a plan that I hope to start implementing once I finish up with HeyClock.

For now, feel free to click around in the site, enjoy the scrolling animation I painstakingly programmed from scratch, and bookmark this development blog to see what HMB Tech’s future holds in store!

Hello World

I mean, that’s the traditional “opening attempt” at anything programming-related, right?

This is a brand new WordPress blog, installed under its own subdirectory in the HMB-Tech site’s root folder. This will be the first post in that blog.