Recent Posts

Pure Markdown + HTML Footnotes

There’s a lot of boilerplate here, but I figure I should share how I’ve been writing footnotes for this blog, in the the hopes that it’ll someday help someone, somewhere in this vast and infinite universe:

<a class="anchor" id="1-text"></a>Some concise content.[<sup>1</sup>](#1)

[...]

<a class="anchor" id="1"></a><sup>1</sup> Let's expand on it at the end of the post. [⏎](#1-text)

That should work in any blogging system that supports Markdown, but Jekyll also exposes the URL slug of the current post to help avoid conflicts on collection pages that may contain footnotes from multiple posts. This can be used like so:

<a class="anchor" id="markdown-footnotes-1-text"></a>Some concise content.[<sup>1</sup>](#markdown-footnotes-1)

[...]

<a class="anchor" id="markdown-footnotes-1"></a><sup>1</sup> Let's expand on it at the end of the post. [⏎](#markdown-footnotes-1-text)

A cheaper, better base model

Let’s take a look at these two MacBook Pro options:

The first is the 16-inch base model, which gets you a 6-core i7 processor with 16 GB of RAM, 512 GB of disk space, and dedicated graphics.

It has to contend with an upgraded 13-inch model (the 4-port one), which has a 4-core i7 processor with 16 GB of RAM, 512 GB of disk space, and integrated graphics.

It may come as a surprise to you that the 16-inch option is actually $100 cheaper than the 13-inch.

I’m tempted to give full credit to the concept of the base model and prove that upgrades simply provide less value, but perhaps this difference is exaggerated by that fact that Apple doubled the storage1 of the bigger base model with the introduction of the 16-inch, and the now-half-a-year-old 13-inch has yet to benefit from a similar price drop.

I don’t know about you, but I’m going to keep crossing my fingers and hoping for a 14-inch MacBook Pro (with scissor keys, of course).


1 Here’s a link to the archived store page depicting the 256 GB 15-inch base model.

Troubleshooting Apple Books, or ‘Log Out Solves Everything’

Whether you have iCloud enabled in “Settings > Books” on iOS, or you’re so last year and use iTunes like me, you’ve probably come across an EPUB file you’ve wanted to read before. This afternoon I had some trouble with accomplishing exactly that: syncing the Mac Books with the iOS version. Here are some steps to take if this happens to you or someone you know (pass it on!):

  • On your phone: Consider enabling iCloud in “Settings > Books”, because when it’s disabled and iTunes Sync isn’t in use, there’s no way for your phone to accept new books from your computer.
  • On your Mac: Make sure Books and iTunes (if applicable) are authorized. You can do this in “Store > Authorize This Computer…” and “Account > Authorizations > Authorize This Computer…”, respectively.
    • As a side note, I ran into an endlessly looping Apple ID sign-in dialog when using Books, and canceling the prompt left the underlying problem, which was that sync wasn’t possible (not even through iTunes, which either contained a blank “iPhone > Settings > Books” window, or a list with no books). I was able to fix it by going to “Store > Sign Out” and then following the prompts to sign in again.

Error Code #3, or ‘The Adventure of Deleting a HealthKit Object’

“An invalid argument was provided to the HealthKit API.”

This dreaded error has a code of #3. It signifies my lack of knowledge about how HealthKit works, as well as how it should work.

Unfortunately, duplicate samples can be added to Health. If the framework relied on indexOf to delete an object with matching properties, only the first occurrence would be deleted. Therefore, Apple doesn’t want to prescribe a deletion method, relying instead on shared identifiers between the exact same instances.

Because of this, instantiating a new HKObject (HKCategorySample in my case) with any properties and passing it to the delete method will throw an error like the one above.

While I was debugging this issue, I thought it was ridiculous that an error message blaming the source code would be used to communicate that a HealthKit object couldn’t be found (“Failed to find some objects for deletion”). However, it turns out that the code looked fine on the surface, while actually assuming the existence of a flaw in HealthKit’s design, by expecting it to figure out which exact object to delete.

My (now obvious) solution was to iterate over the results of an HKSampleQuery and delete the first object that shares properties with the custom object set for deletion by the user. If you just can’t ignore duplicates at runtime and want to avoid unexpected behavior (which, of course, was the whole point of HealthKit not using indexOf), you can keep track of which Nth occurrence to delete with a similar loop.

Sourced from Allan’s Stack Overflow post.

This Blog Turns 2!

I’ve started and quit quite a few different blogs, but none of them were about technology until 2017.

I published this site’s first placeholder post on this day two years ago. Many drafts, hosting platforms, and writing workflows later, I have thirty text files in my “posts” directory.

Fast forward to last month and I’ve added a micro post format to improve the freshness of the home page while encouraging me to write more frequently.

Thanks for reading, and see you in 2020!