Making an iOS custom dialer app with Shortcuts and elm-spa


Many moons ago I wrote an Odorik iOS app that allowed comfortably setting up a callback on my VOIP/GSM operator of choice – Odorik.

But since Apple Developer membership isn’t exactly free (and the app was written in Rubymotion, which switched to subscription model), it was uneconomical to keep the app updated and in the AppStore. Last year I pulled a plug on it.

But turns out that I would still like to easily setup callbacks! And so would others, that miss it (I’ve got several emails).

Spoiler alert: This post documents the journey to a viable replacement built on top of iOS Shortcuts app (by Apple) and elm-spa.

Problem statement

I, as a user, want to select a phone number from one of my iPhone’s contacts, and have an app setup a callback – with that number as a target – for me.

For those of you who don’t know, callback is basically a two-legged phone call. Odorik’s PBX first calls one number, then another, and connects them together.

Why is that useful? Say you reside in Switzerland, but have a lot of people to call in the Czech republic. Outgoing call rate from your GSM operator is horrendous1. So you have Odorik dial out to your phone, and connect you internally with the destination number. Both legs combined add up to a fraction of the normal (per minute) cost.

The easy parts

Odorik already publishes their API. And a monkey with a screwdriver2 can do an outgoing HTTP POST call, so setup a callback for me is trivial.

The hard parts


Let’s start with one of my world-famous arch diagrams:


Architecture implications

In order to avoid cookies and storing any user data in general3, I had to find a way to make use of client javascript.

Fortunately, localStorage is a thing. So I can store some amounts of data directly on the iPhone. And call the Odorik API also directly from the iPhone.

Thus the webapp simply serves as a (client) software delivery mechanism.

In order to avoid passing the contact data, I resorted to using the #hash part of URL. As hashes are not part of HTTP requests. They are only processed in the browser.

With those two, the data privacy issue is solved4.

Shortcuts app – selecting the contact & forwarding

Apple’s Shortcuts app5 is one of the iOS’s best kept secrets. By that I mean that it’s severely underutilized (as far as I can tell), apart from a few superusers.

And it’s a shame. Because apart from the drawback of visual workflow creation, it is the single best “glue” you can find for iOS.

To Script the necessary workflow, I basically:

  1. Asked to select a contact
  2. Grabbed name, label, number
  3. Encoded as json
  4. base64encoded that
  5. Called out to the webapp (<datahere>)

Check this out:

workflow thumbnail workflow thumbnail; click for full-size version

Granted, I also added an extra feature where numbers with a certain (customizable) prefix (+41 for me, skip by default) cause the workflow to dial the number directly instead of setting up callback. That way I can use one app for all my calling needs.

The shortcut workflow is downloadable here if you want to poke around.

To view/install it, you need to visit System settings → Shortcuts → Allow Untrusted Shortcuts.

After installation it can be also added to the Home screen, by tapping the three dots (visible in the screenshot above) and selecting Add to Home screen from the sharing sheet (modal menu).

The web app

How I wish I could say “oh, it was super easy, barely an inconvenience”.

That would be lying, though.

I kept banging my head against the wall for a few days. Fortunately, I’m unaware of any lasting brain damage as a result. ;)

I think that’s in part thanks to Alex Korban’s books (Practical Elm and elm-ui: The CSS Escape Plan), which cleared up some sticky points for me. (Http tasks, for one)

Those resources, coupled with a whole lot of web-searching allowed me to go from zero to functional in… sigh… a more than a few evenings.

If you’re really interested in particulars6, look at the commit history.

Because I’m unsure how to put my experience to words.

I’ll touch on a few points:

In the end, it could be the noob in me talking. :-)

To conclude, check the source if curious.

Or the deployed website; demo credentials included.

Final words

Here it is. An Shortcut workflow and a single page app. To get callbacks through Odorik working.

I’m happy with the result, even if there’s ample room for improvement.

Can’t wait to hear what other iOS users of think.

Meta: I’ll continue poking both Shortcuts but also elm in further posts (after all, the Yamaha Soundbar needs a proper “UI”).

  1. Hello, Sunrise.

  2. That would be me.

  3. It would be a privacy nightmare to process someone’s contacts with phone numbers!

  4. Inevitably someone will stop by to tell me that I (or an attacker) could deploy a malicious app that steals all the contact data. Yes, you’re right. If that a concern, please deploy your own instance of it. It ain’t a rocket science.

  5. Which used to be called Workflow by a third party devs.

  6. In other words, knowing what it takes for a total elm noob to write an elm web app that compiles. [Nobody dares to say anything about “idiomatic” here.]