WWDC19 Reactions

2019-06-07    ✪Permalink

I’m still digesting all of the news from this year’s WWDC, but it was a fantastic year as far as I’m concerned. Reflecting on my wish list, I got a remarkable number of the things I was looking for.

Mouse and Keyboard Support

Though Apple have been relatively coy about it, it certainly looks like mouse support is here, albeit as an accessibility feature. It looks like some devices are supported over Bluetooth, and some only USB (trackpads?), but I’m excited to try this out. I have a few questions how about scrolling and text selection1 will work, but we’ll have to wait and see.

Keyboard support certainly seems to be improved across a number of system apps such as Safari and Files. I’m unsure as to whether the new multitasking features are controllable by the keyboard, but in a way mouse support makes this slightly less urgent. The main thing is that I can get around the OS without having to reach up and touch the screen.2

Speaking of input more generally, voice control is amazing. I’m definitely going to be using it for dictation, where I’ve long wished to be able to correct mistakes while speaking – but also I’m keen to see if I can get value from it more generally. I should also have had swipe typing on my wish list, but I was thinking mostly of my iPad when I put it together. I used to be a super-fast thumb typist, but I find it uncomfortable nowadays, and when I moved to Gboard for a while, I found swipe typing much better ergonomically3. But I wasn’t that keen on the potential privacy implications all of my text input going through a third-party keyboard, so I stopped using it. Now I can have both ergonomics and privacy. Swipe typing is also available on the iPad, which now has a detachable iPhone-sized floating keyboard you can move around the screen. This thought led me to realise what might be the most awesome new text input method: swipe typing with the Apple Pencil on the floating keyboard ⌨️✍🏻🤩. Can’t wait to give this a try.

Xcode for iPad

Sadly we didn’t get it this year, but it’s got to just be a matter of time. As I said during the keynote, the new SwiftUI framework makes this much more feasible for the future because it makes the link between code and UI both stronger and simpler. Swift Playgrounds doesn’t have Xcode’s interface builder – being very pointing device dependent it’s difficult to see how it would easily translate from the Mac. SwiftUI along with its previews feature, however, is something I can easily imagine on an iPad. I can’t wait until it’s supported in the Swift Playgrounds iPad app.

Odds and Ends

I’m happy to say that I got a lot of these. Improvements to Siri Shortcuts, including the Shortcuts app look amazing. With shortcuts now able to take input and pass output, the possibilities to add scripting in the middle of multi-step shortcuts have really expanded. I’ve no idea if the command-tab list has been made more logical, but with the overhaul to multitasking more generally I’m optimistic. The new Files app has come a long way, I can now have widgets on my home screen, and halleluja there are shared folders in iCloud Drive.

Tidbits

Apart from all of the above, there were still plenty of things I was surprised and delighted by. It’s worth having a look at this amazingly comprehensive list of new features that Apple put together. Several things that jumped out at me which didn’t get big headlines.

Siri:

Add custom words
Whether you’re writing a biology report, filling out a legal document, or emailing about a favorite topic, you can add custom words to ensure that Voice Control recognizes the words you commonly use.

Radio
Ask Siri to tune in to your favorite radio station.

Share sheet:

One-tap suggestions
When you share a photo or document, receive a suggestion about who you might want to share it with and which app you may want to use, so you can share with just a tap.

Messages:

Share ETA
Share your estimated time of arrival with family, friends, and coworkers. Your ETA even updates should a significant delay occur.

Improved search
Search in Messages makes it easier to find what you’re looking for. Even before you type a character, you can see recent messages, people, photos, links, and locations you might be looking for. When you type in a search, Messages categorizes the results and highlights matching terms. You can also search within individual conversations for the message you’re looking for.

Notes:

New checklist options
Quickly reorder checklist items using drag and drop, swipe to indent items, and move checked items to the bottom. If you’ve completed the checklist and want to use it again, you can click to uncheck all the items and start over.

Folders and notes management
Organize your notes by creating folders and nested subfolders and easily manage how they’re organized in your folder lists.

View‑only collaboration
Share notes and entire folders as view only so you’re the only one who can make changes.

I haven’t quite decided if and when I’m going to jump on the beta train. I think I will definitely wait until at least public beta 1 if not 2, but I’m really excited to try out all of these new features.


It now really feels to me like the iPad has crossed some kind of threshold of maturity. When people asked me in the past whether they should buy an iPad instead of a laptop, I would generally explain that it was a fantastic device that could do pretty much everything, but that there were a few sharp edges here and there. Either you had to be a bit nerdy to find a good workaround, or you just hit a brick wall. These brick walls were things like working with two Word documents, getting a PowerPoint off a memory stick, or using a web app which assumed a desktop browser. All of these obstacles are now gone, and I would have no reservations recommending the iPad as a truly excellent personal computer.

  1. The new methods for text selection with a finger may remove this concern. 

  2. I did see this tweet, but I haven’t seen anything else corroborating it. 

  3. It allows you to hold the phone with one hand and type with the other without being unbearably slow. 

WWDC19 Wish List

2019-06-03    ✪Permalink

I’m really looking forward to watching Apple’s WWDC19 Keynote this evening (UK time). As an iPad first user, I think it’s going to be a big one for me. For better or for worse, big iPad updates now come every two years, so today is the pivotal moment when we get to see Apple’s plans for the future of the platform over the next two years. Here are my personal priorities for iOS 13 on the iPad.

Mouse Support

These aren’t meant to be in any particular order, but yes, I am putting this one first. When I first moved to the iPad as my primary computer three years ago, I used to laugh at people who asked for this. I thought you might as well ask for the iPad to be steam-powered or have a hand crank1. But given how much I’m now using my iPad, especially with the Smart Keyboard, I’ve been really feeling the need for this ergonomically. When using the iPad “like an iPad” this just isn’t necessary: the input surface and the output surface are one and the same. But with the Smart Keyboard – which Apple suggests you might want to use with your iPad Pro – the two surfaces become separated. We’ve had a way of dealing with this separation for over fifty years: it’s called a mouse, and I hope Apple offers it at least as an option for those who want to use it with their iPad.2

Better Keyboard Support

I love the Smart Keyboard, and I love apps like Things that really take advantage of it, but I wish more apps had such extensive keyboard shortcuts, and that the system did too. It needs to be at least possible to use an iPad solely with the keyboard. Keyboard input also needs to work better with multitasking, where it can often be unclear which app in a split view is the one responding to keyboard input and keyboard shortcuts.

Xcode for iPad

I recently built my first ever app, and I did it using Xcode on an old MacBook Air. The device was perfectly suitable for the job, but the iPad is still my favourite computer, and building apps is the one thing I want to be able to do there that I still can’t3. For an iPad-first user like myself, Apple is currently saying that I should just buy a Mac as well, and I slightly worry that they are tempted to prolong this situation because of the obvious revenue benefits. But what I really want is one great computer, not two. The iPad for me is so close to being that one great computer, and I hope that it can become that.

Odds and Ends

  • Improvements to the Shortcuts app and Siri shortcuts more generally.
  • Some kind of Swift for Automation technology, perhaps in Shortcuts.
  • Make the command-tab switcher work like it should.
  • Better Files app.
  • Widgets on the home screen.
  • Shared folders in iCloud Drive.

Ten years in, it’s time for iOS to fully mature into a self-sufficient computing platform. I’m looking forward to seeing how Apple moves towards that goal.

  1. What a ludicrous idea 😉 

  2. Even better would be a trackpad on the next Smart Keyboard. 

  3. There are a few other developer features that would be really welcome too. 

RSS Digest for Kindle

2019-05-24    ✪Permalink

A shortcut I made ages ago that I’ve been meaning to share. I like reading RSS, and I like reading on my Kindle, so I decided to try and make a shortcut that could turn a list of RSS feeds into a daily digest of articles I could read on my Kindle.

The shortcut leverages the Send to Kindle share sheet extension which is able to accept PDFs and convert them to Kindle format. Once the shortcut has run, the share sheet will appear. Select Send to Kindle and then on the dialogue box that appears hit Send. You will then be asked whether you want to convert the PDF to Kindle format, and you should hit Yes.

There were a couple of interesting challenges building this shortcut. One was dealing with block quotes, which the Kindle format simply turned into normal text, making articles containing them confusing to read. Having no idea how the Kindle app does the PDF to Kindle conversion, I wasn’t able to find a way of having the resulting document display indentation or a vertical line. My compromise was to just turn all block quotes into italic text, and the result is actually pretty good.

The other challenge was a feature I decided to add while writing this post. On iOS my current RSS reader of choice is Unread. It’s an app I’ve always liked because it just gets all the usual UI elements out of the way and lets you read uninterrupted, and the controls to the app are a rather elegant selection of gestures. But I’ve been playing around with Fiery Feeds recently because it allows feed subscriptions to be added within the app. Using Unread means I have to deal with the Feedly website, which is not great and downright impossible to use on an iPhone. Fiery Feeds and several other apps allow you to export OPML, so I wanted to offer support for that as a convenient way to use this shortcut with your existing feeds. I cobbled together some regex which seems to do the job. 1

I had a half-working version of this shortcut that also included articles that were linked to from link posts, but hit a brick wall in making that work in a satisfactory way. Different blogs just don’t seem to be consistent in the way they indicate which posts are link posts and what the linked URL is. If anyone has any ideas how to make this work, let me know.

You can download the shortcut with this link.

  1. I wish the JavaScript action step in the Shortcuts App could be used outside of a webpage, in which case I’m sure there would be a more elegant way to parse that information. 

Quick Open Action for Drafts

2019-05-21    ✪Permalink

Just whipped up a super simple little Drafts script action which I thought I’d share. By default, Drafts opens with a blank new draft, ready to capture your thoughts. If you’ve just been working on a draft, however, it will reopen when you switch back to the app, as long as you haven’t been inactive for too long. In settings, you can adjust that time delay to whatever suits you best. When you find your own sweet spot1, it’s a fantastic feature which pretty much always does what you want without your having to think about it.

Just occasionally though, you end up on the wrong end of that delay. If you launch expecting a blank draft, and your previous one is still there, you just hit ⌘N. But what happens if you end up with a blank draft when you were expecting to reopen your previous one?2 My solution was to create a two-line script action to quickly open the most recently accessed draft3 with the keyboard shortcut ⌘O:

let recent = Draft.query('', 'all', [], [], 'accessed', true, false)[0]
editor.load(recent)

It’s one of the simplest script actions I’ve made, but also one that I now use frequently. You can download it now from the Action Directory.

  1. Five minutes for me. 

  2. Drafts does offer a “focus mode” to prevent this from happening, so this action is just for when I forget to turn it on. 

  3. The action only works if you don’t edit the blank draft first. For a longer list of recent drafts, there’s a combination of built in keyboard shortcuts you can use. Just hit ⌘\ then use the right arrow key to select Recent Drafts, up and down arrow keys to navigate between them, and return to open the one you want. 

The Line Between

2019-05-14    ✪Permalink

I’m currently reading The Gulag Archipelago by Aleksandr Solzhenitsyn (the abridged version). While a gruelling read at times, it’s certainly a worthwhile one. His writing manages to hold together within it so much dark and light. Sometimes it even makes you laugh:

Marx … declared with equal conviction that the one and only means of correcting offenders … was not solitary contemplation, not moral soul-searching, not repentance, and not languishing … but productive labor. He himself had never in his life taken a pick in hand. To the end of his days he never pushed a wheelbarrow, mined coal, felled timber, and we don’t even know how his firewood was split – but he wrote that down on paper, and the paper did not resist.

But it was this passage that I was recently struck by:

Gradually it was disclosed to me that the line separating good and evil passes not through states, nor between classes, nor between political parties either – but right through every human heart – and through all human hearts. This line shifts. Inside us, it oscillates with the years. And even within hearts overwhelmed by evil, one small bridgehead of good is retained. And even in the best of all hearts, there remains … an unuprooted small corner of evil.

I think this is a lesson we need to re-learn in our present times. Increasingly we seem to police one another’s speech and thought against the modern heresies, and we are only too quick to excommunicate. The motivation is what it has always been: to root out evil. But the mistake is also what it has always been: to measure the demarcation according to affiliations – good and evil defined by what party you support, whether you voted leave or remain, by your moral or religious beliefs.

The struggle is one in which we all need to be engaged, but each of us needs to recognise that we have an allegiance to both sides.

Cacio e Pepe

2019-05-11    ✪Permalink

The dishes I most love to cook are the deceptively simple ones. Typically they contain very few ingredients, but require care and attention to master. It also helps if they’re considered a classic of their cuisine. I don’t know what it says about me, but I’ve always been drawn to those areas of culture where there is considered to be a right way of doing things.

I recently discovered a dish which very much ticks all of these boxes: the Roman speciality cacio e pepe, literally cheese and black pepper. It consists of just three ingredients: spaghetti, pecorino cheese, and black pepper1. The inherent problem that this dish presents is that its sauce is a blend of cheese and water, two substances which don’t in the normal course of events prefer to intermingle. Done wrong – and I did so many times – you end up with lumps of cheese with the consistency of wet chewing gum.

The key to avoiding this is to understand the importance of the starchy pasta water. The starch helps the water and the cheese to mix together properly to make the proper sauce, and a higher concentration really helps.

Here is my reasonably reliable recipe:

  • Boil a pot of water. Use less than you would usually use for pasta. Add salt.
  • Grate the pecorino cheese. It needs to be very finely grated, almost a powder. Use the side of a box grater which has protruding spiky holes.
  • Once the water has boiled, add the spaghetti and cook roughly half way to al dente.
  • Heat a frying pan, grind in lots of black pepper and toast briefly.
  • Add the spaghetti to the pan, along with some of the water. Slowly add water as it reduces. This increases the concentration of starch in the water.
  • Add some water to the grated cheese in a bowl, stir to form a smooth paste.
  • When the pasta is ready and the water is mostly reduced, remove from the heat and stir in the cheese. If all goes well they should blend together to form a creamy sauce.

One of the best YouTube videos for this recipe I came across was this one by a rather engaging Frenchman named Alex.

Buon appetito!

  1. Five if you include water and salt. 

Grader+

2019-04-20    ✪Permalink

Today I’m very excited to announce the release of my first ever iOS app, Grader+. It’s a simple utility app, primarily designed for teachers marking tests and exams. It’s available on the App Store now as a free download, with a $0.99 in-app purchase to unlock the premium features.

My motivation for creating it was twofold. Firstly, it’s an app that I wanted to exist so I could use it myself. The way I mark, I go through tests question by question, writing the number of marks for each question on the paper. At the end, I then need to add up the marks for each student to work out their total mark and then record it. Grader+ is designed to help with the adding up and recording part of that. Now you might think – as a maths teacher – that I would be good at adding up, but in practice I would frequently lose count and have to start again, especially when I had to stop and re-mark something I had missed along the way. Other options include using a calculator, and just pressing the plus button every time, but that doesn’t solve the recording problem; or recording individual marks directly into a spreadsheet, a technique that can be useful if you want to analyse the breakdown of marks question by question, but is also time-consuming and difficult to do on the go. What I wanted was a way to record an individual mark with a single tap, and then save each mark quickly and easily. That core functionality was the inspiration of this app, and then the other features grew from there.

Secondly, my motivation for wanting to build an iOS app from scratch was to begin to properly learn the Swift programming language and the ways it can be used to build apps. I also wanted to get to grips with Xcode, the Mac app one uses to actually put the parts of the app together. I learnt a lot of the fundamentals of iOS app design from this process, especially UI design – a part of programming that I had never done before. I’ll talk more below about some of the resources I’ve found most helpful.

Grader+ Features

Firstly, I want to run through the basic features of the app and how it’s intended to be used, and I think it makes sense to do this screen by screen.

Counter

The counter tab of the app is where marks can be entered. By default it counts up, but this can be changed in settings if you are used to beginning from a maximum score and taking marks off. Alongside the total so far, the counter display also shows the last few marks entered (to help you keep track) as well as percentages1, grades2, and ranking. Saving a score will prompt for a student name, which is then saved, along with the score, to the scores tab.

Scores

The scores tab is where scores are recorded, and can be configured in settings to display percentages and grades and to sort the results in various ways. There is also an option to display statistics for all of the scores. The first of the premium features is available on this screen in the share button, which allows you to export the scores to a CSV file for easy importing to a spreadsheet, which is where these things usually end up.

Grades

This screen allows you to create and edit grade boundaries. They can be be entered as percentages or as marks3. The percentage for each one is the minimum threshold at which a grade should be awarded.

Settings

I’ve mentioned most of the settings already, but one notable one I haven’t is the other premium feature: dark mode! Why? Because it looks cool.

Learning Swift, iOS, and Xcode

There are a lot of great resources out there for learning how to make iOS apps, but I wanted to mention a few of the ones I found most useful. As a total beginner, I wanted to see someone actually make an app from scratch in Xcode to see what the process involved, and I discovered a course from Stanford University called Developing iOS 11 Apps with Swift, available on iTunes U, as a podcast feed, and also on YouTube. I watched the entire series, completing some of the assignments as I went along, and the lecturer, Paul Hegarty, does a really good job of explaining the ideas and techniques. The course does assume knowledge of the concepts of object-oriented programming, so go and do some reading on that first if you’re not familiar.

When I got stuck, I would google my issue, and I frequently found the solutions on one of the following websites:

In particular, I would not have been able to have figured out in-app purchases without this great tutorial.


I hope you enjoy using the app. It’s available now on the App Store, and if you want to support its development, and the development of future apps, please do unlock the premium features and throw a dollar (or a pound) my way.

  1. Requires a maximum score to be entered in Settings 

  2. Requires grade boundaries to be entered in the Grades tab 

  3. The latter only if the app knows the maximum score 

The Fragility of iMessage Conversations

2019-03-14    ✪Permalink

A couple of times recently, I’ve had a family member or a friend come to me with a problem. At first it seems like no big deal: they accidentally deleted an iMessage conversation, and they just need to get it back. It might have some information they need, or it might have sentimental value. They look in vain for an undo button; dare I say it, they might even shake their phone. But to no avail. When I break the news to them that there is basically no solution, or that the solutions that do exist involve considerable inconvenience or drawbacks, they can be distraught, and rightly so.

Our text messages are the form of communication we have that most closely mirrors our everyday interactions with the people in our lives. The archive of these snippets of text, stretching out into the past, tells a story of the mundane and the intimate that is our lived experience. For some, the brevity of these messages makes them essentially ephemeral: a trail of crumbs we leave behind us, never returning to pick up. But for others, the unique record that they hold makes them incredibly precious, perhaps as precious as photographs, particularly when it comes to loved ones who have passed away.

With this kind of data, it’s our natural assumption that the more precious it is, the better it should be protected. Apple has made a lot of progress in this regard with services like iCloud Photo Library, which remove a lot of the worry of losing or breaking a device.1 However, it’s my contention that iMessage is where Apple is currently getting this the most wrong. Our iMessages conversations are highly valuable to us as irreplaceable personal data, but they are also far too easy to accidentally delete and very difficult to recover. A swipe and a couple of taps is all it takes.2

iCloud backup had previously solved the problem of losing your messages when you lose your phone. Since messages were stored in your iCloud backup, restoring a backup to a new device would restore all of your messages as well. Some kind of answer involving iCloud backups is what you will most often find online when you search for solutions to accidental deletion of conversations. But depending on when your last backup was, restoring your phone using a backup is likely to result in other data loss, since messages received after the time of the backup would not be contained within it. Other suggested solutions involve downloading third-party software which offers to take an unencrypted iTunes backup of your device and go digging around for your lost data. I won’t bother explaining why that’s a bad idea.

With iOS 12, the situation changed, or at least it could change. iOS 12 introduced the option – by default disabled – to store iMessages3 in iCloud (by which I mean iCloud storage not iCloud backup). In some ways, this makes things better. My full archive of messages is no longer preserved only in the iCloud backup of my oldest device. If I get a new device, or wipe and restore an old device, that archive is now synced in full. That sense of permanence, independent of a particular device, is what encouraged me to turn this option on and to recommend to others to do the same.

However, it also introduces a considerable downside. Deleting a conversation now results in it being deleted across all devices. And since it’s no longer stored in an iCloud backup, winding back the clock by restoring a backup does nothing. In 2019 I really think it’s unacceptable that an ordinary user can accidentally delete some incredibly important data and have no way to easily recover it.

So, what’s the solution to this problem? As I see it, there are two pretty simple ways Apple could improve the user experience in this regard. One is the humble undo button – even shake to undo would be better than nothing. Or they could go the way of iCloud Photo Library, and have a section where deleted conversations live for 30 days before permanent deletion. The other solution would be to have something on iCloud.com, which currently offers the ability to restore deleted files in iCloud Drive, contacts, calendars and reminders, and last but not least, Safari bookmarks!4 The fact that it is easier to restore an accidentally deleted bookmark than it is to restore all of the messages one has ever exchanged with one’s spouse, say, is just absurd.

Apple is generally pretty good at knowing the kind of digital belongings we value most and helping us to protect and make the most of them. iMessage is one where they are failing us. Let us restore them, let us back them up, and maybe let us export them to other formats without having to expose our unencrypted backups to third-party software.

  1. Insert the usual disclaimers about free iCloud storage being meagre and the importance of proper backups. 

  2. I’ve also seen people try to delete one message and hit the “Delete All” button; there is a confirmation dialogue, but it’s all too easy to breeze through without thinking. 

  3. I don’t know whether SMS are included in this. 

  4. Thank God that my bookmarks are safe from the capricious wrath of the delete button. 

Siri Shortcuts and Transport APIs

2019-03-11    ✪Permalink

I haven’t written anything about Shortcuts since it was released last September, so I thought it was about time I share a few of the shortcuts I’ve had fun making recently and which I’m finding myself using almost every day. All of them leverage the advantages that came with the transition from Workflow, in particular the ability to both trigger them from Siri, and for Siri to natively respond with the output of the shortcut using the show results action.

They’ve also given me the opportunity to try two things I’ve been meaning to play around with: the Transport for London API, and the wonderful JSON parsing app Jayson. The TfL API is an amazingly comprehensive web API that gives information about public transport services all over London. I wanted to use it to build shortcuts related to common journeys I take.1

Line Status Report

The first one I built to allow Siri to tell me the status of the tube line I live on. So that I could experiment with the various URL endpoints offered by the TfL API, I built a small utility shortcut which takes a URL and uses the Jayson “View JSON in Notification” action so that I can quickly see the results by dragging down on the notification that appears. Jayson is one of the apps that has really embraced the rich notifications that were introduced in iOS 12.

JSON Shortcut, JSON in rich notification, JSON in Jayson

Running this shortcut with the URL

https://api.tfl.gov.uk/Line/Mode/tube

returns eleven JSON objects, each corresponding to one of the tube lines in London. For example, here is the raw JSON returned for the Bakerloo Line:

{
  "$type":"Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities",
  "created":"2019-03-05T14:58:26.59Z",
  "crowding":{
    "$type":"Tfl.Api.Presentation.Entities.Crowding, Tfl.Api.Presentation.Entities"
  },
  "disruptions":[

  ],
  "id":"bakerloo",
  "lineStatuses":[

  ],
  "modeName":"tube",
  "modified":"2019-03-05T14:58:26.59Z",
  "name":"Bakerloo",
  "routeSections":[

  ],
  "serviceTypes":[
    {
      "$type":"Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities",
      "name":"Regular",
      "uri":"\/Line\/Route?ids=Bakerloo&serviceTypes=Regular"
    }
  ]
}

Since I want to check the status of a particular line, the part I need here is the id key. Now I can query the URL

https://api.tfl.gov.uk/Line/bakerloo/Status

which returns the following JSON data:

[
  {
    "$type" : "Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities",
    "created" : "2019-03-05T14:58:26.59Z",
    "crowding" : {
      "$type" : "Tfl.Api.Presentation.Entities.Crowding, Tfl.Api.Presentation.Entities"
    },
    "disruptions" : [

    ],
    "id" : "bakerloo",
    "lineStatuses" : [
      {
        "$type" : "Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities",
        "created" : "0001-01-01T00:00:00",
        "id" : 0,
        "statusSeverity" : 10,
        "statusSeverityDescription" : "Good Service",
        "validityPeriods" : [

        ]
      }
    ],
    "modeName" : "tube",
    "modified" : "2019-03-05T14:58:26.59Z",
    "name" : "Bakerloo",
    "routeSections" : [

    ],
    "serviceTypes" : [
      {
        "$type" : "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities",
        "name" : "Regular",
        "uri" : "\/Line\/Route?ids=Bakerloo&serviceTypes=Regular"
      }
    ]
  }
]

To get the human-readable status, I need to take the value from the lineStatuses key, then the first item of that array, then the value from the statusSeverityDescription key. In the shortcut I built to do this, I then have a few conditional statements to change the wording of the Siri’s response in the most common cases, so that it sounds nice and makes grammatical sense. So for example, if the API returns Good Service I have Siri respond with “There is currently a good service on the [line name]”, but if there are delays, she instead says “There are currently [type of delays] on the [line name]”. In other cases, I fall back to a default, “The current status of the [line name] is: [status]”. At some point, I should probably add some other conditionals for occasional statuses like Part Suspended.2

Line Status Report in Siri

Here’s the finished shortcut. The import question will ask you which line you want to use, and you just need to drag the one you want to the top of the list. Then you can add it to Siri with whatever phrase you like.

Arrivals Information

This isn’t the case on most of the London Underground network, but on the route I take to and from work, the trains are actually relatively infrequent. I have a ten minute walk from my work to the nearest station, and so ideally I want to time things so that I arrive a minute or two before my train arrives. I wanted to build a shortcut that would allow Siri to tell me how long it is until my train arrives. To do this, I used the URL endpoint

https://api.tfl.gov.uk/StopPoint/{id}/Arrivals

with the id of the station near my work. I first had to find out what this id was, so I used the endpoint

https://api.tfl.gov.uk/Line/{line id}/StopPoints

to list all of the stations, along with their ids, on a given line. This is a case where Jayson really comes into its own. When you open some JSON data in the app, you can use the key button in the top right to display the value for a given key for each element of an array. So using the previous URL with the id for the Bakerloo line, and opening the data in Jayson, I can use the key button to display the values for the key commonName. This makes it much easier to find the station I want, and then drill down to identify its id.

Jayson key tool

Armed with this information, I can now build the query to get the arrivals information I need. But since not all the trains arriving at the station go in my direction, I need to filter the results I get. Each item in the array returned from the arrivals endpoint represents an approaching train, and each has a key called destinationNaptanId whose value is the station id of the terminus. I wanted to filter the results using this key to reduce the list to only those going in my direction.

In the Shortcuts app, working with lists can be a little awkward at times, and things like sorting and filtering are not natively supported. However, there’s a relatively elegant way to implement a filter operation using the Repeat with Each block. Within the repeat block, you add an if block, and within the if block you put a Get Variable action with Repeat Item as the variable name. In the Otherwise section of the if block, you put the Nothing action. This means that the if block passes through the input when it passes the condition and passes nothing when it doesn’t. It’s perhaps not intuitive that it works this way, but the output of a repeat block is actually a list of all the outputs produced at the end of each repetition – in this case, only the inputs which matched the condition.

Once I’ve filtered the results, I count how many there are. If zero, Siri responds with a default “No trains currently due”. If there are more than one, I take the first and find that value of of the key timeToStation which is given in seconds, divide by 60, and round it down to the nearest minute. This is then the value that Siri replies with using the Show Results action.3

Time to Next Train shortcut

Here’s a link to the finished shortcut.

Building these shortcuts was a lot of fun, and was made much easier by the wonderful Jayson app, without which it would have involved a lot of my poring over screeds and screeds of un-indented raw JSON data. I use these actions every day to get to and from work, and being able to ask Siri “When is the next train home?” and have her quickly reply is so much better than launching an app to enter the same journey information every time.

  1. In the API documentation, it says, “To use the Unified API, developers should register for an Application ID and Key. Append the app_id and app_key query parameters to your requests.” In practice I’ve found this isn’t necessary for the very low volume of requests I’ve been making. 

  2. One of the reasons I haven’t is that the Shortcuts app still doesn’t offer an else if option in conditional blocks, necessitating awkward nested blocks as a workaround. 

  3. In my version of this shortcut, I put in the line status shortcut at the end with a Run Shortcut action, so that Siri also tells me about any disruptions after telling me about when my train is. 

Unprofessional Development ↪︎

2018-08-24    ✪Permalink

I’m very excited to announce that my former colleague Luke Pearce and I have just released the pilot episode of our podcast called Unprofessional Development. The tag line is sometimes teaching, always learning, and that’s exactly what we’ll be discussing. We’re both maths teachers who want to continue to develop our knowledge and skills in teaching, but we both also have a passion for learning things outside of our jobs.

With the end of the summer holidays looming, this episode is entitled Back to School, and in that we discuss how best to teach the first lessons of the year. We hope that you enjoy it. You can find us in Apple Podcasts, Overcast, and lots of other places.

We also have a new twitter account @unprofdev, where you can send us feedback on the show and hear about future episodes.