# iOS screenshots of overlays

When presenting choices to a user, iOS has overlays with rounded corners. An example is the overlay that appears when you want to delete an image from the Photos app.

Officially, these have a few names, depending on their exact look and how they’re used. For modal interaction, there are alerts and modal views; for non-modal (and some modal) interaction, there are popovers. Regardless of the name and the underlying code, they have a similar look, and I often like to include screenshots of them in my posts. I’ve recently come up with a way to do this without leaving a cluttered background in the image.

Immediately after taking a screenshot, it’s easy to crop the image down to nearly the right size, but virtually impossible to crop it down to exactly the right size, because you can’t zoom in with the iOS-supplied cropping tools.

And even if you could crop precisely to the edges, the rectangular corners would still have wisps of background peeking out from beyond the rounded corners.

My solution is a two-step process:

1. Use Pixelmator to crop precisely to the edges. This is a “by hand” operation that I just haven’t figured out how to automate.
2. Use Shortcuts to mask out the rounded corners and, optionally, add a solid gray background. To me, white, or near-white overlays look better against the white background of the blog if they’re set against a darker background.

I typically do an approximate crop right after taking the screenshot, leaving me with something like this:

I then open the image in Pixelmator and crop it down to hit the edges precisely.

There is a technique to this. If you zoom in to a corner and then choose the crop tool, Pixelmator will zoom back out before allowing you to crop. This doesn’t hurt anything, but it means you wasted your time by zooming first.

So choose the crop tool and then zoom in to one of the corners. You will almost certainly need to pan during this process, which you must do with two fingers, as Pixelmator interprets all one-finger swipes while in crop mode as directions to move the crop handles. Once you get zoomed in to a corner, use one finger to align the crop with the sides of the rounded corner. This is relatively easy to do because the lines jump one pixel at a time at high zoom.

After cropping the first corner, you’re best bet is to tap the Apply button and then go back into crop mode to do the opposite corner. Every time I’ve tried to crop both corners in a single trip to crop mode, I’ve screwed up the crop while moving from one corner to the other. Inevitably, Pixelmator interprets one of my zoom or pan motions as a one-finger swipe and changes the crop.

Now we have our overlay cropped down to a precisely aligned rectangle, which I save back into the Photos app.

It’s time to run the Round Corners shortcut. This is a Share Sheet shortcut that acts on images. It asks the user first for the corner radius to use in the masking.

I set the default radius to 40 pixels because I’ve found that to work reasonably well for most overlays. The rounded corner mask that Shortcuts applies isn’t an exact match for the rounded corners used in overlays. I think that’s because Shortcuts uses a quarter circle for the rounding (hence the need for a radius) and iOS uses a squircle.

The shortcut then asks if a background should be applied. The answer you give determines whether you end up with this

or this

Here are the steps of the Round Corners shortcut:

I think the comments do a decent job of explaining what’s going on, but there are two tricks worth noting. First, I’m using Federico Viticci’s technique of embedding a base64-encoded version of the background image into the shortcut itself. It’s there in the Text step a little more than halfway down. Second, to save space, that background image is just a 1×1 pixel image. It gets resized to slightly larger than the target image (20 pixels larger in all four directions) before the overlay is done.

An obvious improvement would be to get rid of the hand cropping. The OpenCV library, which has bindings for Python, might be a way to grab just the needed portion of the image and would probably handle the masking, too. It works in iOS, but I think you have to be a real developer, not just a scripter, to use it there. I could probably get it running on my Mac or blog server if I dedicate the time to it.

# Drafts, Shortcuts, and blogging

For the past several months, almost all of my blog posts have been written on my iPad. My system for publishing the posts, though, was still Mac-based. It consisted of a set of scripts and Makefiles that would compile the Markdown source of the post into HTML and regenerate whatever new pages were needed to update the site. It did all this locally, on the Mac, and then ran rsync to upload the new and altered pages to the blog server. A good system for all those years I was writing posts on the Mac, but less good if I’m going to be writing mostly on the iPad.

To publish a post written on the iPad, I had to get the Markdown source file over to the Mac (Dropbox made this easy) and then I had two choices:

1. Leave my iPad, go to the Mac and run the publishing scripts. I almost never did this.

The second option, in which the Mac was basically an intermediary between the iPad and the server, seemed like a waste. So a couple of days ago I moved all the publishing scripts and Makefiles to the server, cutting out the middle man.

My publishing system is a melange of Python and PHP—Python because that’s what I prefer scripting in; PHP because this used to be a WordPress site and I have some custom PHP from those days that I don’t want to rewrite. A few Makefiles control the scripts to ensure that only the pages that need to be regenerated are. A system like this runs as easily on Linux as it does on the Mac, so I just had to add a library or two and change a few paths here and there to get everything working on the server. Then it was time to do some scripting on the iPad.

First, I needed to be able to upload a draft from Drafts to the server. I already had a two-step action for uploading a draft to Dropbox, so I was more than halfway there.

The source code for a post starts with a header that looks something like this:

Title: Drafts, Shortcuts, and blogging
Keywords: drafts shortcuts blogging
Summary: A change to how I blog means new Drafts actions that use Shortcuts.
Image: https://leancrew.com/all-this/images2018/20181215-Publish%20shortcut%20options.png
Date: 2018-12-15 12:10:23
Slug: drafts-shortcuts-and-blogging


The name for the Markdown source file and the folder into which it’s saved are determined by the year, the month, and the slug. The first step in my uploading action is this script:

javascript:
1:  // Set template tags for the path and filename
2:  // of a blog post.
3:
4:  var d = draft.content;
5:
6:  // Set up regexes for header info.
7:  var dateRE = /^Date: (\d\d\d\d)-(\d\d)-\d\d \d\d:\d\d:\d\d$/m; 8: var slugRE = /^Slug: (.+)$/m;
9:
10:  // Get the year and month and set the path.
11:  var date = d.match(dateRE);
12:  var year = date[1];
13:  var month = date[2];
14:  var path = '/path/to/blog/source/' + year + '/' + month + '/';
15:
16:  // Get the filename from the slug.
17:  slug = d.match(slugRE)[1];
18:
19:  // Set tags for use in other action steps.
20:  draft.setTemplateTag('source_path', path + slug + ".md");


This is almost identical to the earlier script, so I won’t describe it in full. The main differences are in Line 14, which defined the path on the server to the folder where the Markdown source files are kept, and Line 20, which defines the source_path template tag that will be used in the second step of the action.

Drafts1 has action steps for easily uploading to Dropbox, Google Drive, One Drive, Box, and WebDAV, but not for uploading via SFTP. I could install Dropbox for Linux on the server or maybe get WebDAV working on it, but I didn’t really want to install new stuff on the server just to be able to upload files. I could also switch to using Coda or some other editor on the iPad that handles SFTP, but I wanted to stick with Drafts. Because I already know how to upload files via SFTP in Shortcuts, I decided to use the Run Shortcut action step:

This step call the Upload Blog Source shortcut (which we’ll get to in a minute) and passes to it the source_path template tag that was defined above, a line of 10 carets, and then the full contents of the current draft. As you can probably guess, the line of carets is there to provide a distinct separator that the Upload Blog Source shortcut can parse.

Speaking of the Upload Blog Source shortcut, here it is:

The second step of the shortcut splits the input text, using ten carets as the separator. This creates a list. The next two steps take the first item of that list, which is the source_path followed by a newline, and strips the trailing whitespace. This output is available to later parts of the shortcut through a magic variable. By default, this magic variable would be named Replace Text, but because there is another Replace Text step in the shortcut, I renamed it sourcePath to avoid confusion. Unfortunately, this renaming is hidden when you take a screenshot of a shortcut, which could be its own source of confusion.

The next three steps return to the list of split items created in Step 2, pull out the last item from it, and strip the leading whitespace. This leaves us with the text of the draft.

Finally, the last step connects to the server and runs the cat command to redirect the standard input passed to the step (the Markdown source) to a file defined by sourcePath.

This is harder to explain than it is to do, but it would be easier if Drafts had a native action step for SFTP. I think I’ll put that bug in Greg Pierce’s ear.

OK, now I have an action that saves a draft to the server. I can use Prompt to log onto the server and run the make command that generates the necessary HTML and publishes the new pages. But wouldn’t it be nicer to just have an action that does that directly from Drafts. Of course it would. This is a single-step action that uses Run Shortcut:

Boy, that’s dull. Here’s the shortcut it runs:

My Makefile has several sections. By default, when make is run without an argument, it runs the sections needed to publish a new post. When given the up argument, it runs the sections needed to update an already-published post. Thats why there are two options to the Publish shortcut.

Many of you are thinking I could have written a shortcut just like this to log in and run make on my Mac, which would have saved me the trouble of moving all my publishing scripts to the server. You’re right, I could have. But I never did because the incentive wasn’t strong enough. It was only after I put the publishing system on the server—something I’ve been meaning to do for longer than I’ve had an iPad—and needed to solve other problems that I felt compelled to write the publishing shortcut. Motivation is funny.

The obvious drawback to setting things up this way is that I’ve now made it harder to blog from my Mac. But BBEdit knows SFTP, so it won’t be hard to teach it how to upload a file to right place. And there are any number of ways on a Mac to run a command on a remote server. I’ll fill those holes soon.

1. Which is, by the way, Time Magazine’s #3 app of 2018

# An unfortunate hole in my portable brain

This morning I got an email from one of my business partners. She’s out of town on a job and needed our FedEx number sent to another lab so they can ship some samples to us. No problem, I thought, I’m sure I have it on my phone. But no, that was one of those things I always meant to save on my phone but never got around to. My partner thought she had it on her phone, too.

Here are the things I have gotten around to saving to my phone:1

• Social security numbers for myself (which is kind of silly—I never need to look it up) and my family. This includes my mother and father, both of whom are now dead.
• Driver’s license numbers for myself and my family. Also photos of the front and back of my license.
• Make, model, year, license, and registration numbers for our cars. Also images of the registration documents.
• Bank account, routing, and other numbers and codes for personal and business accounts.
• My TSA Precheck code.
• The number, expiration date, and a photo of my passport.

Some of these may seem silly, but I’ve made use of almost all of them at one time or another. A couple of years ago, when my mom moved to a nursing home and I needed to close out certain services at her house, I learned that the phone service was still in my dad’s name. She’d never changed it when he died ten years earlier. So I used his SSN (along with my grandmother’s maiden name, which wasn’t saved to my phone but didn’t need to be) to impersonate him with the phone company and get the account closed. That was a little weird.

(I have since learned that friends my age commonly pretend to be their aging parents to deal with customer service reps. I am, however, the only one I know who pretended to be a dead parent.)

As I look through the list, I see that I still haven’t added things I’ve always meant to. In particular, apart from the FedEx number, I should be keeping the account numbers for various insurance policies.

Up until recently, I’ve had (or intended to have) all of this stuff in secure notes in 1Password. As part of my shift to a more iCloud-based system, I’ve copied them over to locked notes in the Notes app. There have been advantages and disadvantages to the change.

• Secure notes in iOS 1Password won’t accept images. When I wanted to add a photo to a secure note, I had to be at my Mac to do so. Given that all the photos I wanted to add—typically cards or documents scanned with Readdle’s Scanner Pro—came from my phone, this was annoying bit of back-and-forth. On the positive side, once the image was in the secure note, I could see it on my phone or iPad.
• Unlocking Notes on iOS can can have its own back-and-forth annoyance. Sometimes the app is perfectly happy to unlock after looking at my face or scanning my fingerprint. But sometimes, it wants me to enter the iCloud Keychain password I’ve associated with Notes. Which means I have to unlock the Keychain and select the password to fill into the text field. Often, the just-unlocked note still won’t show itself to me until I go back to the list of notes and select it again. I’m sure there’s some logic behind this, but I have no idea what it is.

1. And iPad and Macs, but it’s mostly when I’m out with just my phone that I need them.