Your system has run out of application memory HUR HUR HUR

I hate this dialog with the fire of a thousand suns.

When this appears, it basically means one (or both) of two things:

  1. Some application went nuts and chewed through all your memory and/or disk space.
  2. macOS got itself into a darkly comical & embarrassing deadlock.

Quitting any of the listed applications is rarely the correct move.  It’s often enough the case that none of them are the root cause, and you can kill all of them if you want, but it won’t fix the problem.

One important thing to clarify first, though, is that this dialog does not necessarily use the term ‘memory’ in the conventional sense – i.e. RAM.  It can also refer to disk space.  Unfortunately it doesn’t bother to distinguish between the two, which is particularly stupid of it since any possible resolution of the issue is highly dependent on which of the two cases it in fact is.

Thank goodness for iStatMenus, though, which in the most recent incident showed that I had ~20 GiB of RAM completely free (not even inactive, actually outright free).  So immediately that rules out what the daft bloody dialog’s actually saying.

The worst thing about all this is when it’s #2 the occurs.  For example, I had Lightroom do a 63-image panorama merge.  As Lightroom is a gross memory pig when doing panorama merging, it consumed something like 40 GiB of memory.  Which caused a bunch of stuff to page to disk.  Which consumed all the disk space.  Which led to that obnoxious dialog.  Which further led to macOS in its infinite fucking wisdom ‘pausing’ (SIGSTOPing) almost all running programs, including evidently whatever daemon actually handles paging.  Thus when Lightroom actually completed the panorama merge and released all that memory, I now had 20 GiB of free memory and the system refused to use any of it to page back in all that memory it’d paged out.  Because it was out of disk space.

The only solution – short of hard rebooting and hoping it resolves itself – was to delete a bunch of files I actually do still want, but which will now have to be recovered from a backup.  Great job macOS, thanks for all your help.

Of course, even once you do that and recover the system from the derpeche mode it put itself into, it won’t actually unpause any of the shit it broke.  You have to do that manually.  It pretends you can do that via that dialog that started the whole thing – assuming you left it open the entire time, blocking your view as you actually help the situation – but that only shows user-visible applications, not all the other system & background processes that it also rudely halted.

So, simple tip for resuming everything:

sudo killall -CONT -m '.'

Elegant, after a fashion.  Though every time, it reminds me that whomever named it ‘killall’ was either not very friendly or not very wise.

Note that the system will probably still be a bit broken in places, as despite what macOS thinks, you can’t just blindly pause random system tasks and not have things get really, really confused.  A reboot is always wise after seeing this dialog, to properly undo its fuckery.

iOS Family Sharing users cannot mix authentication schemes

Apple supports two styles of two-factor authentication, that they call (and distinguish as) “two-step” vs “two-factor”.  “Two-step” is their older method, though functionally they’re basically equivalent.

If you have multiple accounts on a Family Sharing arrangement, and some use “two-factor” while others use “two-step”, you’re in for a bag of hurt.

For example, any time you change the password on any of the non-master accounts, you’ll have to reauthorise all devices on that account with the master purchaser.  You’ll be prompted, when trying to download apps or purchase anything etc, with a dialog saying “Your Family Organizer, [foo], must enter the security code for their payment method”, asking for some kind of input.  There is literally nothing you can enter there that will make it work.  Not the password for any of the relevant Apple IDs, not any security codes for any credit cards, nada.

The problem is that it’s asking for a verification code that you can only create on a device which has “two-factor” authentication enabled.  Compare for example what you see with “two-factor” authentication enabled on your iDevice:

Screenshot of two-factor authentication enabled in iOS account settings

Versus what you see with “two-step”:

Screenshot of two-step authentication enabled in iOS account settings

That “Get Verification Code” “button” is what you’re looking for.  As you can see, it simply doesn’t exist with “two-step” authentication enabled.

The only solution – to allow your family members to download apps, purchase music / videos / books / etc, or pretty much do anything else on their iDevices – is to force the master account over to “two-factor” authentication.

To do this, you have to go to https://appleid.apple.com/ and turn off “two-step” authentication (which will require you to complete some stupid ‘security’ questions).  You cannot turn off “two-step” authentication from any of your actual iDevices’ Settings apps.

Then, stupidly, you can’t actually enable “two-factor” authentication from that same website.  That can only be done in the Settings app on one of your iDevices – by (in iOS 10.3 or later) going into Settings ➜ <your name at the top of the list> ➜ Password & Security.

There’s no way to enable “two-step” authentication anymore.  And not having any form of two-factor authentication enabled is a very bad idea.  So if any of your family’s accounts have “two-factor” authentication enabled, you basically have to switch to “two-factor” on all of them.

Which would be broadly fine, if Apple hadn’t made it so needlessly complicated, and the two systems so incompatible that their own software can’t figure out what’s going on.

Stupid Swift error message #a bajillion and one

Input code:

let componentsOfPotentialInterest = [Calendar.Component: ((Int) -> String)](
 .day: { String($0 + 1) },
)

Push button.  Expect results (or at least bacon).  Get:

Foo.swift:76:21: error: expected ',' separator
 .day: { String($0 + 1) },
     ^
     ,
Foo.swift:76:21: error: expected expression in list of expressions
 .day: { String($0 + 1) },
     ^
Foo.swift:76:21: error: expected ',' separator
 .day: { String($0 + 1) },
     ^
     ,

Believe it or not, Swift, blindly repeating your obtuse error messages does not help.

What it’s trying but as usual failing miserably to tell me is that Dictionary doesn’t have an initialiser that takes key: value pairs (my mistake for writing straight-forward, Python-like code).  You have to use the dictionary literal syntax instead:

let componentsOfPotentialInterest: [Calendar.Component: ((Int) -> String)] = [
 .day: { String($0 + 1) },
]

Now it merely complains about the expression being too complex for it’s pathetic little brain, rather than having no fucking clue what you’re doing to begin with.  Pick your utterly useless poison, I suppose.