Prompt forever

A lot of my work on the iPad isn’t really on the iPad. It’s command line work that’s executed on a Mac or a Linux server while I use my iPad as a terminal via SSH. A feature recently added to Prompt has made that much easier.

The problem I’ve always had with using Prompt is that it would disconnect from the server if it was the background app for more than a few minutes. This was a “feature” of iOS that the folks at Panic couldn’t seem to get around. Because it’s common for me to jump between three or four apps while working, I couldn’t always keep Prompt as one of the active apps in Split View, and I’d often have to reconnect.

I tried making the reconnection as painless as possible by using tmux. This worked, but working in a tmux session didn’t allow me to scroll back freely to see the results of old commands. Using the mobile shell, Mosh, and the Blink app had the same scrolling problem. (I should make it clear that when using tmux or mosh I could use keyboard commands to scroll back a page at a time, but I didn’t want to work as if I were sitting at a text-only terminal in 1982. I like working at the command line, but I want to do so in a modern setting.)

In recent months, the terminal feature built in to Textastic has been my workhorse. Because I tend to keep Textastic active in one of the Split View panes as I take notes, edit a program, or write a report, its connection to the server seldom gets culled by the operating system. Unfortunately, its terminal emulation isn’t as full-featured as Prompt’s—it’s fine for simple tasks, but not great for a Jupyter console session.

Recently, though, I learned that a new feature of Prompt may give me everything I want. It’s called Connection Keeper, and when I first heard of it I had two misconceptions:

  1. I thought it was a temporary workaround to the terrible background process culling that iOS 13.2.1 was doing and wouldn’t be helpful once Apple fixed that in 13.2.2.
  2. I thought it was essentially built into Prompt, not a setting that has to be turned on.

I was set straight earlier this week by Athanasios Alexadrides and Anders Borum.

Here’s what Panic says in the latest release notes:

Prompt’s new Connection Keeper feature lets you audit exactly when and where you’ve connected to your servers. It also helps keep your connections alive while Prompt is in the background.

You can turn this feature on in “Settings > Connection Keeper”

While I’m sure there are plenty of people who want to track where and when they connected to the server, it’s the part tucked after the “also” that excites me. Since turning Connection Keeper on several days ago, every SSH session in Prompt has had an essentially permanent connection, no matter how long I’ve had Prompt in the background.

When Prompt is connected to a server and in the background, this flag appears in the statusbar:

Prompt background flag

It’s similar to the background flags that appear when you’re talking on the phone or getting directions in Maps. As with those flags, tap it and you’re taken back to Prompt.

As Panic says in the release notes, you turn Connection Keeper on in Prompt’s settings, but you might have trouble finding it. Like many gear/hamburger “menus” in iPadOS, Prompt’s Settings popup is limited in height. On my 12.9″ iPad, only the items on the left are shown when I tap the gear icon.

Prompt settings menu items

At first, I didn’t notice the line under the Keyboard item that indicates there are more items available. Scrolling up revealed all the other items shown on the right.

Turning Connection Keeper on is pretty much what you’d expect: flip the slider button to the right.

Connection Keeper

As with the release notes, the instructions here focus more on connection history than connection maintenance. I suspect Panic doesn’t want to oversell connection maintenance because it’s not entirely under their control; they know Apple could kill it with another point release.

But until that happens, I’m enjoying SSH connections that last as long as I want them to. One more step in the direction of making the iPad into a full-featured computer.

A little chart adjustment

One of the best things about today’s introduction of the 16″ MacBook Pro was that it inspired Marco Arment to write a new blog post—a rare treat. I am perhaps unusual in that I think Marco is a better writer than he is a talker. I like his talking; I just like his writing more.

Of course he commented on the new keyboard, and his comments were accompanied by this cute graph comparing the new keyboard with the old one and some others:

Marco's chart

It’s nicely done. Displaying the key spacing and travel as a stacked pair of charts was a good idea. Putting them together in a single chart with the spacing and travel columns next to one another would have been the easy choice, but it wouldn’t be nearly as clear. And the decision to show the key travel columns growing down—the direction of travel—was inspired. It does what good charts do: give you an instant understanding of the point being made while also providing a clear way to explore the data further.

But I have opinions about chart style, and I think a handful of small improvements could be made. Most of these could not be made within the charting software Marco was using (Numbers, I think); the charts would have to be imported into a drawing package and manipulated there. But the small extra effort would be worth it.

I don’t have the data Marco was working from, and I wanted some practice editing images in Pixelmator on my iPad, so I edited his PNG image instead of creating a new chart from scratch. Here’s his chart with my edits:

Edited version of Marco's chart

First, I made it seem more like a single chart by getting rid of the superfluous second set of categories and moving the lower chart up to make it more obvious that it and the upper chart are sharing the categories. The legends were Marco’s only bad idea, so I got rid of them. A chart with only one data set doesn’t need a legend, it needs a title. I confess my placement of the titles could be better.

I also changed two of the grid lines in the lower chart, thickening the one at 0 and thinning the one at 5 to make it clear which was the base from which the red columns were growing. And I deleted the minus signs in front of the ordinate labels. I’m sure Marco used negative values to trick the charting software into making his columns grow downward, but we think of key travel as a positive number, and that’s how it should be labeled.

One change I couldn’t make in Pixelmator, but is the change I first thought of when looking at Marco’s original, is to adjust the ticks and grid lines to whole millimeters. This is a pet peeve of mine: charting algorithms often make unnatural decisions about default tick spacing, setting the marks at places that no human would. In this case, the algorithm no doubt felt that four divisions was best, leaving us with a silly grid spacing of 1.25 mm. It is true that adding an extra grid line would make the chart a little more busy, but the advantage of having simple numbers as the labels outweighs the additional clutter. This is especially true given that one of the main points of the new keyboard is that it’s travel is 1.0 mm.

My apologies to Marco for this. His chart really is good. I just can’t help myself.

Accidents and estimates

I came very close to being in a car accident on Friday, which got me thinking about kinematics and estimation in engineering calculations.

I was stopped in a line of cars at a traffic light when something—probably the squeal of brakes, although I may have heard that after later—made me look up into my rear view mirror. A car going way too fast was coming up behind me. I leaned back in my seat, put my hands on my head, and closed my eyes, waiting for the impact.

Which never came.

After a couple of seconds, I opened my eyes and looked in the mirror. There was a car back there, slanted out toward the shoulder, but it was much further away than I expected. Then I noticed a car on the shoulder to my right and ahead of me. That was the car I had expected to hit me. The driver had managed to swerve to the right and avoid me.

That led to some conflicting feelings. I was pleased he was skillful enough to steer out of the accident but angry at his stupidity in needing to exercise that skill. Then the engineer in me took over. If he came to a stop ahead of me, how fast would he have hit me if he hadn’t veered to the right?

It’s a pretty simple calculation, the kind you learn in high school physics. There are two equations of kinematics we need:

[d = v_0 t - \frac{1}{2} \alpha g t^2]


[v_0 = \alpha g t]

These are covering the period of time from when his front bumper passed my rear bumper to when he came to rest. The distance traveled is [d], his speed at the beginning of this period is [v_0], the duration is [t], and the deceleration (assumed constant) is [\alpha g]. It’s common in situations like this to express the acceleration or deceleration as a fraction of the acceleration due to gravity; [\alpha] is a pure number.

We don’t really care about [t], so with a little algebra we can turn these into a single formula with only the variables of interest:

[v_0 = \sqrt{2 \alpha g d}]

Based on where the car ended up, I’d say [d] is about 25 feet. The deceleration factor, [\alpha] is a bit more dicey to estimate, but it’s likely to be somewhere around 0.6 to 0.8. And since we’re using feet for distance, we’ll use 32.2 [\mathrm{ft/s^2}] for [g]. That gives us a range of values from 31 to 36 [\mathrm{ft/s}] for [v_0]. Converting to more conventional units for car speeds, that puts him between 21 and 24 mph. That would have been a pretty good smack. Not only would my trunk have been smashed in, I likely would have had damage to my front bumper from being pushed into the car ahead of me.

This was a simple calculation, but it illustrates an interesting feature of estimation. Despite starting with a fairly wide range in our estimate of [\alpha] (0.8 is 33% higher than 0.6), we ended up with a much narrower range in the estimate of [v_0] (24 is only about 15% higher than 21). For this we have the square root to thank. It cuts the relative error in half.

Why? Let’s say we have this simple relationship:

[a = \sqrt{b}]

We can express our uncertainty in the value of [b] by saying our estimate of it is [b (1 + \epsilon)], where [\epsilon] is the relative error in the estimate. We can then say

[\sqrt{b(1 + \epsilon)} = \sqrt{b}\sqrt{1 + \epsilon}]

and using the Taylor series expansion of the second term about [\epsilon = 0], we get

[\sqrt{b} \left( 1 + \frac{1}{2}\epsilon + \mathrm{h.o.t} \right)]

If the absolute value of [\epsilon] is small, the higher order terms (h.o.t) won’t amount to much, and the relative error of [a] will be about half that of [b].

Lots of engineering estimates aren’t as forgiving as this one, so it’s important to know when your inputs have to be known precisely and when you can be a little loose with them.

Speaking of forgiving, I searched for rear end crash test results for my car to see how much damage it would have taken. I came up empty, but here’s a more recent model undergoing an impact at twice the speed.

I don't want nobody nobody sent

I have been known to complain bitterly about Apple’s decline in software quality. Sometimes the complaints have been typed into Twitter; more often they been spit out between clenched teeth as yet another damned thing doesn’t do what it should. But iOS 13 has added one new feature that is both incredibly valuable and works.

It’s Silence Unknown Callers, an option you can find in the Phone section of the Settings app.

Silence unknown callers

In my experience, it does exactly what it says and has already saved me lots of time and frustration. It’s not that I often answered spam calls; I had already trained myself to almost never pick up a call that my phone didn’t associate with a contact. But I still had to stop what I was doing and look at my phone or my watch whenever one came in. Now that’s a thing of the past.

I’ve seen many people say they can’t use Silence Unknown Callers because they often need to take cold calls. I pity those people. I did wonder myself whether it was OK to silence business calls from prospective new clients who aren’t yet in my contacts list, but a little thought led me to the conclusion that those callers always leave messages and aren’t offended by having to do so.

Oddly enough, my first and only bad experience with Silence Unknown Callers was the exact opposite of missing an important call. A day or two after I had turned it on, a spam call rang on my phone. My initial reaction was that Apple had screwed up (yet again), but no. The call rang because the number was in my Contacts. Over several years I had collected spam numbers into a special contact—called AAASpammer to put it at the top of the list—that was blocked. I had apparently mistakenly unblocked him,1 and now because he was in my list of contacts, and the caller was reusing a number associated with that contact, the call rang through. I deleted AAASpammer from Contacts and have not been bothered by a spam call since.

If you have any sense of the history of Chicago machine politics, you will recognize the source of the post’s title. Spam callers are nobodies that nobody sent.

  1. In my experience, when adding a new number to a blocked contact, you had to unblock the caller and then reblock him to get the newly added number to “take” (whether this was a bug or an idiotic design choice by Apple, I never knew). I must have missed a step in this dance the last time I added a number and left the contact unblocked.