The Desolation of Blog

The personal blog of Jeff Johnson.
https://lapcatsoftware.com/articles/atom.xml (RSS)
visit blog
Technology is never a substitute for consent
4 Jan 2025 | original ↗

This is a follow-up to my recent blog posts Apple Photos phones home on iOS 18 and macOS 15 and The internet is full of experts. I've read a lot of the discussion about and responses to my blog posts, which has forced me to hone my own thinking and arguments on the subject. I characterized Apple's new Enhanced Visual Search feature as a privacy...

The internet is full of experts
31 Dec 2024 | original ↗

My recent blog post Apple Photos phones home on iOS 18 and macOS 15 has received widespread attention, and perhaps inevitably, it has also received widespread criticism by random internet commenters. A common criticism is that I somehow discredited myself by stating, honestly, "I don't understand most of the technical details of Apple's blog...

Apple Photos phones home on iOS 18 and macOS 15
28 Dec 2024 | original ↗

This morning while perusing the settings of a bunch of apps on my iPhone, I discovered a new setting for Photos that was enabled by default: Enhanced Visual Search. (I manually disabled it before taking the screenshot below.) Apps > Photos"> This setting is also new to Photos on macOS Sequoia, and enabled by default. Oddly, this new feature has...

Deep dive into a macOS default web browser bug
20 Dec 2024 | original ↗

This blog post has undergone some revision and correction since first published. It turns out, contrary to my initial assumption, that the code signatures of the apps is largely irrelevant. Thanks to Avi Drissman of the Google Chrome team for assistance! According to the Apple Developer Documentation, "macOS Launch Services is an API that enables...

How Safari 18.2 https upgrade works
12 Dec 2024 | original ↗

Yesterday, Apple released Safari version 18.2, included with iOS 18.2 and macOS 15.2, as a separate update for macOS 14 and 13. I've already discussed one new feature of Safari 18.2, Copy Link with Highlight, in another blog post. Now I'd like to discuss another new feature, automatic https upgrade. From Apple's announcement: Safari 18.2 on iOS,...

How Safari (insanely) displays app extension icons
29 Nov 2024 | original ↗

I'm not talking about the tint of the extension icons this time. I'm talking about the size of the extension icons in the Safari toolbar on Mac. I've explained the difference between Safari app extensions and Safari web extensions before, so I won't repeat the explanation here, except to note that my own StopTheMadness Pro and StopTheScript are...

Apple continues to dismiss bug reports
25 Nov 2024 | original ↗

As far as I can tell, the Apple developer boycott of Feedback Assistant, which I launched a year ago, appears to have gone nowhere and made little impact, unfortunately. I personally ended my boycott a couple of months ago when I filed a Feedback about visionOS that I didn't want to publicize. I've filed only a few bug reports since then, but...

Apple rejected my Vision Pro app update
1 Nov 2024 | original ↗

StopTheMadness Pro has three variants, one each for iOS, macOS, and visionOS, because I created native apps for each platform rather than simply porting an iPad app to Mac and Vision Pro. The way the App Store works, each native app variant must be reviewed separately by Apple, so every update to StopTheMadness Pro must now pass through an...

Apple silently uploads your passwords and keeps them
31 Oct 2024 | original ↗

This is a follow-up to my blog post macOS Sonoma silently enabled iCloud Keychain despite my precautions from five months ago. The TL;DR of that blog post is that when you have iCloud enabled but not iCloud Keychain, updating from Ventura to Sonoma causes iCloud Keychain to be silently enabled. (I don't know yet whether that still occurs when...

How Safari can improve extensions: Redux
23 Oct 2024 | original ↗

In my first blog post of the year, way back at the beginning of January, I wrote about how Safari can improve extensions, offering a number of suggestions. Last month, Apple released a major update to Safari, version 18 for iOS and macOS, so now it's time to look back at how my suggestions fared. 1. Bring the Manage Extensions widget to Mac from...

Mac App Store receipt validation problem on Sequoia
19 Oct 2024 | original ↗

This problem was highlighted the other day in an update to Michael Tsai's earlier blog post about “Damaged” Mac App Store Apps, but I think it's important enough to warrant a dedicated blog post, because Mac developers who missed the update need to know about it. The problem is that if you compile your app with the macOS 15 SDK in Xcode 16, and...

Safari 18 randomly appearing sidebar
30 Sept 2024 | original ↗

I never use the sidebar in macOS Safari and always keep it closed. However, since I updated to Safari 18 on macOS 14.7, I've been seeing new Safari windows open with the sidebar open. This is driving me crazy! It doesn't happen every time, though. It's seemingly random, which makes the issue extremely difficult to diagnose. It frequently happens...

More annoying macOS 15 Sequoia prompts: Bluetooth
23 Sept 2024 | original ↗

It turns out that the monthly screen recording prompts are not even the most annoying new "feature" of macOS 15 Sequoia. Behold! "If you turn Bluetooth off you will not be able to use your Bluetooth devices." I mean, duh?!? Does this prompt appear monthly? No, that would be far too convenient. So how often? Every. Single. Time. You. Try. To....

Stop macOS 15 Sequoia monthly screen recording prompts
21 Sept 2024 | original ↗

All credit for this discovery should go to Ricci Adams, who told me about it. But Ricci doesn't have a blog, and I do, so here it is. Thank you very much, Ricci, and please start a blog! Much has already been written about the new monthly screen recording prompt in macOS 15 Sequoia. As always, Michael Tsai has an excellent summary. The good news...

Can't change security policy or disable SIP with macOS 15 Sequoia
20 Sept 2024 | original ↗

My M1 Mac mini, which I use for software testing, has five APFS boot volumes, one each for macOS 15 Sequoia, 14 Sonoma, 13 Ventura, 12 Monterey, and 11 Big Sur. Today I learned that I can no longer change the startup security policy or disable System Integrity Protection (SIP) on any of the boot volumes. (I actually didn't bother to test macOS...

Passkey privacy issues
19 Sept 2024 | original ↗

Today I downloaded a copy of my data from https://privacy.apple.com, Apple's Data and Privacy website. (For some reason it took 5 days after my request for the data to be ready for download.) I highly recommend that you download your data too, because you might be shocked how much Apple has on you. Apple's advertisement "What happens on your...

Safari missing feature: auto-clear website data
29 Aug 2024 | original ↗

When I search for the same text in multiple Safari tabs, I experience a lot of trouble with Safari failing to remember the search string in the find panel. As a workaround, sometimes I open a new TextEdit document, start a search for the desired text, and switch back to Safari, which then remembers the search string across multiple tabs. Today I...

macOS firewall slows DNS queries
13 Aug 2024 | original ↗

I learned of this issue from a Reddit post and decided to investigate. When I enable the built-in firewall on macOS Sonoma, I've noticed that my DNS query times increase - we're talking several times slower. The built-in firewall can be enabled and disabled in the Network pane of System Settings. I'm able to reproduce the issue not only on macOS...

How I git push from my laptop to my website
12 Aug 2024 | original ↗

I keep this website under version control in a git repository on my MacBook Pro. The tricky part is getting the website files from my laptop onto my web server. In the past I did this manually via SFTP, which obviously sucked. With help from the excellent customer service of my web host Tiger Technologies, whom I've been with since 2006 and...

New macOS bug: Updates Available notification with no updates
8 Aug 2024 | original ↗

I first saw this bug on the macOS 15 Sequoia betas, which I ignored as a beta issue, but I've started to see the bug on Sonoma too after updating to macOS 14.6, and the bug continues on macOS 14.6.1. I've seen the bug on both my MacBook Pro and my Mac mini. Out of nowhere, an "Updates Available" notification appears, despite the fact that I...

Apple memory holed its broken promise for an OCSP opt-out
7 Aug 2024 | original ↗

When you launch an app, macOS connects to Apple's OCSP service to check whether the app's Developer ID code signing certificate has been revoked by Apple. In November 2020, Apple's OCSP service experienced a mass outage, preventing Mac users worldwide from launching apps. In response and remedy to this outage, Apple made several explicit promises...

Has Apple underpaid App Store developers AGAIN?
3 Aug 2024 | original ↗

Yesterday, App Store developers were paid for app purchases made during the period of June 2 through June 29, 2024. You may recall that Apple underpaid App Store developers for app bundle purchases made in February through May, due to a bug in Apple's accounting software. I wrote about this issue originally on May 10, with a follow-up on June 3....

Smart App Banners don't appear in private browsing
2 Aug 2024 | original ↗

Here's a tip for iOS app developers and mobile web developers: today I learned that Smart App Banners don't appear in private browsing. I haven't seen this documented anywhere! Smart App Banners appear above a web page in Safari when the page includes a special HTML element, for example: You can tap the banner to download the app from the App...

Fix Safari Private Window Empty Page
31 Jul 2024 | original ↗

Dearest gentle reader, this author opens new Safari windows with an empty page, like a proper member of The Ton. A new private window normally appears as below, untitled. Back in April, I posted on Mastodon about a bug introduced in Safari Technology Preview version 192 that caused the start page rather than an empty page to be shown in new...

Deluge of Fake Mac App Store Reviews
20 Jul 2024 | original ↗

Yesterday I discovered a deluge of recent fake customer reviews for a number of top paid apps in the United States Mac App Store. (Each country has its own version of the App Store with separate reviews.) I've now checked the reviews for all of the current top 40 paid apps in the Mac App Store, and 8 of those apps have a large number of fake...

Amazon Web Services dark patterns
25 Jun 2024 | original ↗

In April, a StopTheMadness Pro customer contacted me about an incompatibility with the Amazon Web Services Management Console. I had never used AWS before, but I noticed that it has a free tier, so I decided to sign up in order to debug the incompatibility. The first AWS dark pattern is that the free tier still requires payment information, e.g.,...

Safari bookmarklet permissions
22 Jun 2024 | original ↗

A bookmarklet is a bookmark stored in a web browser that contains JavaScript commands. Here's a simple, useless example: javascript:alert('Hello,%20World!'); To run bookmarklets in Safari on macOS, you need to enable "Show features for web developers" in Safari Advanced Settings and "Allow JavaScript from Smart Search field" in Safari Developer...

Advanced tracking and fingerprinting protection breaks Safari extensions
15 Jun 2024 | original ↗

Advanced tracking and fingerprinting protection is in the Safari Advanced Settings on both iOS and macOS. The setting has three options: disabled, enabled in private browsing, or enabled in all browsing. Last year I wrote about why I disabled advanced tracking and fingerprinting protection in Safari. This year I found another reason: it breaks my...

Stop iCloud Keychain with a profile
5 Jun 2024 | original ↗

This is a follow-up to my blog post macOS Sonoma silently enabled iCloud Keychain despite my precautions. A follower on Mastodon gave me a nice tip on how to prevent this in the future: create a configuration profile. First, download the Apple Configurator app from the Mac App Store. Then open Apple Configurator, select New Profile from the File...

WWDC Boycott of Feedback Assistant
4 Jun 2024 | original ↗

I really want to report bugs to Apple. In fact I do frequently report bugs to Apple via the WebKit Bugzilla. I want to report bugs to Apple so badly that sometimes I write entire blog posts here about Apple bugs. But Apple's Feedback Assistant is a frustrating nightmare, for a number of reasons, and I'm refusing to use it. Back in November I...

macOS Sonoma Mail bug: spam bypasses Block All Remote Content
4 Jun 2024 | original ↗

Mail app on macOS has a privacy setting Block All Remote Content that prevents downloaded emails from connecting to the internet. For example, HTML emails frequently include image links, which can be used for tracking: when the image is loaded from a remote server, the owner of the server knows that you've opened the email! Block All Remote...

Follow-up on developer payments for App Store bundle purchases
3 Jun 2024 | original ↗

This is a follow-up to my blog post Apple started cheating me out of App Store bundle purchases. The good news is that Apple appears to have resolved most of the issues. Let me give a timeline: May 9: By closely analyzing my App Store Connect financial reports, I discovered that Apple appeared to be underpaying me for StopTheMadness Pro upgrade...

Apple silicon MacBook Pro batteries can't be replaced under warranty by third parties
30 May 2024 | original ↗

I bought a new M1 MacBook Pro in April 2022. A little over two years later, I'm seeing a service recommended message, and the maximum capacity of the battery is now down to 78%. Admittedly, my MacBook Pro experiences heavy usage: basically all day, every day. The batteries in my previous 2014 Intel MacBook Pro, which experienced the exact same...

Verify Your Recovery Key?
29 May 2024 | original ↗

Four days ago, I updated my MacBook Pro from macOS Ventura to Sonoma. Since then I've encountered several bugs. This morning, for no apparent reason, Sonoma System Settings decided to show me the warning, "Verify Your Recovery Key". The warning includes some very scary text: To avoid losing access to your account, verify your recovery key. The...

macOS Sonoma bug: Can't create disk image containing locked file
27 May 2024 | original ↗

Two days ago I updated my main development Mac from Ventura to Sonoma. Besides the bugs already mentioned yesterday, I've found another new bug. This bug did not exist in Ventura and earlier. You can reproduce the bug via the GUI or Terminal. Create a new folder in Finder Create a new file, for example a text file, and save it in the new folder...

macOS Sonoma silently enabled iCloud Keychain despite my precautions
26 May 2024 | original ↗

This is a follow-up to my blog post Updating from macOS Ventura to Sonoma silently enables iCloud Keychain. In the addendum to that blog post, I discussed a workaround, which was to delete my WiFi password right before rebooting into the updater. In a trial run on my M1 Mac mini, the workaround was successful. Thankfully, iCloud Keychain remained...

Updating from macOS Ventura to Sonoma silently enables iCloud Keychain
26 May 2024 | original ↗

This is not a new issue. It was discovered last year, and it also affects updating from iOS 16 to iOS 17. As far as I'm aware, I'm the first to have noted the issue publicly: The latest iPadOS beta seems to have silently enabled iCloud Keychain. (Although I don’t actually have any passwords on the iPad.) Jul 25, 2023 Later, after iOS 17 and macOS...

Apple started cheating me out of App Store bundle purchases
16 May 2024 | original ↗

TL;DR I've discovered that starting in February, Apple mistakenly subtracts the price of the previously purchased app twice from the proceeds of a "Complete My Bundle" purchase, thereby causing me to take a loss on each such bundle purchase. This accounting change has cost me thousands of dollars over the past few months. Update: May 15 2024 This...

YouTube video quality bug in iOS Safari
9 May 2024 | original ↗

How do I report a YouTube bug? I don't know, so I'm going to blog it. Steps to reproduce: In Safari on iPhone or iPad, open the Apple “Let Loose” video: https://m.youtube.com/watch?v=f1J38FlDKxo Pause the video Open Playback Settings Select Quality 2160p Press OK The spinner spins indefinitely, and the video doesn't play again. Below is a video...

Show passwords as they're typed in Terminal
17 Apr 2024 | original ↗

After I posted my funny story of how I recovered the password of an encrypted Mac disk image, I received an email from a reader of the blog, who schooled me on some UNIX. Believe it or not, I don't know everything; know-it-all is just a character that I play on the web. I'd like to express my thanks and appreciation for this blog post to...

Funny story of how I recovered the password of an encrypted Mac disk image
9 Apr 2024 | original ↗

This is a story about so-called "secure" password entry that doesn't allow you to see the password you're typing. Back in 2009 I filed a report with Apple—a "Radar" as it was called at the time, now called a "Feedback"— requesting a standard way to show typing in secure text fields. My report, my Feedback (FB5392624), is still open 15 years...

Stop The Mac App Store improved for Sonoma and Ventura
3 Apr 2024 | original ↗

The App Store app on macOS is the default handler of URLs with the macappstore: scheme. App Store preview web pages automatically open the App Store app by setting the location of an HTML element to a macappstore: URL. My free open source app Stop The Mac App Store registers itself as the default macOS handler for the macappstore: scheme,...

Safari Search Settings spacing
2 Apr 2024 | original ↗

Here's a screenshot of the Search pane in the Preferences window of Safari 16 on macOS Big Sur. (This was before Preferences became Settings in macOS.) Note that the preference "Include search engine suggestions" is clearly associated with the "Search engine" preference. Safari 17 (on macOS Monterey and later) added separate settings for search...

Mac app launches slowed by malware scan
14 Feb 2024 | original ↗

I've always attributed slow Xcode launches to Xcode simply sucking, but I've noticed that the FileMerge app frequently launches slowly too. When this happens, the app can take a dozen bounces in the Dock before finally opening. FileMerge resides in the folder Xcode.app/Contents/Applications/ within the Xcode bundle and can be opened from the...

How to stop Upgrade to macOS Sonoma notifications
8 Feb 2024 | original ↗

Are you still on macOS Ventura or Monterey and prefer not to install Sonoma yet? Sadly, the brain trust at Apple have decided that your preferences don't matter. (These are the same people who decided to rename Preferences to Settings and wreck the app.) Instead, you get harassed by frequent notifications imploring you to "Upgrade to macOS...

The HTML dialog element API is a mess
1 Feb 2024 | original ↗

The HTML element was introduced ten years ago by Google Chrome. However, dialog didn't become a web standard until 2022, when Firefox and Safari added support for the element. A dialog is a box shown in front of all other web page content, similar to an alert, but a dialog is much more configurable than an alert and can be shown either modally...

Abandonware featured in iOS App Store
25 Jan 2024 | original ↗

The Safari Extensions section of the iOS Settings app has a More Extensions link that takes you to the Safari Extensions section of the App Store. In the App Store Safari Extensions section, there's a list of Essential Safari Extensions, selected by App Store editors. Note that the list of 23 extensions does not include and never has included my...

Beware of App Store app bundles
19 Jan 2024 | original ↗

This is a follow-up to my post StopTheMadness Pro postmortem: crApp Store still crappy. As I explained in that post, I recently released StopTheMadness Pro, a major update to my Safari extension StopTheMadness, and since the App Store doesn't support paid upgrades, my workaround was to create app bundles in the iOS App Store and Mac App Store...

How Safari can improve extensions
9 Jan 2024 | original ↗

As a longtime Safari extension developer, I have a number of suggestions about how Safari could improve its extension support. I've already filed some of these suggestions with Apple's Feedback Assistant, but since I'm now boycotting Feedback Assistant, I thought I'd post the list on my blog. Another benefit of blogging the suggestions is of...

StopTheMadness Pro postmortem: crApp Store still crappy
27 Dec 2023 | original ↗

In case you missed the announcement, StopTheMadness Pro is available now! StopTheMadness Pro is a major update and paid upgrade to my Safari extension StopTheMadness. Last year I blogged about App Store pricing inflexibility. Nothing much has changed since then. Sadly, those issues persist. I decided to bite the bullet for StopTheMadness Pro,...

iOS 17 App Store screenshots caveat
22 Dec 2023 | original ↗

The App Store has strict screenshot requirements. Your app screenshots must conform to specific device screen sizes. For iPhone, those sizes are a 5.5-inch display and either a 6.5-inch or 6.7-inch display. I don't know why the screenshot requirements are so strict, because most App Store developers completely ignore the specific screen sizes...

iOS 17.2 shows the wrong Safari extension icons
12 Dec 2023 | original ↗

Apple released iOS 17.2 today, and I've noticed that it has started to show the wrong Safari extension icons in some places for some extensions. The same happens on iPadOS 17.2. By design, each Safari extension has two icons: (1) an app icon, in full color; (2) a Safari toolbar icon, black and transparent template. Below are the app icons in...

macOS Sonoma increases NSControl font size
8 Dec 2023 | original ↗

If you compile an AppKit app with the macOS 14 SDK in Xcode 15, the default font size of several NSControl subclasses increases from 12 to 13 when the app runs on macOS 14 Sonoma. I discovered this the hard way yesterday when I noticed that my box—an NSBox, that is—was no longer big enough for my controls. I haven't done an exhaustive review of...

Disabled Safari extensions are not fully disabled, and other problems
30 Nov 2023 | original ↗

What happens when you update a Safari extension in the App Store while Safari is open? If it's a Safari app extension, such as my own StopTheMadness, you see this: In contrast, a Safari web extension, such as my own Homecoming for Mastodon, can be updated while Safari is open. I have a theory about why, which I'll discuss later in this blog post....

NSFileManager error messages lie
29 Nov 2023 | original ↗

I wasted at least an hour debugging what I incorrectly assumed was a Mac app sandboxing issue, because I believed what the NSFileManager error told me. Below is the source code of a command-line tool to demonstrate the issue. #import #define SourcePath @"/Library/Receipts/InstallHistory.plist" #define DestinationPath...

The myth and reality of Mac OS X Snow Leopard
13 Nov 2023 | original ↗

The myth of Snow Leopard was started by Senior Vice President of Software Engineering Bertrand Serlet at WWDC 2009. This famous keynote slide was, to put it euphemistically, a bit of product marketing. Non-euphemistically, it was a big lie. Snow Leopard had quite a few new features, including significant changes "under the hood", so to speak. In...

Mac App Store receipt validation revisited
8 Nov 2023 | original ↗

Michael Tsai's encyclopedic blog has discussed issues with Mac App Store receipt validation in 2019 and again in 2022. In summary, Apple's old sample code for developers was broken, some developers tried to fix it, and Apple later posted new sample code (at the same URL). However, I've recently run into a case that seems to call into question all...

Feedback Assistant boycott web page and participants list
7 Nov 2023 | original ↗

Following up on yesterday's announcement of an Apple developer boycott of Feedback Assistant, I've now created an official web page for the boycott, an email address, an RSS feed, and a Mastodon account. Moreover, I'm going to compile a public list of boycott participants, to be posted on the official site. You can definitely participate in the...

Apple developer boycott of Feedback Assistant
6 Nov 2023 | original ↗

I'm organizing a boycott of Apple's Feedback Assistant, starting immediately, and I encourage all Apple developers to join me. Here's how I propose that each of us can effectively participate in the boycott and let Apple know that we're boycotting Feedback Assistant: File a new Feedback about Feedback Assistant (in Developer Tools & Resources)...

This Feedback will no longer be monitored, and incoming messages will not be reviewed
3 Nov 2023 | original ↗

This blog post is a follow-up to How to fix the disastrous new Xcode 15 console, which was itself a follow-up to Xcode 15 logs nil as an empty string, not (null). I mentioned in the previous blog post that I filed three bugs with Apple, one of which was FB13289059 "Xcode 15 console logs truncated". Since then I've had some back and forth with...

Safari share menu now violates privacy
26 Oct 2023 | original ↗

Last year I wrote about why the macOS Ventura share menu is bad, but that was from a user interface perspective. It turns out that the share menu in Ventura—and now Sonoma—is also bad from a privacy perspective. Here's an example, using http://example.org. In the web inspector, I changed the More information link from https to http so that I...

Why I disabled advanced tracking and fingerprinting protection in Safari
23 Oct 2023 | original ↗

Advanced tracking and fingerprinting protection is a new feature of Safari 17 that's enabled by default in private browsing on iOS and macOS. I analyzed the details of this feature after it was introduced back in June at Apple's Worldwide Developers Conference (WWDC). Despite the fact that I'm obviously interested in protection from tracking and...

Safari 17 hidden feature: Always allow this website to open an app
21 Oct 2023 | original ↗

Safari 17 has a new hidden feature that I wasn't even aware of until a customer brought it to my attention. I haven't seen it mentioned anywhere by Apple in their release notes. You may already be aware that for a number of years, Safari has asked your permission every time you click on a link, such as an RSS feed, that opens in an app other than...

How to fix the disastrous new Xcode 15 console
19 Oct 2023 | original ↗

This is a follow-up to my recent blog post Xcode 15 logs nil as an empty string, not (null). I've now found three different bugs in the new Xcode 15 console. FB13268283 Xcode 15 console logs nil as empty string rather than (null) FB13270074 Console logs missing on first run after launching Xcode 15 FB13289059 Xcode 15 console logs truncated In my...

LaunchServices and Spotlight
14 Oct 2023 | original ↗

A few days ago, Howard Oakley wrote an article LaunchServices problems in Sonoma 14.0, I wrote a comment on the article, and today Howard wrote a follow-up article LaunchServices problems and Ventura. This article is a follow-up to Howard's follow-up. You should read Howard's articles before mine, otherwise mine might not make much sense, and I...

Xcode 15 logs nil as an empty string, not (null)
13 Oct 2023 | original ↗

I just discovered a shocking, troubling, and as far as I know, undocumented change in Xcode 15: the functions os_log and NSLog now log nil as an empty string. The previous behavior, going back forever as far as I remember, was to log nil as (null). Here's a sample command-line tool run with Xcode 14: And here's the same tool run with Xcode 15:...

Your Mastodon archive omits DMs sent to you
3 Oct 2023 | original ↗

This is a follow-up to my previous blog post Mastodon instance admin deleted all of our DMs after 15 days. After I published that blog post, I was arguing with someone (ignorant) online who engaged in blaming the victim and insisted that I ought to be backing up my Mastodon data weekly to avoid data loss. During that argument, I realized that...

Mastodon instance admin deleted all of our DMs after 15 days
2 Oct 2023 | original ↗

I've just migrated Mastodon instances for the second time this year. My new Mastodon account is @lapcatsoftware@mastodon.social. Eight months ago, I migrated to appdot.net because Mastodon instance mstdn.plus with over 4K users suddenly broke, and mastodon.social was not accepting new signups at that time. My first migration was triggered by an...

How did Apple get all of my email addresses?
27 Sept 2023 | original ↗

For software testing purposes, I use a Mac mini with four APFS boot volumes, one each for Big Sur, Monterey, Ventura, and Sonoma. These were all "fresh" macOS installs with no upgrades or data migration. For the most part, the Mac mini contains very little of my personal data. I do sign in with my Apple ID, but that's it. I never receive, read,...

Mysterious disappearing Apple ID 2FA codes
18 Sept 2023 | original ↗

After testing the iPadOS 17 beta since WWDC, I decided to start over fresh today and "Erase All Content and Settings" on my iPad. There were a couple of reasons for this. First, since iPad 17 beta 4, the Settings app wanted me to verify my recovery key for some reason, and I couldn't get rid of that warning. (FB12749748 for any Apple engineers in...

The most wonderful new hidden feature in iOS 17 and macOS 14
13 Sept 2023 | original ↗

Today Apple published lists of new features available with iOS 17 (to be released September 18) and macOS 14 (to be released September 26). One of those features caught my eye. Indeed it made my eyes bulge. Automatically pause animated images. Pause animated images by default, such as GIFs in Messages and Safari for your visual comfort. This is...

Another Google Search bug in iOS Safari
11 Sept 2023 | original ↗

Last month I asked, How do I report a Google Search bug? In retrospect, it appears that blogging was an effective method of reporting a Google Search bug, because that bug appears to be fixed now! So I'm going to try again this month with a new bug. Once again, this Google Search bug affects Safari on iOS. Let me illustrate the bug with...

Safari Un-Intelligent Tracking Prevention: Data loss by design
30 Aug 2023 | original ↗

I want to use Safari, but sometimes it frustrates the hell out of me, and in some ways it's vastly inferior to Chrome and Firefox. One of my biggest pet peeves is Safari "Intelligent Tracking Prevention" (ITP). This feature is enabled by default and called "Prevent cross-site tracking" in Safari Privacy Settings. Of course I want to prevent...

Threads.net can go to hell
24 Aug 2023 | original ↗

I do most of my computing, including social media, on my MacBook Pro rather than on my iPhone or iPad. I have no interest in mobile-only social networks, and that's why I've been avoiding Threads by Meta (née Facebook). This week, however, Threads introduced a web client, so I decided to sign up today and take a look. Unfortunately, Threads is...

macOS App Management vulnerability illustrated
20 Aug 2023 | original ↗

Yesterday I disclosed an unfixed security vulnerability in macOS Ventura's App Management protection. The explanation was fairly technical, and you had to use Apple's Xcode developer tool in order to test the vulnerability yourself with my sample app. Today I want to illustrate the vulnerability a little more clearly to a non-developer audience....

macOS 0day: App Management
19 Aug 2023 | original ↗

App Management is a new macOS security feature in Ventura introduced at WWDC last year: If an app is modified by something that isn't signed by the same development team and isn't allowed by an NSUpdateSecurityPolicy, macOS will block the modification and notify the user that an app wants to manage other apps. Clicking on the notification sends...

How do I report a Google Search bug?
14 Aug 2023 | original ↗

I found a Google Search bug in Safari on iOS. Or rather, a StopTheMadness customer found the bug and reported it to me. I investigated and determined, to my relief, that the bug wasn't mine, because I could (eventually) reproduce it with StopTheMadness disabled. The question is, how do I report this bug to Google? They have a public issue...

Follow-up to Firefox 115 can silently remotely disable my extension on any site
11 Jul 2023 | original ↗

Last week I wrote Firefox 115 can silently remotely disable my extension on any site. This blog post is a follow-up with more information. First, Mozilla has published a support article about the new quarantined domains feature. Here's an excerpt: Firefox version 115 introduced Quarantined Domains to protect our users' privacy and security when...

Reflections on my 7th Twitter anniversary
9 Jul 2023 | original ↗

Content warning: This blog post is navel-gazing. It's fine if you're not interested in that, but then please just stop reading now and close the browser tab instead of becoming annoyed that I'm wasting your time. Thank you! For several reasons, one of which is the introduction of Threads (an Instagram app), I've been thinking a lot lately about...

Firefox 115 can silently remotely disable my extension on any site
7 Jul 2023 | original ↗

Firefox version 115.0 was released on July 4, but I'm not celebrating. I'm concerned about a new "feature" in the release notes. Certain Firefox users may come across a message in the extensions panel indicating that their add-ons are not allowed on the site currently open. We have introduced a new back-end feature to only allow some extensions...

My thoughts on Apple Vision Pro
14 Jun 2023 | original ↗

1. Naming There are only two hard things in Computer Science: cache invalidation and naming things. I joked during the WWDC keynote that "Vision Pro" sounds like a health insurance plan. Conspiracy theory: a common criticism of Tim Cook is that he has no vision; now he does, literally. Incidentally, I did think that macOS Sonoma was a fine name....

Little Snitch "denied" connections leak your IP address: Developer response
12 Jun 2023 | original ↗

About a month ago I wrote a blog post and a follow-up about how Little Snitch—and all network content filter extensions, as it turns out—leak your IP Address. Last week the developer of Little Snitch responded to my blog posts, though they didn't directly mention me: There has been some discussion recently about the bypassing of Little Snitch by...

Safari 17 Link Tracking Protection Details
10 Jun 2023 | original ↗

A blog post by Cory Underwood inspired me to poke around in the macOS Sonoma beta to discover more details about the new Link Tracking Protection in Safari 17. From Apple's press release: Link Tracking Protection in Messages, Mail, and Safari Private BrowsingSome websites add extra information to their URLs in order to track users across other...

macOS Sonoma sandbox security
7 Jun 2023 | original ↗

From Apple's new Security updates document: App Sandbox now associates your macOS app with its sandbox container using its code signature. The operating system asks the person using your app to grant permission if it tries to access a sandbox container associated with a different app. For more information, see Accessing files from the macOS App...

macOS: Attribute Not Found?
19 May 2023 | original ↗

I have a bit of a mystery, and I'm hoping that my readers can help me with it. When I was manually backing up my M1 MacBook Pro today, I experienced something bizarre that I can't explain. Last year I wrote about my backup strategy for my new MacBook Pro. What I do is boot into recovery, mount the Data volume, and then run the following commands...

Passkeys: A loss of user control?
8 May 2023 | original ↗

This blog post doesn't have the answers. I'm trying to learn about passkeys, but I don't claim to be an expert. I do have a lot of questions, especially for Apple, because I'm an Apple user and developer. According to Betteridge's law of headlines, "Any headline that ends in a question mark can be answered by the word no." Nonetheless, I want to...

Follow-up to Little Snitch "denied" connections leak your IP address
31 Mar 2023 | original ↗

A few days ago I wrote Little Snitch "denied" connections leak your IP address in which I explained that connections denied by Little Snitch are still leaking your IP address, a major privacy issue. The addendum of the blog post notes that I had briefly tested LuLu and saw some of the same behavior. After I published my blog post, I sent a link...

Little Snitch "denied" connections leak your IP address
31 Mar 2023 | original ↗

Little Snitch is a macOS app and network filter extension made by Objective Development Software. I purchased Little Snitch years ago, continue to use it, and will continue to use it. I've also done a lot to promote Little Snitch on my blog and even in the news media. However, this blog post raises a privacy issue with Little Snitch that bothers...

What Apple doesn't get about Feedback
27 Mar 2023 | original ↗

I've had a hate-hate relationship with Apple's Feedback Assistant for well over a decade, since before its name was changed to Feedback Assistant from Radar. (I think it's still known internally as Radar.) At various times over the years I've even boycotted Radar/Feedback Assistant out of frustration, refusing to file any bug reports with Apple....

Mac Messages: Can't I show my email address?
8 Mar 2023 | original ↗

Years ago I stopped using iMessage because it was losing messages. Some messages were simply not delivered, with no error or explanation. I found this unacceptable, and it never happened to me with SMS. I understand that SMS is not end-to-end encrypted, but what's the point of encryption if the message never makes it from end to end? So I've been...

Race to the bottom: App Store peer benchmarks
1 Mar 2023 | original ↗

Today Apple announced the availability of peer group benchmarks for developers in App Store analytics. App Analytics in App Store Connect is a helpful tool with a breadth of features to help you understand and improve how your app is performing on the App Store. With metrics related to acquisition, usage, and monetization strategy, App Analytics...

I do want to go back to social media
28 Feb 2023 | original ↗

Back in November I wrote a blog post titled I don't want to go back to social media. In retrospect, I realize that I do want to go back to social media, in fact did go back to social media (to Mastodon, that is, not to Twitter, which I definitely don't regret leaving). So this blog post is a kind of mea culpa. I wasn't wrong about everything I...

Ventura or Vista? Cancel or Allow in Mac Preview app
27 Feb 2023 | original ↗

Apple used to parody permission prompts in Windows Vista. Many years later, the last laugh is on Mac users. This permission prompt is new in macOS 13 Ventura. To see it, just Print this web page, Open in Preview, and click any link. Preview app shipped with Mac OS X 10.0. In fact, Preview was carried over to Mac from NeXTSTEP. I don't know why,...

App Store Review continues to delay updates for no reason
14 Feb 2023 | original ↗

Happy Valentine's Day to everyone except Apple's App Store Review! My story does have happy ending: my Safari extension StopTheScript is now updated in the iOS App Store. If you're not familiar, StopTheScript is unique in that it stops all JavaScript on your selected web pages, including inline JavaScript, a capability not possessed by Safari...

Mastodon postmortem
7 Feb 2023 | original ↗

My previous blog post described how Mastodon instance mstdn.plus with over 4K users suddenly broke. After 6 days of breakage, and 6 days of no word from the instance administrator, an automated email arrived yesterday from mstdn.plus stating that my archive was ready for download. I had started an archive of my mstdn.plus data the same day the...

Mastodon instance mstdn.plus with over 4K users suddenly broke
7 Feb 2023 | original ↗

Does it matter which Mastodon instance you choose? I've seen many people claim that it doesn't matter, and moreover that you can easily switch instances. I learned the hard way that this claim is unwarranted, a disservice to new Mastodon users. Your choice of instance is important, indeed crucial. Until yesterday I was on mstdn.plus, a Mastodon...

NSURLSession connection leak
23 Jan 2023 | original ↗

Apple's documentation for the class NSURLSession (or URLSession for Swift coders) contains a warning marked "Important": The session object keeps a strong reference to the delegate until your app exits or explicitly invalidates the session. If you don’t invalidate the session, your app leaks memory until the app terminates. This warning doesn't...

Bing and DuckDuckGo removed my business web site AGAIN
16 Jan 2023 | original ↗

Last year I wrote Bing and DuckDuckGo removed my business web site describing how https://underpassapp.com had been removed from Microsoft Bing search results, and thereby also from DuckDuckGo search results, since DDG relies on Bing. As described by my friend Jesse Squires in the blog post My website disappeared from Bing and DuckDuckGo, Part 2,...

Universal Links Revisited
16 Jan 2023 | original ↗

A couple years ago I wrote about the monstrous Open in the Twitter app banner in Safari, which is caused by the Twitter app's adoption of Apple's Universal Links. My very clever (IMO) solution to this problem was to create a Mac app, very cleverly (IMO) named StopTheTwitter, that technically impersonated the official Twitter app by copying its...

The App Store does not protect consumers
4 Jan 2023 | original ↗

This morning I came across a post on Reddit about App Store refunds. I'll quote it in full: Hello! Recently I forgot to cancel two free trials for a couple apps that I’d purchased. I figured it wouldn’t be an issue getting them refunded, and went to reportaproblem.com to request a refund. Both refund requests were denied, so I requested they be...

App Store Connect is the worst web site ever made, Part 4: Works as currently designed
28 Dec 2022 | original ↗

Last month in Part 2 of my unfortunately ongoing series "App Store Connect is the worst web site ever made", I wrote that Touch ID login no longer works right on App Store Connect and that I filed Feedback (FB11775777) with Apple about the issue. Yesterday I was looking through Feedback Assistant for other issues, and I noticed that my App Store...

I posted my Safari extension issues on GitHub. Post yours too!
27 Dec 2022 | original ↗

Apple's bug reporting system Feedback Assistant is a black hole. I once filed a bug report against the bug reporter itself, requesting a public, searchable bug database, and here's what happened: Much has changed. Yet nothing changed. Time is a flat circle. For the sake of Safari extension developers everywhere, I've decided to post my Safari...

How to restore the Preferences menu item to macOS Ventura, Part 2
17 Dec 2022 | original ↗

This is a follow-up to my blog post from several months ago, How to restore the Preferences menu item to macOS Ventura. In that blog post, I explained how you could use the default NSMenuShouldUpdateSettingsTitle to control whether apps have the menu item title "Preferences…" or "Settings…" on Ventura. To restore pre-Ventura behavior for all...

macOS removes and reinstalls Rosetta after every update
14 Dec 2022 | original ↗

I'd like to thank Mark Rowe (AKA bdash) for critical help in making this discovery. After every macOS update, I see this dialog when I launch Xcode. I thought this happened to everyone — that is, everyone with Rosetta and Xcode installed — but I was wrong. So why me? Do Apple engineers have a personal vendetta against me? Well, yes, but that's...

macOS Monterey still vulnerable to CVE-2022-40303
13 Dec 2022 | original ↗

On November 9, Apple released macOS Ventura 13.0.1, as well as iOS 16.1.1 and iPadOS 16.1.1. The release notes list two security vulnerabilities fixed. libxml2 Available for: macOS Ventura Impact: A remote user may be able to cause unexpected app termination or arbitrary code execution Description: An integer overflow was addressed through...

Mac OS X analogue for Node.js?
13 Dec 2022 | original ↗

One thing I loved about Mac OS X was that Apple took responsibility for curating, installing, and updating Unix libraries and tools. I say Mac OS X rather than macOS because sadly, in recent years Apple has removed many parts of the Unix foundation from the Mac and also shirked its responsibility to update the remaining Unix components (see for...

Hide System Preferences Dock badge
28 Nov 2022 | original ↗

Badges? We ain't got no badges. We don't need no badges. I don't have to show you any stinkin' badges! If you're like me (lord help you) and still running macOS Monterey, avoiding Ventura and System Settings like the pandemic, you may have noticed that macOS shows you an "advertisement" for the Ventura update, in the form of a persistent Dock...

I don't want to go back to social media
20 Nov 2022 | original ↗

I left Twitter several weeks ago. If you want to know why, you can read the addendum of this blog post, but I don't want that to distract from my main point here, so I'll put it off until the end. For various reasons, many Twitter users are currently looking for an alternative to Twitter: Mastodon, Micro.blog, Tumblr, Cohost, etc. A number of...

App Store Connect is the worst web site ever made, Part 3
12 Nov 2022 | original ↗

I complained about App Store Connect a few days ago, and I'm already back to complain about it again. While preparing an app update for submission, I discovered that What's New in This Version no longer accepts the On the other hand, it does still accept the > character. is not allowed."> This is a problem for me because the release notes of my...

App Store Connect just got worse. But I made it better.
10 Nov 2022 | original ↗

App Store Connect is the web site that members of the Apple Developer Program use to manage their App Store apps. I check it daily to see yesterday's sales numbers (live App Store sales numbers are haphazard at best and have stopped working entirely the past week) and to check for new App Store user reviews of my apps. Inexplicably, Apple...

I'm starting a company blog and Slack
3 Nov 2022 | original ↗

I started this as a personal programming and technical blog, and I'd like to keep it that way. I write many articles that are of interest only to programmers, such as the recent How to regenerate Xcode managed provisioning profiles. However, since I've become an indie developer, I also want to write about my software. Some of the articles I've...

Blogging without a blogging engine
2 Nov 2022 | original ↗

Many years ago I had a self-hosted WordPress blog, but that became a pain because I had to keep installing WordPress security updates to patch vulnerabilities. Also, I had to customize the WordPress code somewhat to suit my preferences. For a few years I stopped blogging entirely, and when I eventually restarted I decided that I wanted a very low...

A list of Apple-related RSS feeds
1 Nov 2022 | original ↗

If you want to reduce your reliance on Twitter, consider RSS. In a way, RSS feeds are what Twitter ought to be: a reverse chronological list containing only content that you chose to follow. (Indeed, Twitter had RSS feeds until 2012.) Below is a list of some RSS feeds that might be useful to Apple developers and others with a strong interest in...

How to regenerate Xcode managed provisioning profiles
27 Oct 2022 | original ↗

This is a follow-up to my article Check your App IDs for unused capabilities. The other day I was about to upload a new build of StopTheMadness to App Store Connect, but at the last minute I noticed that the build still had the Game Center entitlement, even though I had already removed the entitlement from my AppID. Where was it coming from?...

How macOS Ventura App Management works and doesn't work
24 Oct 2022 | original ↗

Apple's Worldwide Developer Conference (WWDC) session What's new in privacy introduced a new security feature in macOS Ventura called App Management. Here's an excerpt from the session transcript. Gatekeeper checks the integrity of newly-downloaded apps. In macOS Ventura, Gatekeeper will now check the integrity of all notarized apps, not just...

Mac indie dev alliance
21 Oct 2022 | original ↗

Small indie developers have always relied on word of mouth recommendations, because we don't have big budgets for paid advertising. Ironically, in the App Store era we may have become even more dependent on word of mouth recommendations, because App Store top charts favor cheap crap and massive hype over sustainable artisanship, while...

Works as currently designed
8 Oct 2022 | original ↗

On September 1, I filed a bug with Apple's Feedback Assistant (FB11426949) about Safari extensions titled "Web Extension storage callbacks in the wrong order". Usually Apple will email you when your feedback status changes, but in this case they didn't notify me. Instead, while I was manually browsing my bug reports I discovered that the status...

Check your App IDs for unused capabilities
28 Sept 2022 | original ↗

My most recent Mac App Store submission of StopTheMadness was rejected by Apple App Review for the reason "Your app contains the Game Center entitlement, but it does not link against the GameKit framework." This was puzzling, because my app does not contain the Game Center entitlement! % codesign --display --entitlements -...

Every unsandboxed app has Full Disk Access if Terminal does
22 Sept 2022 | original ↗

When System Integrity Protection (SIP) is enabled, as it is by default, macOS restricts apps from accessing certain files and folders such as ~/Desktop, ~/Documents, and ~/Downloads. If I run a simple ls command in Terminal, % ls ~/Downloads I get a Windows Vista style permission dialog. And if I click "Don't Allow", then Terminal is not allowed...

iOS 16 text view breakage
13 Sept 2022 | original ↗

In the past, I've written about my adventures with UITextView. At present, I'm writing about a new problem I have with UITextView in iOS 16: it crashes while editing, which is one of the worst problems possible! Ironically, the crash is caused by a workaround for another, less serious problem: NSLayoutManager defaultAttachmentScaling doesn't...

How to restore the Preferences menu item to macOS Ventura
5 Sept 2022 | original ↗

On the macOS 13 Ventura beta, the venerable "Preferences…" menu item has been replaced by the iOS-like "Settings…" menu item in Apple's built-in apps. The menu item also gets automatically replaced in third-party apps if they're compiled with the macOS 13 SDK in the Xcode 14 beta. Fortunately, I've discovered a way to undo this change and stop...

Web pages can overwrite your system clipboard without your knowledge
28 Aug 2022 | original ↗

This blog post isn't just about Google Chrome, it's also about Safari and Firefox. Chrome is currently the worst offender, because the user gesture requirement for writing to the clipboard was accidentally broken in version 104. A public demonstration of the brokenness has been posted on Web Platform News. If you simply visit the demonstration...

Safari updates reset your Experimental Features preferences
24 Aug 2022 | original ↗

A couple of months ago I blogged about how you can stop Safari from switching your Twitter timeline by selecting "Disable Removal of Non-Cookie Data After 7 Days of No User Interaction (ITP)" in the "Experimental Features" submenu of Safari's "Develop" menu. If you don't select this experimental feature, then Safari's "Intelligent" Tracking...

Extensions API broken in Mac Safari
23 Aug 2022 | original ↗

I'm frustrated because an important feature of the cross-platform WebExtensions API for web browser extensions has been broken in Mac Safari — and only in Mac Safari — for two years. It works everywhere else: Firefox, Google Chrome, other Chromium-based web browsers, and even in Mobile Safari! The feature I'm talking about is run_at...

iOS dictation is dickish
22 Aug 2022 | original ↗

I constantly accidentally hit the dictation button when editing URLs in the Safari address bar on my iPhone 7 (soon to be replaced, as iOS 16 drops iPhone 7 support), so I was looking for a way to remove the dictation button. For reasons that will become apparent later, the following screenshots are not from my iPhone 7 but rather from the iOS...

Why macOS Ventura Share menu is bad
9 Aug 2022 | original ↗

The new macOS Ventura System Settings app has been widely criticized. I've personally written two articles criticizing it. The new macOS Ventura Share menu, on the other hand, hasn't yet received much discussion or criticism. This is due partly to System Settings taking a lot of the rhetorical focus — it's so blatantly bad! — and partly to the...

Twitter crypto spam bots copy real tweets to appear real
7 Aug 2022 | original ↗

As a Safari extension developer, I have a Safari extension saved search on Twitter. Over the past couple of months, this saved search has shown the exact same tweet many times, with the exact same typo, from a different Twitter account each time. (I used a more specific search below in order to highlight this tweet.) Where did this tweet come...

Apple re-enables Bluetooth on every OS update on purpose
20 Jul 2022 | original ↗

On April 22, I filed a bug (FB9992639) with Apple's Feedback Assistant titled "Bluetooth re-enabled after every iOS and macOS update". I believe this issue started with iOS 14 and macOS 11, but in any case it definitely happens now with every iOS 15 and macOS 12 update, including today's iOS 15.6 and macOS 12.5 updates, on every device I own. (I...

NSURL is relatively bad
19 Jul 2022 | original ↗

I've written about NSURL once before. I did not have good things to say. I do not have good things to say this time either. Here's the documentation for the resourceSpecifier property of NSURL: This property contains the resource specifier. Any percent-encoded characters are not unescaped. For example, in the URL...

More disappearing Safari extensions
6 Jul 2022 | original ↗

A year ago I blogged about a macOS bug that causes all of your installed Safari web extensions to disappear silently and mysteriously from Safari. The bug seems to have started on Big Sur, and unfortunately it hasn't gotten any better on Monterey. If anything, the bug gotten worse. It's happening to me rather frequently now. And it continues to...

Thoughts on Swift and Objective-C
4 Jul 2022 | original ↗

I want to start by saying that I speak only for myself. I don't speak for other Objective-C programmers, nor do they speak for me. We are not of one mind. The same is true of Swift programmers: some of them seem quite reasonable to me, and others seem rather… fanatical. Regardless, it's almost impossible to have a productive discussion about...

macOS Monterey Dock watches /Users/Shared/
30 Jun 2022 | original ↗

Lately I've noticed that every time I login to my user account on macOS Monterey, the root process fseventsd goes nuts, using almost 100% CPU for 5 to 10 minutes straight. I don't know how long this issue has been happening, because the fans rarely go nuts on my new M1 MacBook Pro. I would've noticed immediately from the fans revving on my 2014...

macOS Monterey unannounced security misfeature
23 Jun 2022 | original ↗

macOS 12 Monterey doesn't support my 2014 MacBook Pro, so I bought a new MacBook Pro in April. For a long time afterward I thought there was a bug in Keychain Access app that causes it to randomly launch in the background, behind the active app. I keep Keychain Access in my Dock and launch it from there, typically to copy a password and paste it...

Link Unshortener enhancements
22 Jun 2022 | original ↗

Link Unshortener is my Mac app that expands shortened web links, following redirects until it reveals the destination URL. Version 9.0 of Link Unshortener is now available in the Mac App Store, and this update is big! Link Unshortener 9.0 adds a convenient list of all your installed web browsers so that you can open a link in any browser with one...

Stop Safari from switching your Twitter timeline
20 Jun 2022 | original ↗

Suppose you don't use Twitter for a week on one of your Apple devices. This can easily happen to me, because I own half a dozen Apple devices. Or suppose you decide to take a long break from "doomscrolling". Or maybe you just go on a vacation for a week. When you return home from your Twitter vacation, you may find that Twitter has also returned...

Bing and DuckDuckGo removed my business web site
16 Jun 2022 | original ↗

Yesterday I was searching with DuckDuckGo and noticed to my dismay that my business web site https://underpassapp.com was missing entirely from the search results! (My personal web site https://lapcatsoftware.com is still in DuckDuckGo, however.) Many people don't realize that DuckDuckGo sources its search results from Microsoft Bing. I learned...

Apple reneged on OCSP privacy
13 Jun 2022 | original ↗

The incident I refer to as the Mac OCSP appocalypse occurred in November 2020. Apple's Developer ID Online Certificate Status Protocol (OCSP) service went down, which caused Mac users worldwide to experience issues with launching their apps. I was among the first to discover the cause of this app launching issue. In response to the Mac OCSP...

Why Ventura System Settings is bad, Part 2
9 Jun 2022 | original ↗

I have some additional thoughts after Part 1. First, I've seen some people vehemently defend the System Settings redesign who haven't yet installed macOS 13 Ventura or used the new System Settings. I find this ridiculous. Why are people like this? It's like they revel in ignorance. Anyway, they're missing the fundamental maxim I quoted in Part 1,...

Why Ventura System Settings is bad
7 Jun 2022 | original ↗

"Most people make the mistake of thinking design is what it looks like. People think it's this veneer, that the designers are handed this box and told, "Make it look good!" That's not what we think design is. It's not just what it looks like and feels like. Design is how it works." - Steve Jobs The venerable System Preferences app has been...

Apple's director of App Review emailed me
4 Jun 2022 | original ↗

Last week I wrote a blog post about how my bug fix update was stuck in App Store review. Somehow my blog post came to the attention of Apple's senior director of App Review, Trystan Kosmynka, who sent me an unsolicited email about it later that day. I didn't actually realize until yesterday, when I saw a tweet from Kosta Eleftheriou, that the...

My bug fix update is stuck in App Store review
27 May 2022 | original ↗

Timeline summary: Tuesday 5:39pm: Tweaks for Twitter Mobile update submitted Tuesday 5:43pm: Tweaks for Twitter Mac update submitted Wednesday 4:29am: Tweaks for Twitter Mac update "In Review" Wednesday 7:56am: Tweaks for Twitter Mac update "Pending Developer Release" Wednesday 12:32pm: Tweaks for Twitter Mobile update "In Review" Thursday...

On App Store pricing inflexibility
12 May 2022 | original ↗

I released my web browser extension StopTheMadness four years ago in the Mac App Store. It was initially priced at $4.99 USD and supported only Safari. Since then I've added a ton of new features, as well as support for Firefox and Chromium browsers. It's almost embarrassing how primitive version 1.0 of StopTheMadness was compared to the current...

Safari solving the wrong problem
4 May 2022 | original ↗

Today I learned that Safari, and only Safari, allows the HTML image element to show a video. A web page just has to set the src attribute of an to an MP4 video URL. The video will auto-play, albeit without sound, even if you've set your Safari Preferences to "Never Auto-Play". Here's an example. It turns out that this feature was introduced in...

The App Store Improvements process makes no sense
2 May 2022 | original ↗

A week ago it was reported that a number of developers were receiving an email from Apple: App Store Improvement Notice This app has not been updated in a significant amount of time and is scheduled to be removed from sale in 30 days. No action is required for the app to remain available to users who have already downloaded the app. You can keep...

Google Chrome 101 removed Fill passwords on account selection
27 Apr 2022 | original ↗

Google Chrome version 101 was released today, and I've discovered to my dismay that it removed the long-standing flag #fill-on-account-select "Fill passwords on account selection". For some strange reason, this very useful flag was never exposed in Chrome's preferences, but you can — or could! — find it by opening chrome://flags in a Chrome tab....

How do I backup my new MacBook Pro?
26 Apr 2022 | original ↗

A few days ago I blogged about my new M1 MacBook Pro. It's mostly been fine, but now I'm experiencing a significant problem: I can't figure out how to make a backup! I back up my home folder daily, and that continues to work as before, but I also back up the entire internal disk weekly, and that doesn't work. With my 2014 Intel MacBook Pro, I can...

Impressions of the new MacBook Pro
19 Apr 2022 | original ↗

I just bought a new MacBook Pro as my main development computer, because macOS Monterey doesn't support my previous main development computer — a 2014 MacBook Pro — and Xcode now requires Monterey. This will become crucial at the beginning of June with the new WWDC Xcode beta. The specs of my new MacBook Pro: 16-inch screen, M1 Pro, 16 GB RAM, 1...

Why is /AppleInternal factory installed on new Macs?
18 Apr 2022 | original ↗

I just bought a new MacBook Pro, because macOS Monterey doesn't support my 2014 MacBook Pro. I'll blog in more detail about the new MacBook Pro later, but I want to mention something very odd that I quickly discovered: there was an empty AppleInternal folder in the root / folder of Macintosh HD. This was visible in Finder. The /AppleInternal...

Mac Pro historical perspective
5 Apr 2022 | original ↗

Thanks to Mactracker for maintaining historical lists of Mac models and prices. The Mac Pro was introduced in 2006 at a base price of $2499. However, the Mac Pro was effectively the Intel successor to the PowerPC Power Mac. The computer case design was introduced in 1999 with the Power Macintosh G3 and remained mostly the same in fundamentals...

App Store Connect is the worst web site ever made
31 Mar 2022 | original ↗

App Store Connect is the web site that members of the Apple Developer Program use to manage their App Store apps. I check it daily to see yesterday's sales numbers (live App Store sales numbers are haphazard at best and have stopped working entirely the past week) and to check for new App Store user reviews of my apps. Inexplicably, Apple...

Do you want me to leave the Apple ecosystem?
26 Mar 2022 | original ↗

"If you want sideloading, then you can just buy an Android phone." This is an ubiquitous response to the request that Apple unlock iPhone and allow installation of software from outside the App Store (which has always been possible on the Mac). It reminds me of the "America, love it or leave it" response to criticism of US government policies....

Misinformation from… Stephen Fry?
22 Feb 2022 | original ↗

Misinformation from… Stephen Fry? February 22 2022 by Jeff Johnson Support this blog: StopTheMadness, Tweaks for Twitter, StopTheScript, Link Unshortener, PayPal.Me The world-famous Stephen Fry tweeted yesterday about my Safari extension Tweaks for Twitter. Under most circumstances I'd be thrilled if someone with over 12 million followers tweeted...

How to make a home page bookmark to Twitter in Mobile Safari
3 Feb 2022 | original ↗

How to make a home page bookmark to Twitter in Mobile Safari February 3 2022 by Jeff Johnson Support this blog: StopTheMadness, Tweaks for Twitter, StopTheScript, Link Unshortener, PayPal.Me A customer of my Safari web extension Tweaks for Twitter asked me how to add a bookmark to their iOS home screen to open Twitter in Mobile Safari. The Add to...

Siri may phone home with Ask Siri disabled
2 Jan 2022 | original ↗

Whenever I install a new version of macOS, I always disable Siri in the setup screen. In fact I always disable Siri on my iOS devices too. I have no interest in Siri, and I don't want my devices to phone home to Apple with so-called "anonymous" data that always turns out to be less anonymous than claimed. I expected that the OS would respect my setup screen choice, and indeed if I look at the Siri pane in System Preferences, everything looks disabled.

iOS 15.2 broke Safari extension preferences storage
14 Dec 2021 | original ↗

Apple made a breaking change to Safari extension preferences storage in iOS 15.2 and iPadOS 15.2, which were released to the public yesterday. I believe but haven't confirmed that this breaking change was also made in Safari 15.2 for macOS, which was included in yesterday's Monterey update. I assume that Safari 15.2 is forthcoming for macOS Big Sur and Catalina too, though for some reason it hasn't yet been released (despite the 0day security vulnerabilities already announced in the release notes).

You always had the power to PiP on YouTube and everywhere
1 Dec 2021 | original ↗

My Safari extension StopTheMadness has a ton of features, which is great! Except when it's not. One downside to all those features is that an individual feature can get overlooked or forgotten. One such feature is "Show video controls", included with StopTheMadness for 2 years on macOS and since the beginning (September) on iOS. When this website option is enabled, StopTheMadness replaces the web site's custom video controls with Safari's native video controls, including picture-in-picture, full screen, AirPlay, and the timeline scrubber! It works not only on YouTube but on almost every site on the web with custom video controls.

Safari bug: background tabs reactivate
29 Nov 2021 | original ↗

As a Safari extension developer, I run into a lot of Safari bugs. A week ago I wrote about a bug where Safari forgets your history. This week I'm writing about a different bug. The bug was reported to me by one of my customers, as many bugs are, including last week's. Technically, it was more of a feature request than a bug report: the request was for my extension to "stop the madness". The madness in this case is Safari background tabs spontaneously coming to the front again, an obviously undesirable behavior. The initial report was for an obscure (to me) web site in New Zealand, but then I asked around, and someone said it also happened on ESPN, which is not so obscure (to me).

Safari forgets your history
21 Nov 2021 | original ↗

Clicking a link in a web browser changes the URL, and if you look at the browser's history after clicking, you'll see both the old URL and the new URL. The URL can also be changed programmatically, using the JavaScript Location API. After a new location is assigned in JavaScript, you should also see the old URL and the new URL in the browser's history. You should, and you do in Chrome and Firefox. But not in Safari! For some reason, Safari forgets the URLs. This bug appears to be many years old: it occurs in the latest version 15.1, and it occurs in the oldest version that I could test, Safari 11 on macOS 10.13 High Sierra. You can reproduce the bug by simply clicking the button below. The button runs a little script to change the location from my blog to my business web site.

DNSServiceNATPortMappingCreate was quietly killed in macOS Monterey
2 Nov 2021 | original ↗

According to Apple's API documentation, the function DNSServiceNATPortMappingCreate "Requests a port mapping in the NAT gateway, which maps a port on the local machine to an external port on the NAT." This function has been available to developers for more than five years, and it continues to work fine on macOS 11.6.1 Big Sur. It's not marked as deprecated in the documentation or in the framework header files from the macOS 12 SDK. However, the function simply doesn't work on macOS 12 Monterey and never has. I filed a bug in Apple's Feedback Assistant on June 8, the day after we got the first developer preview of Monterey at this year's Worldwide Developers Conference. I know of several other developers who also filed the same bug. Yet almost 5 months later, with Monterey having been released already to the general public, DNSServiceNATPortMappingCreate still doesn't work. I've heard that the bug hasn't been fixed in the macOS 12.1 beta either. Any software that relies on DNSServiceNATPortMappingCreate is out of luck on Monterey.

Mass confusion and dislike over Safari extension icon tinting
15 Oct 2021 | original ↗

For background to this post, you can read yesterday's Apple vandalized my icon in the latest betas and The Safari extension blues from a few weeks ago. In this post I want to document the mass confusion and dislike over Safari extension toolbar icon tinting, which started with Safari version 14 in 2020, continues to the present, and was just made worse in the Safari 15.1 beta.

Apple vandalized my icon in the latest betas
14 Oct 2021 | original ↗

A few weeks ago I wrote a blog post called The Safari extension blues, in which I described how Safari tints many extension toolbar icons with the system accent color, by default blue, and how my own StopTheMadness avoids the tinting. This blog post is a sequel, so if you haven't read the previous one yet, I hope that you'll go back and read it now for essential context. Don't worry, it's fewer than 1000 words, interspersed with pretty (and ugly) pictures.

Did iOS 15 kill Google AMP?
6 Oct 2021 | original ↗

For the past several days at least, Google search results have not included AMP links on iOS 15, but they still include AMP links on iOS 14. I've determined that Safari's User-Agent makes the difference. (You can spoof the User-Agent on iOS using the Safari web inspector on macOS.) Here's my iPhone's User-Agent:

StopTheScript
6 Oct 2021 | original ↗

StopTheScript is my new Safari extension for iOS 15 and iPadOS 15 that stops all JavaScript on your selected websites! It comes just two weeks after I brought my Safari extensions StopTheMadness and Tweaks for Twitter to iOS and iPadOS. StopTheScript is the only Safari extension in existence now that stops inline JavaScript on the web page as well as externally loaded JavaScript. Did you know that Safari content blockers can't actually block inline JavaScript? There's a demo you can test the StopTheScript website.

The Safari extension blues
30 Sept 2021 | original ↗

Answer me these questions three. What is your name? What is your quest? What is your favorite color?

Where are the Safari extensions in the iOS App Store?
21 Sept 2021 | original ↗

Yesterday Apple released iOS 15 and iPadOS 15 with a great new feature: Safari extensions! On my iPhone running iOS 15, when I select "More Extensions" in Safari Extensions Settings, it goes to the Safari Extensions page in the iOS App Store.

Google Chrome to remove detailed cookie and site data controls
3 Sept 2021 | original ↗

A month ago I ran into an obscure Google Chrome bug on macOS that caused the "All cookies and site data" page in Chrome settings (chrome://settings/siteData) to load very slowly. You can see this page if you open Preferences, select "Privacy and security", "Cookies and other site data", and then "See all cookies and site data". I filed a bug report with Chromium's issue tracker. Since then, some members of the Chromium team have been trying to track down the cause of the bug, a normal and boring process. However, this week I got an update on the issue that was shocking to me:

Why Xcode tools are slow after reboot
28 Aug 2021 | original ↗

I ran git status on a newly created, very small repository, but the command took more than 10 seconds to finish. This was highly unusual, as git status is mostly instantaneous for me. Indeed it was instantaneous the next time I ran it on the same repository. Puzzled, I could only think of one thing out of the ordinary: I had just rebooted my Mac. So I tried rebooting again, and then the issue occurred again!

The color purple
24 Aug 2021 | original ↗

Twitter inexplicably changed the color purple on their website today. It seems they also changed pink/red, but I'm going to focus on purple, because that's my Twitter theme color (and my favorite color, because Prince). You can set your theme color by pressing the "More" button in the Twitter left sidebar and selecting "Display" in the popup menu.

Dark menu bar and Dock on Big Sur
21 Aug 2021 | original ↗

On macOS High Sierra there was a system preference "Use dark menu bar and Dock":

Disappearing Safari extensions
18 Aug 2021 | original ↗

Since I released my Safari extension Tweaks for Twitter three months ago, I've received a number of bug reports from customers saying that the extension doesn't appear in Safari. And when my app calls the API [SFSafariApplication showPreferencesForExtensionWithIdentifier: completionHandler:] to show the extension in Safari Preferences, there's an error "SFErrorDomain error 1". This issue never happened with my other Safari extension StopTheMadness, which is three years old. The two extensions use different Safari extension API: Tweaks for Twitter is a Safari web extension, a newer API, whereas StopTheMadness is a Safari app extension, an older API. I've never been able to reproduce the issue with Safari web extensions myself until yesterday, so now I have more details to share. I suspect the reason I can now reproduce it is that I recently updated to Big Sur.

Mac OS update failed for the first time in 19 years
16 Aug 2021 | original ↗

I bought my first Mac, an iMac G4, in 2002. It came installed with Mac OS X 10.1 Puma, and I've been installing minor and major Mac OS X and macOS updates ever since, with the one exception of Mac OS X 10.7 Lion, which in my opinion was the worst Mac OS version ever (before now). My current machine is a 2014 MacBook Pro, which I had updated from Mavericks through Mojave. I did skip macOS 10.15 Catalina, however, which I've heard was very buggy, and I had been holding off as long as possible on macOS 11 Big Sur, which I've seen is very ugly. Ultimately, though, I couldn't wait any longer, because I need to run the latest Xcode beta in order to develop Safari extensions for iOS, and the latest Xcode beta requires Big Sur, so I finally decided to update to Big Sur on Saturday. This was a disaster.

Twitter locked my account (again) for an obvious joke
22 Jul 2021 | original ↗

My Twitter account has been mistakenly locked for the 4th time. This morning, Craig Mod wrote a tweet about YouTube.

Stop the Medium
13 Jul 2021 | original ↗

I don't understand why programmers — who could theoretically write their own blogging engine — write on Medium. There's not even a need to roll your own system, because a number of off-the-shelf options already exist. WordPress, anyone? Anyway, I usually try to avoid clicking on medium.com links, but occasionally there's a Medium article that I don't want to miss. For example, I read one today about the Apple Security Bounty program. That Medium article, though important, is not the subject of this non-Medium article. The subject is the awful Medium user interface and how to make it less awful. If you want to see how awful it is, try to select and copy some text from the linked article. Go ahead, I'll wait… forever.

Safari extension development: icons
7 Jul 2021 | original ↗

I'm working on bringing my Safari extensions StopTheMadness and Tweaks for Twitter from Mac to iOS, and it's progressing well! During this process I've noticed that there are some platform-specific differences between Safari iOS and Safari Mac extensions, as indeed there are between Safari Mac extensions and Google Chrome extensions, even though they all use the same cross-platform Web Extension format. (There's an older Mac-specific Safari app extension format, but that won't be available on iOS.) One easily noticeable platform-specific difference is the extension icons. Safari unfortunately tends to eschew the use of color now: you can see that all of Safari's built-in toolbar items are grayscale. If you're porting your Chrome extension to Safari Mac, you may notice that your toolbar item suddenly seems out of place and conspicuous; it's almost like landing in Kansas after having been to the land of Oz. Ironically, the Safari toolbar itself gets color in macOS Monterey, but not the toolbar items.

iOS Safari extensions bug
11 Jun 2021 | original ↗

I'm working on StopTheMadness for iOS, and I ran into my first bug already. The bug involves the Safari setting Preload Top Hit, which I blogged about recently. I encourage you to disable Preload Top Hit, but unfortunately that setting is enabled by default in Safari on both iOS and macOS, so my extension can't avoid it. The bug is that Safari's Preload Top Hit breaks run_at document_start for injected content scripts in web extensions.

StopTheMadness for iOS
8 Jun 2021 | original ↗

Before I (pre)announce the big news, a brief macOS update: I've done preliminary tests of my Mac App Store apps — StopTheMadness, Link Unshortener, Tweaks for Twitter, Underpass — on the developer beta of macOS 12 Monterey, and they all seem to work fine. My free app Stop The Mac App Store also works on Monterey. I'm not expecting compatibility issues with my Mac software. I'll continue to test on Monterey during beta period. If you experience any issues with one of my apps, please contact support.

Disable Safari Preload Top Hit
19 May 2021 | original ↗

By default, "Preload Top Hit in the background" is enabled in the Search tab of the Preferences window in Safari for Mac. Do yourself a favor and disable it, because the downsides outweigh the small upside.

Mac trustd high CPU
11 May 2021 | original ↗

Six months after the Mac OCSP appocalypse, here we go again, and here I go again. Back then I discovered that the trustd process was having trouble connecting to ocsp.apple.com, an issue temporarily solved by preventing connection attempts to that domain (for example in Little Snitch). Yesterday I started noticing another issue with trustd, but this time the issue was a little different: very high CPU usage. I've heard from several other people who started noticing the same issue yesterday too, one of whom helpfully referred me to this reddit thread with even more reports. On investigation, I found that the nsurlsessiond process was connecting to the server valid.apple.com, and immediately afterward trustd CPU jumped from 0% to 100%. It seems that the issue can be temporarily solved by preventing nsurlsessiond from connecting to valid.apple.com. You may have to reboot or force quit trustd to get its CPU usage back to normal. It's important to note that this is only a temporary workaround to the CPU usage problem; trustd is an important macOS system process that checks certificate validity and revocation status, so you probably don't want to block valid.apple.com forever.

Porting your Chrome extension to Safari
29 Apr 2021 | original ↗

Safari version 14 for macOS, released last year, added support for the cross-platform Web Extensions API. The intention was to make it much easier to port your Chrome extensions to Safari, by allowing you to use the same code on each platform. (This applies to Firefox extensions too, but I'm going to focus on Chrome, because that's where the main interest seems to be for Safari ports.) In the ideal case, your Chrome extension's code will "just work" in Safari, no changes required. Believe it or not, even chrome.* JavaScript API calls work in Safari! But there's a catch. You knew there'd be a catch. Or several catches. In this blog post, I'll give an overview of the issues you may face in porting your Chrome extension to Safari.

StopTheMadness: Hovering near greatness
21 Apr 2021 | original ↗

Today I released StopTheMadness version 21 in the Mac App Store. StopTheMadness is only 3 chronological years old, but software versions are like dog years. I just wanted to highlight some new features here, because most features in my web browser extension tend to be invisible. You wouldn't even know about them unless you read the release notes. And who does that? "Bug fixes and performance improvements."

Mac App Store review folly
19 Apr 2021 | original ↗

On April 13 I submitted Link Unshortener 7.0 to App Store Connect for review. It was approved with no issues, and I released the update in the Mac App Store the next morning. This was the sixteenth release of Link Unshortener. By pure coincidence that I'm just realizing now, Link Unshortener 7.0 shipped exactly one year after Link Unshortener 1.0. The update added a great feature worthy of the anniversary, but it became clear that the new feature needed refinements, so I submitted another version to App Store Connect three days later. While I was asleep that night, my submission went into review and was rejected. In the morning I read the unpleasant news:

NSURL is a bad host
10 Apr 2021 | original ↗

If NSURL invites you to a party, you should pass. Why? Because NSURL parties are passé. To be more specific, NSURL is based on an obsolete RFC. (Note: RFC is an acronym for Read the F-ing Commandment, while NS is an acronym for No Swift.) The obsolescence of NSURL is all explained in the class documentation for NSURL.

Distributing unnotarized Mac apps in a text file
3 Apr 2021 | original ↗

This isn't a late April Fools joke. (My April Fools joke that I got hired by Apple as a Swift Evangelist backfired with a profusion of congratulations.) This blog post is a kind of follow-up to some previous blog posts. Last month I wondered what's the best way to distribute Mac apps without notarization, and I decided that the best way was downloading with curl directly to the Applications folder. Unlike web browsers, curl does not add the com.apple.quarantine extended attribute to downloaded files. Still, this method is not ideal, because the app developer has to send users to the scary place: the command line! So I've continued to wonder if there's a relatively simple way to do it with a graphical interface. (If you think you can "just right click", well no, that's not quite how it works.) And then it finally hit me like a brick of gold wrapped in a lemon: I already knew how to remove the quarantine with a GUI, because this was my Mac sandbox escape! If you recall, a year ago I showed how to escape the sandbox by opening a maliciously crafted executable in TextEdit and then telling TextEdit via AppleScript to save the executable file. This causes the quarantine to be removed from the executable, because TextEdit has the special com.apple.security.files.user-selected.executable entitlement. I never received a bug bounty from Apple, and as far as I can tell this sandbox escape still exists in Big Sur. Which is actually good news for us right now, because we can use it to distribute Mac apps! For your enjoyment, I've created an example, which I call Gatecrasher:

How to stop Mac App Store notifications
29 Mar 2021 | original ↗

What's wrong with this screenshot? (It was taken on a non-retina monitor, but other than that…)

Closing web browser windows doesn't close connections
17 Mar 2021 | original ↗

Months ago I noticed something strange in the Little Snitch Network Monitor: Safari was still connecting to web sites after every window had been closed. At the time, I thought this was just a Safari bug. I brought the issue to the attention of some Safari engineers, who I had hoped would look into it. Since then, Safari has seen several software updates, and recently I remembered to check again to see whether the issue was resolved. Unfortunately I could still reproduce it, so I decided to investigate further. To my horror, I discovered that Chrome and Firefox were doing it too. That's too much a coincidence to be a bug, right? Could it be that web browsers are keeping open connections after windows are closed on purpose? If you don't have Little Snitch installed on the Mac (you should!), you can still see the open (ESTABLISHED) connections using the lsof (list open files) command-line tool in Terminal:

TRY THE NEW SAFARI
8 Mar 2021 | original ↗

In the past couple of days, news sites such as ZDNet and iMore have reported that macOS can display a notification advertising Safari when you first launch Microsoft Edge. It turns out that this "feature" actually appeared first in Mac OS X 10.10 Yosemite, as described in an old blog post by Daniel Aleksandersen, an engineer for the web browser Opera. The Safari advertisement can occur with any alternative web browser, such as Opera, not just with Microsoft Edge. Ironically, it can occur even with Apple's own Safari Technology Preview! I've discovered reliable steps to reproduce the advertisement, using the information from Aleksandersen's blog post.

Distributing Mac apps without notarization
7 Mar 2021 | original ↗

Sometimes a developer needs to send a Mac app to a user for testing, and in that case it's a pain to upload the app to App Store Connect first and wait for Apple to notarize the app before you distribute it. Another problem is that notarization requires apps to enable the hardened runtime. As I explained in a previous blog post, sandboxing and the hardened runtime are two independent technologies, and while the App Store requires apps to enable sandboxing, it doesn't require apps to enable the hardened runtime. Thus, if you normally distribute your app exclusively in the Mac App Store, the app might not have enabled the hardened runtime, and you won't be able to notarize the app for distribution outside the Mac App Store, which you may discover to your frustration at the last minute. (Needless to say, TestFlight for Mac doesn't exist yet, sigh.)

New app: Default web browser
5 Mar 2021 | original ↗

macOS 11 Big Sur has a bug that prevents some apps from appearing in the "Default web browser" menu in the General pane of System Preferences, which makes it difficult to set one of those apps as your default web browser. My own Link Unshortener is affected, among many others. I blogged about this bug two months ago. I'm told that the bug still exists in the latest 11.3 beta versions, unfortunately, so I'm pessimistic about the prospects of a fix coming from Apple. Therefore, I've decided to take matters into my own hands and write an app to change your default web browser on Big Sur. This new app is named "Default web browser". (There are only two hard things in computer science: changing your default web browser and naming things.)

How to use multiple search engines in Safari
3 Mar 2021 | original ↗

The Search Preferences in Safari for Mac contains a list of search engines, such as Bing, DuckDuckGo, and Google, from which you can pick one as your default search engine. But what if you want to use multiple search engines in Safari? It turns out that you can! The same preference pane also contains a little known feature, Enable Quick Website Search.

Mac App Store updates failing on Mojave, Part 2
26 Feb 2021 | original ↗

A couple months ago I wrote about Mac App Store updates failing on Mojave. This issue continued for a while after my blog post, but eventually Apple seemed to resolve it. Temporarily. Unfortunately, a very similar issue has arisen recently. Some Mojave users say that this issue was caused by installing Security Update 2021-002, which was released on February 9. Other Mojave users say that the Security Update was just a coincidence in time. I can't say definitively one way or another, but I can say definitively that the issue currently affects me (I did install Security Update 2021-002) and many other Mojave users. Apple's support community discussions are full of reports of App Store failures. There's no longer a "cancelled" error message in App Store app, like there was back in December. Instead, the App Store progress spinner simply continues spinning, and the app never downloads. (I can tell that the app download never starts, because I have Little Snitch installed.) This issue affects both app updates and new app installs, making both fail, no matter how many times you try.

Xcode code signing madness
23 Feb 2021 | original ↗

I was trying to build my app StopTheMadness, which I had been building successfully in Xcode for years, but suddenly the build started failing with a mysterious code signing error. Argh!

Deleting DerivedData the right way
2 Feb 2021 | original ↗

I know what you're thinking: there's a wrong way to delete Xcode's DerivedData? It turns out, yes, there is! The good news is that manually moving the DerivedData folder to the trash from Finder is the right way, or a right way. The bad news is that rm -fR from the command-line is the wrong way. To see why, we need to look at another command-line tool, hidden deep within your system:

New app: Stop The Mac App Store
2 Feb 2021 | original ↗

Have you ever been annoyed that Mac App Store pages in Safari automatically open App Store app? Would you like to stop that from happening? Good news, now you can! I've just released a free open source Mac app called Stop The Mac App Store that allows you to stop Safari (and Safari Technology Preview) from opening the App Store app.

How to change your default web browser on Big Sur
2 Feb 2021 | original ↗

macOS 11 Big Sur has a bug that prevents some apps from appearing in the "Default web browser" menu in the General pane of System Preferences, which of course makes it difficult to set one of those apps as your default web browser.

Mac App Store updates failing on Mojave
29 Dec 2020 | original ↗

In its relentless zeal to release major macOS updates every year, Apple is leaving its users behind. Not just behind in their macOS versions but also behind in their app versions installed from the Mac App Store. Many macOS Mojave users, including myself, have experienced frequent failures of App Store to update their installed apps. Whenever this occurs, App Store shows the completely unhelpful error message "cancelled".

Undocumented NSShadow change on Catalina
18 Dec 2020 | original ↗

Apple has published AppKit release notes for macOS Big Sur 11 and for macOS 10.14 but strangely not for macOS 10.15 Catalina. Thus, it's difficult to determine what changed in AppKit for Catalina. I have discovered one thing that changed: the shadowOffset implementation of NSShadow. Curiously, the API documentation for shadowOffset is now shared between AppKit and UIKit.

Disclosure: Yet another macOS privacy protections bypass
1 Dec 2020 | original ↗

Today I'm disclosing a macOS privacy protections bypass. I discovered that an application can use the venerable Unix command-line tool "ls" (list directory contents) to bypass both TCC (Transparency, Consent, and Control) and the sandbox, enabling unauthorized access to file metadata in directories that are supposed to be protected. This issue remains unaddressed in the latest public versions of Big Sur, Catalina, and Mojave, and is therefore, in one sense, a zero-day. Here is the timeline leading to my disclosure:

Some BS AppKit notes
28 Nov 2020 | original ↗

This blog post describes a few things I found while "adapting" my AppKit apps for macOS 11 Big Sur. Apple has documented some changes in its AppKit Release Notes for macOS Big Sur 11, but these are not comprehensive. My blog post is not comprehensive either, but it does go beyond Apple's release notes. I should also mention the helpful site macOS Big Sur changes for developers, which also goes beyond Apple's release notes.

Safari bugs me
18 Nov 2020 | original ↗

As a Safari extensions developer, I'm becoming frustrated with the quality of Safari for Mac. It has too many bad bugs, and they're causing problems for me, even costing me money. For example, there's a bug introduced over nine months ago, which I blogged about before, that prevents Safari users from enabling the extensions they've installed. This bug still exists in Catalina and Big Sur. When the bug first appeared, enabling extensions failed silently, but then later Apple added a (mostly useless) alert on failure, without actually solving the problem. Customers email me mystified, and I even randomly experience the problem myself, since I frequently need to enable my extensions for testing. A few months ago I blogged about a bug in Safari's WebExtensions API that was preventing me from releasing a new extension I was working on. That bug, which is a showstopper for me, is still not fixed either, not even in Safari Technology Preview, much less Safari.

Apple Developer ID OCSP
14 Nov 2020 | original ↗

On Thursday, the day that macOS 11 Big Sur was released, Apple's Developer ID Online Certificate Status Protocol (OCSP) service went down. This seems to have been part of a larger outage affecting a number of Apple services, as indicated by their System Status. When you launch a Mac app, macOS may check with Apple's Developer ID OCSP to see whether the app developer's code signing certificate is revoked. Since 2012, macOS (then known as Mac OS X) has required that all apps downloaded from the web (outside the Mac App Store) be signed with a valid Developer ID certificate, issued by Apple to developers. The purpose of Developer ID, according to Apple, is to prevent the spread of malware; if Apple discovers that a developer has distributed malware, Apple will revoke that developer's code signing cert, and then macOS will prevent any software signed with that cert from launching, thus protecting Mac users. Unfortunately, if there's an internet connection problem involving the Developer ID OCSP, that can also prevent Mac apps from launching. For several hours on Thursday, Mac users around the world experienced extreme slowness when launching their installed apps. It's possible that millions of Macs were affected by this OCSP problem, a major if short-lived computing disaster. Many Mac users, completely unaware of why their apps wouldn't launch, feared that there was a problem with their operating system, or even with their hardware.

Developer ID certificate revocation
29 Oct 2020 | original ↗

Last week, Mac users with HP printers were unable to print or run their printer software, because HP's code signing certificate was temporarily revoked. In this blog post I'll talk about how this works from a technical perspective, and clear up some misconceptions about the situation. Software distributed outside the Mac App Store, such as a printer driver from HP, is signed with a Developer ID code signing certificate. This certificate is issued by Apple's Developer ID Certification Authority (CA). There's a different CA, the Apple Worldwide Developer Relations Certification Authority, that's used for Mac App Store development. Information about Apple certificates and CAs can be found on the Apple PKI (Public Key Infrastructure) page. You can use the codesign command-line tool to see the certificate used to sign an app. For example, if you have my own app StopTheNews installed, use this command:

Chrome exempts Google sites from user site data settings
7 Oct 2020 | original ↗

In Google Chrome's "Cookies and site data" settings, accessible via the Preferences menu item or directly with chrome://settings/cookies in the address bar, you can enable the setting "Clear cookies and site data when you quit Chrome". However, I've discovered that Chrome exempts Google's own sites, such as Search and YouTube, from this setting.

Stop animated GIFs in Safari
1 Oct 2020 | original ↗

How do you pronounce GIF? I would claim that it's pronounced like "Jeff", but that's not important. What if you don't want to pronounce or indeed see animated GIFs? There's a preference "Reduce motion" in macOS System Preferences, Accessibility, Display, but for some reason this preference doesn't apply to animated GIFs. Fortunately, there's a workaround if you prefer not to display GIFs in Safari: use a style sheet. If you open Safari's Preferences window to the Advanced tab, you can set your own .css file as the style sheet. Here's some sample CSS that should hide GIFs on web pages.

Can't you just right click? Yes, with a workflow.
27 Sept 2020 | original ↗

In an earlier blog post, I explained why you can't "just right click" to open an unsigned app downloaded on macOS. It's not as simple as that. But can we make it simpler? When you download a file from the web, from email, or from an instant message, macOS "quarantines" the file. In technical terms, the com.apple.quarantine extended attribute is added to the file. If you attempt to open a quarantined app, macOS Gatekeeper checks whether the app has been validly code signed and notarized. If the app fails this check, then Gatekeeper prevents the app from opening. However, if an app is not quarantined, then opening the app bypasses the Gatekeeper requirements. Is there a simple way to remove an app from quarantine?

macOS Containers and defaults
22 Sept 2020 | original ↗

This is a follow-up to the article Enabling the Debug menu in Safari 14 on Big Sur and Catalina by Dan Moren. In the past, you could enable the hidden Debug menu in Safari by using the command defaults write com.apple.Safari IncludeInternalDebugMenu -bool true in Terminal app. However, Dan discovered that this no longer worked for him, and he was forced to manually edit a plist file in order to enable the Debug menu. So what happened here? This is the question my blog post will answer.

Safari web extension bug
17 Sept 2020 | original ↗

Yesterday Apple released Safari 14 for macOS Catalina and Mojave. This may be surprising, if you weren't expecting Safari 14 until macOS Big Sur, but in retrospect, last year Apple released Safari 13 for Mojave and High Sierra before Catalina, and the previous year Apple released Safari 12 for High Sierra and Sierra before Mojave, so we should have known that Safari 14 was coming "early". Apple actually releases major macOS Safari updates simultaneously with major iOS updates (such as iOS 14 yesterday), because iOS also contains major Safari updates. The iOS and macOS versions of Safari share code — and thus security vulnerabilities! — so Apple has to release security fixes on both platforms simultaneously, otherwise one platform's update would zero-day the other platform.

Stop Facebook click tracking
11 Sept 2020 | original ↗

Earlier this year I wrote about how Gmail hijacks your link clicks, swapping the visible URL with a tracking URL hidden in the data-saferedirecturl attribute of the HTML anchor element. Fortunately, my browser extension StopTheMadness protects you from this Gmail "clickjacking". I don't use Facebook, so I hadn't noticed, but a StopTheMadness customer reported a similar problem happening there. On investigation, we found that links in Facebook DMs were using the data-lynx-uri attribute to hide an https://l.facebook.com/l.php tracking URL.

Your Honor, what about the Mac?
27 Aug 2020 | original ↗

On August 17, Epic Games filed a motion for a temporary restraining order against Apple Inc. Here's an excerpt from Epic's proposed restraining order:

Can't you just right click?
18 Aug 2020 | original ↗

In 2012, Apple added Gatekeeper to Mac OS X (now macOS). When you try to run Mac software downloaded from the internet, Gatekeeper checks whether the software was signed with a valid Developer ID certificate. If not, then Gatekeeper refuses to run the software. Over the years, Gatekeeper has become more strict, recently adding a notarization requirement. On macOS Catalina, Gatekeeper not only checks whether the software was signed by a valid Developer ID certificate, it also "phones home" to check whether Apple has notarized the software, again refusing to run it if the check fails. Mac developers must sign up for the Apple Developer Program, sign a legal agreement, and pay an annual fee of USD $99 plus tax in order to obtain a Developer ID code signing certificate and upload software to Apple for notarization.

App Store is neither console nor retail but jukebox
15 Aug 2020 | original ↗

The iOS App Store has been compared alternatively to a retail store and to a game console. Retail stores and game consoles are very different entities, so I'm not sure how, rhetorically speaking, both comparisons are allowed and considered apt. In any case, neither comparison is accurate, presently or historically. We know the origins of the App Store, because it originated only a dozen years ago. The model for the App Store wasn't retail stores. It wasn't game consoles. It wasn't even the smartphones that existed at the time. The model for the iPhone App Store was the iTunes Music Store. Where did the 30% App Store commission come from? No coincidence, 30% just happened to be the commission on songs in the iTunes Music Store!

News+ privacy on Big Sur
11 Aug 2020 | original ↗

A tweet by Tony Haile, CEO of Scroll, received widespread attention yesterday. Haile said,

PSA if you ever ran my SafariPrivacyTest sample app
31 Jul 2020 | original ↗

A month ago I disclosed a macOS privacy protections bypass, and I offered a sample app for download that demonstrates the issue. Unfortunately, it turns out that the app had a little bug. In applicationDidFinishLaunching it calls CFPreferencesSetValue(KeepsWindowsOpenPref, kCFBooleanTrue, kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost), and in applicationWillTerminate it calls CFPreferencesSetValue(KeepsWindowsOpenPref, kCFBooleanFalse, kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost), where KeepsWindowsOpenPref = CFSTR("NSQuitAlwaysKeepsWindows"). The bug is that kCFPreferencesCurrentHost should have been kCFPreferencesAnyHost.

Stop the Swift 2.0
29 Jul 2020 | original ↗

A couple weeks ago I introduced my new browser extension StopTheSwift, which forces Apple's online developer documentation to show Objective-C API instead of Swift. Since then, I've received a report that StopTheSwift wasn't working right on certain pages, such as https://developer.apple.com/documentation/uikit/uipasteboard/detectionpattern. StopTheSwift 1.0 simplemindedly added ?language=objc to the end of documentation URLs, but it turns out that sometimes there are different URL subpaths for Swift (uipasteboard/detectionpattern) and Objective-C (uipasteboarddetectionpattern).

App Store Connect and StopTheMadness
23 Jul 2020 | original ↗

This is a note for users of App Store Connect and StopTheMadness. Since the App Store Connect redesign last month around WWDC, there may be an incompatibility between drag and drop reordering of screenshots and the StopTheMadness "Drag and drop" website option. So if you're having any trouble with that, just create new custom website options for appstoreconnect.apple.com and disable the "Drag and drop" option. More instructions are on the StopTheMadness support page. I'll see if I can fix the issue, but it's a bit difficult to test at the moment, because I'd have to create a new app version in App Store Connect.

Stop the Swift
15 Jul 2020 | original ↗

Many of the API pages in the Apple Developer Documentation have a language selector that allows you to choose whether to see the API in Swift or Objective-C. Swift is the default:

macOS Recovery: Bug or Feature?
9 Jul 2020 | original ↗

If you enter diskutil list in Terminal, you can see that your Mac's internal disk has a recovery volume, and if you hold down ⌘r at boot, your Mac boots into the recovery volume. If you've installed multiple macOS boot volumes, either on your Mac's internal disk or on an attached external disk, you may also have multiple recovery volumes. When you hold down ⌘r at boot, your Mac selects the recovery volume associated with the Startup Disk selected in System Preferences, so you can change the recovery volume by changing the Startup Disk. Starting with macOS Catalina, the recovery volume requires a login for some reason. According to Apple's support documentation, "You might be prompted to enter a password, such as a firmware password or the password of a user who is an administrator of this Mac." The word "might" seems a bit misleading: you will be prompted to enter a password on macOS Catalina and later (later AKA Big Sur). The big (Big) question, though — and the purpose of this blog post — is, the password from which volume?

Introducing the free Safari extension FindTheMadness
6 Jul 2020 | original ↗

JavaScript in a web browser is mostly invisible, for better or worse. When my paid extension StopTheMadness is working, you mostly don't notice it, and that's the point. My good JavaScript in the extension prevents bad JavaScript in web pages from affecting users. The value of StopTheMadness is obvious when you install it and some annoying web behavior immediately stops. However, the ongoing value of the extension is less obvious, since it Just Works™, as the saying goes. This is not a worry for StopTheMadness customers, who seem quite happy according to feedback and reviews, but it is a worry for me as the developer of the extension, and a user. In fact it started as a personal project for my own use. It just works for me too, and it has for a long time, so the question is how can I market the extension if I can't explain to people what specific problems it solves? The irony is that my problems are already solved. I've often joked that I should randomly disable StopTheMadness to show people what they'd miss without it. (Don't worry, I won't actually do this!)

Disclosure: Another macOS privacy protections bypass
30 Jun 2020 | original ↗

Today I'm disclosing a macOS privacy protections bypass. (You may recall that I disclosed another one last year.) The privacy protections system (also known as TCC: Transparency, Consent, and Control) was introduced in macOS Mojave, and one of its purposes is to protect certain files on your Mac from access by unauthorized apps. I've discovered a way for an unauthorized app to read the contents of protected files, thus bypassing the privacy protections. This issue exists in Mojave, Catalina, and the Big Sur beta. It remains unaddressed and is therefore, in one sense, a zero-day. Here's the timeline leading to my disclosure:

Better disassembly on macOS Big Sur
27 Jun 2020 | original ↗

This is the third part to what is now a three part series on disassembling system libraries on macOS 11 Big Sur. Part 1 explains how to extract the system libraries from the dyld shared cache, and Part 2 explains some difficulties in disassembling Objective-C in those extracted libraries. Part 3 will provide a solution to those difficulties!

Objective-C disassembly on macOS Big Sur
25 Jun 2020 | original ↗

This is a follow-up to my blog post yesterday Extract the system libraries on macOS Big Sur, in which I explained how to extract the system libraries from the dyld shared cache. Although you can successfully disassemble these extracted libraries, there's still a problem: the otool command-line tool fails to understand many Objective-C references in the disassembly. Let's take a look at an example from my favorite framework, AppKit. The following is from the implementation of the -[NSApplication init] method. In order to call [super init], the implementation has to get the NSApplication Objective-C class. For convenience I use my own command-line tool riptool, which is a wrapper around otool that resolves rip-relative addresses.

Extract the system libraries on macOS Big Sur
25 Jun 2020 | original ↗

According to the macOS Big Sur 11 Beta Release Notes, "the system ships with a built-in dynamic linker cache of all system-provided libraries. As part of this change, copies of dynamic libraries are no longer present on the filesystem." If the libraries are no longer present on the filesystem, that makes it awfully hard to disassemble them! Fortunately, there are ways to extract the system libraries from the cache. One way is provided by Apple itself: the dyld_shared_cache_util command-line tool. Unfortunately, this tool does not come installed with macOS Big Sur. However, the tool is open source, so we can build it ourselves. You can download the dyld project from Apple Open Source. The latest version is a little behind, at macOS 10.15.3, but that works fine for our purpose. The download contains a convenient Xcode project. Don't bother trying to build all targets in Xcode, just build the dyld_shared_cache_util target. You'll need to make a number of modifications in order to build and run the target successfully. I'm assuming that you're building with Xcode 12 on Big Sur.

Stop DuckDuckGo clickjacking
15 Jun 2020 | original ↗

You may think that only Google is guilty of clickjacking search results, but DuckDuckGo is guilty too. Although the "crime" is not nearly as bad in this case, DuckDuckGo still uses JavaScript to intercept your link clicks, and there's no good reason for it. One consequence of this clickjacking is that your Safari browsing history gets messed up. Let me illustrate with an example. I searched for "StopTheMadness", clicked on the link for the product's home page, clicked on the link for the product's support page, and then opened Show All History in Safari:

StopTheMadness can now stop mouse tracking
1 Jun 2020 | original ↗

Today I've released version 15.2 of my web browser extension StopTheMadness in the Mac App Store. This update contains a new website option called "Mouse movement". When this option is enabled, StopTheMadness stops sites from using JavaScript to track the movement of your mouse pointer (or trackpad pointer). One benefit of the new feature is that it protects your privacy. Some sites such as Facebook are notorious for tracking your mouse movements. Another benefit is that it stops some common website annoyances. For example, it stops the little popups from appearing when you hover over links on Wikipedia or when you hover over user accounts on Twitter. The new website option "Mouse movement" is available in all browsers supported by StopTheMadness: Safari, Firefox, Google Chrome, Microsoft Edge, and Brave.

Logging https requests and responses of Apple system processes
31 May 2020 | original ↗

This is a follow-up to Catalina is checking notarization of unsigned executables. In that blog post, I explained how I was trying to compare packet traces of app notarization checks with packet traces of (apparent) shell script notarization checks. The traces looked the same. The request packets even had the exact same number of bytes. The only problem with the comparison was that the requests and responses use https and are thus encrypted. Is there a way of decrypting them?

Software Update changes in the latest macOS releases
27 May 2020 | original ↗

Today Apple released macOS Catalina 10.15.5, as well as Security Update 2020-003 for macOS Mojave and High Sierra. Apple also published support articles listing the security content and non-security content of those updates. In the latter article, at the end of "Enterprise content", there's a note about the softwareupdate command-line tool:

The Mystery of the Phantom App Updates, Part 2
25 May 2020 | original ↗

As reported by MacRumors and other media outlets, Apple issued hundreds (thousands?) of third-party app updates yesterday in the iOS App Store (but apparently none in the Mac App Store). These were not new versions of the apps submitted by the developers but rather re-releases of the current versions, modified somehow by Apple. (Apple itself must code sign all apps for distribution in the App Store.) It has been speculated that these new releases are to fix a recent issue plaguing iOS users that prevents them from opening their installed apps. Instead, they see an alert that says "This app is no longer shared with you. To use it, you must buy it from the App Store."

Catalina is checking notarization of unsigned executables
23 May 2020 | original ↗

This is a follow-up to Allan Odgaard's excellent article macOS 10.15: Slow by Design. I want to talk specifically about the first section "Spawning a new Process", because there has been widespread misunderstanding of this. Odgaard provides a simple test to show that the first run of an executable is delayed while Catalina checks the executable's notarization status online. This occurs even for shell scripts, which cannot be code signed!

Link Unshortener for iOS
19 May 2020 | original ↗

This is not an announcement of Link Unshortener for iOS. Unfortunately, it's the opposite. I did begin development, but I've determined that unless a pleasant surprise (miracle) occurs at WWDC next month, Link Unshortener for iOS is not a viable product, due to iOS API limitations.

__kindof useful?
17 May 2020 | original ↗

I've noticed the Objective-C keyword __kindof in system framework header files, but I've never used it in my own code. What's the purpose of the keyword? Is it necessary? Is it useful?

Stop the Daring Fireball?
11 May 2020 | original ↗

The title of this article is tongue-in-cheek. I have no desire to stop Daring Fireball. Quite the opposite! I'm grateful that DF exists and thrives. But "Stop the [Thing]" has become a kind of personal brand. It's said that naming things is one of the hardest problems in computing, and that seems right, because my app names are becoming derivative: StopTheMadness, StopTheNews, and StopTheTwitter. Today I released StopTheMadness version 15.0 in the Mac App Store with a new feature: support for site-specific CSS in Safari's user style sheet! The inspiration for this new feature was none other than Daring Fireball.

Stop 'Open in the Twitter app' in Safari Catalina
8 May 2020 | original ↗

Some people install the first party Twitter app on macOS Catalina in order to get push notifications — which Twitter doesn't enable anymore for third party clients — but otherwise have no wish to use the (crappy Catalyst) app. Nonetheless, when you visit a twitter.com web page in Safari when the Twitter app is installed, Safari "helpfully" suggests that you open the link in the Twitter app.

Stop Gmail click tracking
6 May 2020 | original ↗

I have a Gmail account, but I always access it in Mail app, never in webmail, so I wasn't aware of some Google mischief until recently. I had previously written about how Google Search hijacks your link clicks and replaces the apparent URL with a tracking URL. It turns out that Gmail also does something similar.

Reflections on the Mac sandbox escape
30 Apr 2020 | original ↗

My previous blog post disclosed a Mac sandbox escape. To save myself time and effort, I simply copy and pasted my original email to Apple Product Security. (After all, I'm not getting paid a bug bounty for my work!) This probably wasn't ideal for public consumption, because my email presumed a high level of knowledge on the subject possessed by Apple Product Security but not necessarily possessed by the general public. So I'm writing now to clarify a number of points that I feel have not been broadly understood.

Mac sandbox escape
27 Apr 2020 | original ↗

This blog post discloses a sandbox escape on macOS. I reported the issue to Apple Product Security on December 19 2019, the day the Apple Security Bounty program finally opened. (I discovered the issue in August 2019.) Today I received an email from Apple Product Security saying "we do not see any actual security implications." I've heard this kind of response before — they don't see any security implications… until they do — but in any case I obviously won't be receiving a bounty for this issue, and I'm free to publish it, again letting the public judge for themselves whether there are security implications. To save myself time, I'm just going to copy and paste my original report:

NSFormatter allows invalid values
25 Apr 2020 | original ↗

I've written before about a caveat with NSFormatter. Now I'm writing about one again. I've discovered what I consider to be a bug in NSFormatter and NSTextField. One of the roles of a formatter is to prevent the user from entering invalid characters into a text field. For example, if you have a text field that is designed to take a number, you might limit entry in the text field to numerical digits. This is accomplished by subclassing NSFormatter and implementing the method isPartialStringValid: proposedSelectedRange: originalString: originalSelectedRange: errorDescription: to return NO when it detects invalid characters. However, I've discovered a situation in which that method returns NO, but the text field still adds an invalid character to its string value.

Working without a nib, Part 12: NSWindow memory management
21 Apr 2020 | original ↗

I've been working from home for a long time. Now that many of you have joined me in working without an office, will you also join me in working without a nib? You might ask why, and as luck would have it, my previous blog post in the "Working without a nib" series explained why! After why, the next logical question is how. In this blog post I'll talk about a subject that's always been particularly tricky in Cocoa: NSWindow memory management. When you work with a nib, NSWindowController "magically" handles NSWindow memory management. Of course, that just pushes the problem up to the meta-level, because nothing magically handles NSWindowController memory management. Anyway, when you work without a nib, you don't need NSWindowController. So how does NSWindow memory management work?

Bad Safari extensions bug with context menus
20 Apr 2020 | original ↗

This blog post is a heads-ups to Safari extension users, Safari extension developers, and hopefully the Safari extensions engineering team at Apple about a bad bug in Safari with extensions and context menus. The bug is that if you have a Safari extension enabled, and the Safari extension has a context menu item (as many extensions do), then opening a context menu on a link can sometimes cause the link to open, as if you had just clicked the link instead of control-clicking. This bug was introduced recently; my suspicion is that started with the software releases on March 24, which included Safari 13.1 for Mac. I have filed a report (FB7666007) in Apple's official bug reporting system. The following are steps to reproduce on the latest versions of Catalina and Mojave with Safari 13.1 installed. (The bug also occurs with Safari Technology Preview 104.)

Introducing Link Unshortener
14 Apr 2020 | original ↗

Today I've released a new app in the Mac App Store! The app is named Link Unshortener, and its purpose is to expand shortened web links.

Xcode indexing tip
12 Apr 2020 | original ↗

This is a tip to help Xcode find the proper documentation for the methods you use in your source code. Apparently Xcode needs a lot of help. I had implemented some Foundation framework methods in my code, but I was having trouble getting the documentation in Xcode. Option-clicking on the method declarations popped up popups that just said "No Quick Help", and command-clicking on the method declarations did not show the methods in the Foundation framework headers but rather did nothing other than momentarily change the highlight color of the method declarations in my source code. You've probably experienced this phenomenon before. It's ever so much fun! In this case, however, I found a solution.

Resources for learning Objective-C and AppKit
1 Apr 2020 | original ↗

This blog post is not an April Fools joke. It addresses a serious documentation problem. There are millions of lines of Objective-C code in active use, and of course millions of Macs in active use. But how does a new developer work with them?

Underpass is back (though it never left)
30 Mar 2020 | original ↗

At long last, Underpass version 1.2.0 is now available in the Mac App Store and iOS App Store. Underpass for Mac was last updated in January 2019, and Underpass for iOS in December 2018. If you're not familiar, Underpass is a peer-to-peer file transfer and chat app with end-to-end encryption for complete privacy and security. Underpass is unlike any other chat app because it doesn't use a third-party service. The app is both a server and a client, so any two instances of the app running on a Mac or iOS device can make a direct network connection to each other, either on the internet or on a LAN, including ad hoc peer-to-peer wifi networks! You can use Underpass to exchange files and text between your own Apple devices or with another Underpass user.

Safari bug: can't enable extensions on Catalina
25 Mar 2020 | original ↗

In macOS 10.15.3, Apple introduced a bug that can prevent you from enabling or disabling Safari extensions. In order to enable or disable an extension, you must click the checkbox next to the extension in the Extensions pane of Safari Preferences. The support site for my own extension StopTheMadness has instructions and screenshots explaining how to enable a Safari extension, but under normal circumstances it's relatively easy. When the bug occurs, however, then clicking the checkbox does nothing: the checkbox doesn't get checked, and the extension doesn't get enabled either. This is a serious bug affecting many users and all Safari extensions by every extension developer. Unfortunately, the bug was not fixed in macOS 10.15.4, which was released yesterday, so we're still stuck with the bug for the immediate future. The purpose of this blog post is to raise awareness about the bug, for Safari extension users, Safari extension developers, and the Safari engineering team itself.

Safari no longer runs disabled extensions
24 Mar 2020 | original ↗

A couple of months ago I disclosed an issue I had discovered and reported to Apple Product Security: Safari runs disabled extensions. At the time, Apple Product Security felt that there were no actual security implications to this, which is why I went public. However, they seem to have had a change of heart after the publication of my blog post. Apple fixed the issue in Safari 13.1, released today, and credited me in the document describing the security content of Safari 13.1. Under "Additional recognition" at the end it says, "We would like to acknowledge Jeff Johnson of underpassapp.com for their assistance." That's me! So apparently there were security implications, as I argued.

Mac App Store in a nutshell
23 Mar 2020 | original ↗

During this unprecedented period of working from home, Zoom is unsurprisingly among the top 10 paid apps in the Mac App Store, currently #7.

PayPal Me
18 Mar 2020 | original ↗

Some friends have inquired how they can support me financially beyond buying my apps StopTheMadness and Underpass. These apps are one-time, upfront purchases, with no upgrade fees or subscriptions. I had hoped that my app sales would be sufficient, but my sales have never been great, and the current pandemic is causing a dramatic economic decline in most industries, including software. This decline in sales is affecting me and a number of other indie developers I know. Therefore, I've now decided to provide a public PayPal link for those who might be interested. If you've benefitted from my activities over the past few years — adding features to StopTheMadness, blogging about technical issues here, publishing free open sources apps such as StopTheNews and Bonjeff — and you wish to financially support those continued activities, you can now PayPal Me. If you don't want to, or can't afford it, that's perfectly fine, but if you do want to, and are able to afford it, I guess it's silly of me to turn down offers at this point.

Resolve rip-relative addresses from otool
8 Mar 2020 | original ↗

You can use /usr/bin/otool -tV from the command-line to disassemble Mach-O files. If you don't know what Mach-O's are, they're like Krusty-O's only tastier and healthier. One problem with otool, however, is that it doesn't resolve rip-relative addresses. In the x86_64 (64-bit Intel) architecture, rip is the register that contains the instruction pointer. A rip-relative address is an address specified by an offset, either positive or negative, from the instruction pointer. For example, 0x99eac(%rip) is an rip-relative address in this disassembly:

The decimation of Safari extensions
2 Mar 2020 | original ↗

This blog post attempts to give an overview of what happened to Safari extensions in the past few years, from the perspective of a developer (me) with many years of experience working on Mac apps and Safari extensions.

StopTheMadness for Mac adds Chrome, Edge, and Brave!
13 Feb 2020 | original ↗

StopTheMadness, the beloved and highly rated Safari and Firefox extension in the Mac App Store, has added support for Google Chrome, Microsoft Edge, and Brave. That's five web browsers supported for one purchase! A one-time purchase, not a subscription. The new version 11.0 of StopTheMadness is released today and available now worldwide. It's fully compatible with macOS Sierra and later, including the current macOS Catalina.

Safari runs disabled extensions
26 Jan 2020 | original ↗

Little Snitch is great at catching apps "phoning home". Much to my surprise, a couple of months ago Little Snitch caught a disabled Safari extension phoning home (where "home" was Amazon Web Services). In fact this extension had never been enabled in Safari. After further investigation I learned that on every launch, Safari runs every registered extension — that is, every extension that appears in Safari's Extensions Preferences — whether the extension is enabled or disabled.

Swift fatalError is a fatal error
15 Jan 2020 | original ↗

You may have seen the Swift function fatalError() used in code samples, but in my opinion the function ought to be avoided entirely, especially in production code, because using the function exposes TMI in release builds. When fatalError() is called in a source file, the compiler writes the full system path of the source file into the compiled binary, for both debug and release builds, because the function is designed to print the source file path along with its log message. Anyone can see the file path by running strings or otool -tV on the binary from the command line. The output will be something like this:

Questions about the Apple Security Bounty
13 Jan 2020 | original ↗

I'm not a professional security researcher, I'm just an app developer. I don't know how security bounty programs work, as I've never participated in one until now. On August 8 at the Black Hat 2019 conference, Apple announced an expansion of their bounty program for security vulnerabilities. The previous, limited bounty program was by invitation only, and it covered iOS only, whereas the expanded bounty program would be open to anyone and cover all of Apple's operating systems, including macOS. I have over a decade of experience in Mac development, and I've discovered several security issues in macOS during that time, so Apple's announcement of a bounty program inspired me to look for more. Within a couple of months — before the release of macOS 10.15 Catalina on October 7 — I found a couple of issues to report.

The security of Safari extensions
8 Jan 2020 | original ↗

When you open Safari's Extensions Preferences, you may see some scary warnings, such as "Can read sensitive information from webpages, including passwords, phone numbers, and credit cards on: all webpages" and "Can see when you visit: all webpages".

How to stop Safari for Mac disk caching
6 Jan 2020 | original ↗

What happens on the web stays on the web, right? Unfortunately, wrong. We know about web cookies, which sound better than they taste. When you visit a web site in a browser such as Safari, the site may store bits of data called cookies on your disk. Cookies are often abused for tracking but remain a necessary evil to allow you to remain logged into web site accounts. What you may not realize is that cookies are just the tip of the iceberg. We're talking hundreds of megabytes or even gigabytes of iceberg, enough to put a laptop's disk underwater. I thought the purpose of a web browser was to browse the web, didn't you? If I wanted to browse my file system, I'd use Finder. For the purpose of this blog post I did browse my file system, and I'll tell you what I found.

Revisited: The true and false security benefits of Mac app notarization
21 Dec 2019 | original ↗

Eight months ago I wrote an article about the true and false security benefits of Mac app notarization, in which I argued that the publicly touted benefits of notarization — revocation and malware scans — are bunk, but there was one true benefit — two-factor authentication. Now I must admit that I was wrong.

Undocumented Catalina file access change
18 Dec 2019 | original ↗

It's well known that if you drag a file from Finder and drop it into Terminal, the full path of the file will output in Terminal. The same behavior occurs with copy and paste too. This has always been a very convenient but innocuous operation… until macOS 10.15 Catalina. I've discovered that on Catalina, pasting a file from Finder not only outputs the file path in Terminal, it also invisibly and permanently grants Terminal access to the file, bypassing any macOS privacy protections!

Hardened Runtime and XPC Services
9 Nov 2019 | original ↗

This is a follow-up to my recent blog post about the hardened runtime, which was itself a follow-up to my earlier blog post about the hardened runtime. So you can call this a hardened runtime trilogy. Just don't call it a comeback. In episode III (Revenge of the Service), I wish to expand on something I said in episode II (Attack of the Contacts):

NSAssert considered harmless
8 Nov 2019 | original ↗

My friend Ilja Iwas had a question: if a Mac app enables the ENABLE_NS_ASSERTIONS build setting, why doesn't the app crash when it calls NSAssert in the applicationDidFinishLaunching: method of the NSApplicationDelegate protocol? Good question! Curiously, the app does crash when it calls NSAssert in the applicationWillFinishLaunching: method, so we have a bit of a mystery.

Hardened Runtime and Sandboxing Revisited
7 Nov 2019 | original ↗

This is a follow-up to my earlier blog post as well as a response to a a blog post by the developers of GitFinder that was highlighted by Michael Tsai. Although GitFinder is distributed outside the Mac App Store, the developers nonetheless chose to sandbox it. The GitFinder app does not have the sandbox entitlement to access a user's Contacts (com.apple.security.personal-information.addressbook), but the GitFinder app does embed an xpc service with that sandbox entitlement. The xpc service accesses some information in the user's Contacts and passes that information back to the app. GitFinder does not currently enable the hardened runtime, but next year Apple will require all apps to enable the hardened runtime in order to get notarized for distribution outside the Mac App Store. The developers of GitFinder are upset because enabling the hardened runtime requires giving the Contacts sandbox entitlement to the app as well as to the embedded xpc service. Why is that necessary?

Disclosure: macOS privacy protections bypass
9 Oct 2019 | original ↗

On February 9 I emailed Apple Product Security and reported a vulnerability that allows an app to bypass macOS privacy protections. I mentioned this the same day in a blog post. The vulnerability still exists in macOS 10.15 Catalina. Yesterday I learned that this vulnerability would not be eligible for Apple's Mac bug bounty program (because it was reported before the program was announced). Thus, I'm disclosing the vulnerability to the public today. Apple has had 8 months to address the vulnerability, and they've chosen not to address it. I believe that I've already gone above and beyond the duty of responsible disclosure by keeping my secret for so long. It's not even a particularly profound secret, for the vulnerability is hiding in plain sight, as you'll see.

What happened to the Mac bug bounty program?
8 Oct 2019 | original ↗

On August 8 at the Black Hat 2019 conference, Apple announced that they were expanding their bug bounty program for security vulnerabilities. Apple's previous, limited bug bounty program was available only to Apple-selected security researchers, and it covered only iOS. The expanded bug bounty program would be open to anyone, and it would cover all of Apple's operating systems, including macOS.

The Safari Extensions Gallery is no longer available
4 Sept 2019 | original ↗

This is an update to my post from last week Important Information Regarding the Safari Extensions Gallery, which described an email I received from Apple Developer Relations warning that the Safari Extensions Gallery will no longer be available in September 2019. I was expecting this to happen at the end of September, presumably when macOS 10.15 Catalina is released to the public. However, yesterday afternoon I received another email from Apple Developer Relations, just 8 days after the first email. The new email said that the Safari Extensions Gallery is no longer available. And indeed, the previous URL of the Safari Extensions Gallery https://safari-extensions.apple.com/ now redirects to the Mac App Store in Safari, while the URL completely fails to load in other web browsers such as Chrome and Firefox. The Safari Extensions Gallery is officially discontinued.

Important Information Regarding the Safari Extensions Gallery
27 Aug 2019 | original ↗

Yesterday afternoon I received an email from Apple Developer Relations titled "Important Information Regarding the Safari Extensions Gallery". According to the email, "the Safari Extensions Gallery will no longer be available in September 2019."

A problem worse than Zoom
11 Jul 2019 | original ↗

On macOS, an app can register to handle URL schemes. Web browsers such as Safari, Chrome, and Firefox register to handle the schemes for web pages, http or https. Non-browser apps may register to handle other URL schemes; for example, an email client may register to handle the well known mailto scheme. When a URL is opened in a web browser, and the browser itself cannot handle the URL scheme, the browser looks for another app to handle the URL. If there's a handler app for the URL scheme, then the browser will open the app and pass the URL along to that app. Thus, clicking a mailto:[email protected] link will open your email client with a new email addressed to Tim Cook.

Stop Safari from autosubmitting login forms
2 Jul 2019 | original ↗

Today I released StopTheMadness version 8.0 in the Mac App Store. There's one new feature: StopTheMadness can now stop Safari from autosubmitting login forms!

Private browsing in Safari with StopTheMadness
10 Jun 2019 | original ↗

Today I released StopTheMadness version 7.1 in the Mac App Store. There's one new feature: StopTheMadness now stops web sites from detecting that you're in private browsing mode in Safari!

Catalina app compatibility
7 Jun 2019 | original ↗

I'm happy to report that all of my apps seem to be fully compatibile with macOS 10.15 Catalina. This includes StopTheMadness, Underpass, StopTheNews, and Bonjeff.

My Twitter account has been locked for a third time
6 Jun 2019 | original ↗

My Twitter account has been locked for a third time. I have no idea why.

We believe that what’s in our store says a lot about who we are
30 May 2019 | original ↗

According to Apple's new App Store - Principles and Practices page, "We believe that what’s in our store says a lot about who we are." I hope that's not true, because the App Store is rife with scams. Apple says, "It’s our store. And we take responsibility for it." I know that's not true. If you do a little looking, it doesn't take long to find scammers in the App Store. I've done it. Has Apple done it? I haven't found evidence that Apple takes responsibility for the App Store.

Introducing StopTheNews
4 May 2019 | original ↗

Have you ever been annoyed that Safari on macOS 10.14 Mojave wants to open Apple News articles in News app instead of in Safari? Well no more! I've just released a new, free, open source Mac app called StopTheNews that stops Safari from opening Apple News articles in News app. Instead, StopTheNews opens the original article URL in Safari. StopTheNews also works with Safari Technology Preview, if that's your default web browser.

StopTheMadness First Anniversary
30 Apr 2019 | original ↗

Exactly one year ago today, I released StopTheMadness version 1.0 in the Mac App Store. StopTheMadness has come a long way since then and is currently at version 6.1. (No apologies for version number inflation!) The app has gained some great new features, including a Firefox add-on to go along with the original Safari extension. It has increasingly emphasized protecting your privacy on the web, blocking tracking methods such as hyperlink auditing (anchor "ping"), invisible beacons, and uniquely identifying URL query parameters.

Google Chrome can no longer disable hyperlink auditing
23 Apr 2019 | original ↗

As I mentioned in my blog post Safari link tracking can no longer be disabled, the hidden preference chrome://flags#disable-hyperlink-auditing to disable hyperlink auditing had already been removed from the beta versions of Google Chrome. Today, Google shipped Chrome 74 to the public, and this hidden preference is now indeed gone for everyone. The change log for Chrome 74 includes the removal of disable-hyperlink-auditing from Chromium.

The true and false security benefits of Mac app notarization
21 Apr 2019 | original ↗

Almost everyone, including Apple, has painted a false picture of the security benefit of Mac app notarization. There is a true benefit, which I haven't seen anyone mention, but I'll discuss it here. On the other hand, the publicly touted benefits of notarization are bunk, in my opinion, and I'm going to debunk them in this post too. Most notably, I'll explain how the notarization malware scan is superfluous security theater, a mere marketing gimmick that I believe ought to be abolished because of the burden it places on legitimate developers.

More madness stopped: beacons
18 Apr 2019 | original ↗

My blog post Safari link tracking can no longer be disabled generated a lot of discussion and controversy. Eventually the WebKit project itself felt compelled to respond publicly with their own blog post. I won't respond to their blog post here, because I feel that my follow-up blog post Some thoughts on anchor ping already anticipated and addressed the arguments they made. I do want to talk about an additional form of tracking technology mentioned in the WebKit article: the Beacon API. Both WebKit and Mozilla admit that beacons were designed for tracking and analytics. Unlike anchor "ping", there was never a way to disable beacons in Safari… until today!

The madness stopped: anchor ping
13 Apr 2019 | original ↗

Last week I blogged about how Safari link tracking can no longer be disabled. Safari 12.1 removed a hidden preference that was the only way to disable hyperlink auditing, a method for tracking your link clicks via the anchor "ping" attribute. Coincidentally, Google Chrome also removed its hidden flag recently; in the Chrome beta versions you can no longer disable hyperlink auditing, though you can still disable it for now in the "stable" Chrome version. My blog post has sparked a lot of discussion on the web, and it looks like the Safari and Chrome teams are starting to be moved by the public pressure. If you want to keep up with the latest news about this subject, Michael Tsai's blog is a great resource, as always.

Postmortem: iTunes Affiliate for apps
10 Apr 2019 | original ↗

The iTunes Affiliate Program for apps paid registered Affiliates a percentage of app sales that resulted from links to the Apple App Store from the Affiliate's web site. The iTunes Affiliate Program still exists for music, books, movies, and TV shows, but Apple ended the program for apps on October 1 2018. Yesterday, six months later, I finally got paid the remaining balance owed to me as an iTunes Affiliate. Getting paid was an ordeal that took many emails from me to the iTunes Affiliate Program. I know that some developers still haven't gotten paid fully, so I hope this blog post helps them to recover their money.

Some thoughts on anchor ping
8 Apr 2019 | original ↗

This is a follow-up to my recent article Safari link tracking can no longer be disabled. I'm quite surprised that my complaining about a hidden preference in Safari has generated so much discussion on the internet. I'm also quite pleased, because I think it's important to draw attention to the privacy implications of the HTML anchor ping attribute and have a public debate about it. I've heard so many people say that they weren't even aware that anchor ping existed until they saw my article, so I'm glad to raise awareness.

Safari link tracking can no longer be disabled
3 Apr 2019 | original ↗

HTML5 added a "feature" to the web called hyperlink auditing. You can read the specification from the Web Hypertext Application Technology Working Group (WHATWG). Hyperlink auditing is added to a web page via the ping attribute on an HTML anchor element (), i.e., a link. Here's a example, followed by the HTML code for a simple test page that implements it:

NetService NutHouse
14 Mar 2019 | original ↗

Yesterday I received a crash report for Bonjeff, my open source Swift app that shows you a live display of the Bonjour services published on your network. Since I'm (in)famous for my Objective-C advocacy, I wrote an open source app in Swift to demonstrate publicly that I can also write Swift. (Honestly, though, a Swift app has been more trouble than it's worth, but that's a blog post for another day.) The crash was in the CFNetwork function NetService.dictionary(fromTXTRecord:), which corresponds to +[NSNetService dictionaryFromTXTRecordData:] in Objective-C. The crash report stated that the problem was "value type is not bridged to Objective-C".

My Twitter account has been locked again
25 Feb 2019 | original ↗

My Twitter account has been locked again. I don't even know what happened this time. It just seemed to happen randomly.

Finally credit from Apple Product Security
18 Feb 2019 | original ↗

Good news, everyone! I finally got proper credit from Apple Product Security for the Mojave privacy protections bypass that was fixed in macOS 10.14.1 back on October 30, 2018. The Apple support page describing the security content of macOS Mojave 10.14.1 was updated on February 15, 2019 with my new CVE-2018-4468.

Spying on Safari in Mojave
9 Feb 2019 | original ↗

At the end of this blog post I'll provide an update to yesterday's blog post, but first and more importantly I want to report a new hole that I just found in macOS Mojave's privacy protections. This hole exists in every version of Mojave, including macOS Mojave 10.14.3 Supplemental Update released on February 7.

Still no credit from Apple Product Security
8 Feb 2019 | original ↗

I found a bug in the new privacy protections of macOS 10.14.0, and that bug was fixed in macOS 10.14.1. I've already described the bug in a previous blog post. I support the requests for a Mac bug bounty program by security researchers such as Linuz Henze and Patrick Wardle, but I personally am not asking for a monetary bug bounty and never have asked for money in exchange for the bug report. (Though a bug bounty would be nice!) All I want is public credit for reporting the bug. To date, Apple Product Security has failed to credit me.

Stop Google Search Results Tracking
17 Jan 2019 | original ↗

Have you ever heard of The Old Switcheroo? Google pulls that magic trick when you click on a search result link. Below is what it looks like when you hover over a search result link in Safari with the ⌘ key pressed just before you click to open in a new tab. Pay particular attention to the status bar at the bottom:

StopTheMadness for Firefox
16 Jan 2019 | original ↗

The most requested feature for StopTheMadness has been Firefox support. Today, you got it! StopTheMadness in the Mac App Store now includes a Firefox extension. This is a free update for current owners of the Safari extension. And for new customers, StopTheMadness for Mac remains at the same (too) low price. That's 2 (two) browser extensions for the price of 1!

The Mac App Store Safari Extensions Experience
21 Dec 2018 | original ↗

Disclosure: As the developer of a (beloved, highly rated) Safari app extension, the contents of this blog post are relevant to my financial interests. (I'll write the obligatory Reddit/Hacker News comment in advance to save them the trouble: "Just a developer whining about Apple not featuring them more prominently. Why is this even news? Pointless." You're welcome!)

Text view adventures, Part 4
14 Dec 2018 | original ↗

This is my last scheduled text view adventure. There may be more, but they're unscheduled. And let's face it, the best adventures are unscheduled. So stay tuned, the best is yet to come. Or not. If you need to catch up on my previous adventures, you can read Part 1, Part 2, and Part 3. There will be a quiz at the end of the universe.

Text view adventures, Part 3
12 Dec 2018 | original ↗

Part 1 and Part 2 of my text view adventures were about NSTextView for Mac. Part 3 here and Part 4 in the future will be about UITextView for iOS. In Part 2 I wrote about how to handle pasting of arbitrary file types, including movies, into NSTextView. You might wonder how UITextView handles this. The answer is… not very well. On iOS 12, "Copy" is not even listed among the actions when you share a movie from Photos app. However, you can "Save to Files", and Files app will allow you to copy a movie file. If you want to allow users to save files "On My iPhone" in Files app, you need to add LSSupportsOpeningDocumentsInPlace and UIFileSharingEnabled to your app's Info.plist file.

Mac app notarization and customer privacy
6 Dec 2018 | original ↗

When you download a Mac app from outside the Mac App Store and launch the app for the first time, macOS checks whether the app was signed with a valid certificate from a developer registered with Apple's paid Developer ID program. The macOS technology responsible for this verification is called Gatekeeper. On macOS 10.14 Mojave, Gatekeeper added a step to the verification: in addition to checking whether an app was signed with a Developer ID certificate, it also checks whether the app was notarized by Apple. App notarization requires that a developer submit the app to Apple for an automated malware scan, and if no malware is found, Apple notarizes the app; the notarization status is stored on Apple's servers, and a notarization ticket can be "stapled" to the app by the developer so that Gatekeeper can see the notarization when the app is launched. Every version of an app must be notarized separately, the notarization does not carry over to later versions. Apple has provided some documentation of Mac app notarization for developers and for end users.

Text view adventures, Part 2
5 Dec 2018 | original ↗

In Part 1 of my multipart text view adventures, I wrote about an NSTextView memory management bug with attachments that could result in "zombie movies". Zombie movies are bad, m'kay. You don't want to see zombie movies. I explained how to make the zombies disappear, and I thought I killed the zombies, but later I realized that zombies are dead already, so killing them is fruitless. Who knew? It turns out that the zombies were merely in hiding, waiting to attack again. The only true way to avoid zombie movies is to never make them in the first place.

Text view adventures, Part 1
1 Dec 2018 | original ↗

I'm planning to write a series of blogs posts about my recent adventures with text views, i.e., NSTextView and UITextView. The current plan is 3 parts. However, if the box office receipts are high enough, I may continue to milk the franchise indefinitely. This post, Part 1, describes a bug in NSTextView and how to work around it.

Hardened Runtime and Sandboxing
16 Nov 2018 | original ↗

The relationship between the hardened runtime and sandboxing can be confusing to Mac developers, both because the hardened runtime is new and because it's not well documented by Apple. I'll attempt to explain the relationship here. App sandboxing was introduced in Mac OS X 10.7 Lion and eventually became a requirement for all Mac App Store apps, though developers can also choose to sandbox apps distributed outside the Mac App Store. The hardened runtime was introduced in macOS 10.14 Mojave and is currently optional for all apps, though it is required in order to notarize your app. Apple has announced that at some point in the future, all apps distributed outside the Mac App Store will need to be notarized, which means they will need to be "hardened" too. I suspect that Apple will eventually require Mac App Store apps to hardened as well. This may be surprising to developers, who associate sandboxing with the App Store and the hardened runtime with Developer ID, but the two technologies are independent of the distribution method and independent of each other, which means that a single app can be sandboxed and hardened.

macOS 10.14.1 Privacy: What's fixed and what's not
3 Nov 2018 | original ↗

This is a follow-up to my earlier blog post Another hole in Mojave privacy protection. Three days ago macOS 10.14.1 was released, the first software update to Mojave. Apple published a support document about the security content of macOS 10.14.1 on the same day. As of today, the support document does not mention the privacy protection bypass that I discovered and alluded to in my blog post. Nonetheless, macOS 10.14.1 does appear to fix the main issue, although there remain other avenues for bypassing Mojave's privacy protections under certain conditions. I'll discuss everything I know here.

Mac App Store Bundles
1 Nov 2018 | original ↗

On October 16, Apple announced that developers could start offering app bundles in the Mac App Store. App bundles have already been available in the iOS App Store for 4 years. After a relatively long road (not 4 years, but 2 weeks), my own StopTheMadness Underpass Bundle is finally available now in the Mac App Store on macOS 10.14 Mojave. This bundle includes my two Mac App Store apps StopTheMadness and Underpass at a discounted price. Moreover, if you've already purchased one of these apps, you can use Complete My Bundle to purchase the other app and still take advantage of the bundle price. Also, Underpass for iOS is available for free in the iOS App Store, so you can get all three of these apps for very little money! Hopefully I can make it up in volume…

Rickroll Resurrected
26 Oct 2018 | original ↗

I want to talk about a recent announcement by Twitter (and Square) CEO Jack Dorsey: https://twitter.com/jack/status/1017682342008238081. Go ahead and read it, I'll wait.

Mac Mail with Google 2-step and Yubico
16 Oct 2018 | original ↗

How to use Gmail in Mac Mail app with Google 2-step verification and Yubico Security Key.

Another hole in Mojave privacy protection
26 Sept 2018 | original ↗

On Monday, Apple released macOS 10.14 Mojave. One of the new features is supposed to be enhanced privacy protection for Mac users. However, holes that would allow malware to bypass this privacy protection have already been discovered by Patrick Wardle and SentinelOne. I've discovered a third. I emailed all of the details of my discovery to Apple product security on Monday evening. I'm publicly disclosing that I've found a privacy protection bypass, but I won't publicly disclose the details of that bypass now. I will disclose them at some point in the future, though I currently have no timeline for that. We'll see what Apple does. In the meantime, I'll offer a few points of clarification:

No cookie for you!
20 Sept 2018 | original ↗

Safari style sheet to block GDPR cookie dialogs.

Prevent App Nap Programmatically
22 Aug 2018 | original ↗

App Nap is a technology introduced in Mac OS X 10.9 Mavericks. Under certain conditions, such as when an app is not visible on the screen, App Nap automatically puts the app into low power state in order to extend battery life. This can cause problems if the app is performing time-sensitive tasks, which may get delayed or interrupted. Unfortunately, App Nap was designed as opt-out rather than opt-in, which means that App Nap can affect an app even if the developer didn't expect or plan for it. You can see apps going in and out of App Nap by watching the Energy tab in Activity Monitor.

Race to Under the Bottom
7 Aug 2018 | original ↗

Today I released Underpass version 1.0.4 for Mac and iOS, in the Mac App Store and iOS App Store respectively. I also lowered the price of Underpass for iOS to free. Free as in loss leader. This new price is intended to be permanent. As in marriage. 'Til divorce do us part.

Stop The Mad Icon
26 Jul 2018 | original ↗

Yesterday I released StopTheMadness version 4.0. Wow, I can't believe how much time has passed since version 1.0 shipped. It's been almost 3… months. In the beginning, this project had a shoestring budget. I ate shoestrings because I couldn't afford ramen. I'm not an artist — more of a standup philosopher — so when it came time to make the app icon, I had to come up with a "creative" solution. If all you have is Xcode, everything looks like code. Thus, I wrote an app to generate my app icon! (Sadly and ironically, the icon generating app still lacks an icon.) A little NSImageRep, a little NSGradient, a little NSBezierPath, a very little talent, and this was the result:

Ode to a MacBook Pro
12 Jul 2018 | original ↗

My main Mac is a 2014 15-inch retina MacBook Pro. It's a good machine. In some ways, it's superior to the 2018 MacBook Pro, and I have no plans in the foreseeable future to buy a new MacBook Pro. The 2014 model has a keyboard that is both quiet and reliable. It has function keys, including volume and brightness, which I use every day. It has a variety of useful ports, including MagSafe, HDMI, and USB-A, all of which I use regularly. (MagSafe has saved my MacBook Pro from harm on several occasions.) Yet the 2014 is not my favorite model ever. That honor goes to my late 2006 17-inch MacBook Pro. The "late" refers to the October introduction date; the machine itself is still functional. It mostly sits in a closet now, though I occasionally boot it up to print documents, because it runs an older version of Mac OS X with the drivers to support my old printer. In my opinion, the pre-unibody MacBook Pro was the best design ever. The difference is in the details that make this machine most friendly to customers.

NSOnState is deprecated
2 Jul 2018 | original ↗

The AppKit Release Notes for macOS 10.14 have finally been released. In the overview, we are told to pay special attention to the section "Swift and Objective-C API Enhancements":

Debugging on Mojave
11 Jun 2018 | original ↗

In March, Xcode 9.3 shipped with a strange new feature. The Xcode Release Notes miscategorized the feature under the "Server" section:

App Translocation and Safari App Extensions
21 May 2018 | original ↗

First, the good news: my Safari app extension StopTheMadness is now compatible with macOS 10.12 Sierra!

My Twitter account has been locked
16 May 2018 | original ↗

This morning my Twitter account was locked by an algorithm.

Stop The Madness
30 Apr 2018 | original ↗

Have you ever tried to copy some text from a web site, but the web site prevented it? Or the web site inserted an advertisement into the copied text? Has a web site ever prevented you from pasting text into an input field? Has a web site ever disabled password autocomplete, for your "security"? It's madness! But no longer. Today I'm releasing a new Safari app extension called StopTheMadness that stops web sites from messing with the standard Mac user interface features you love and depend on. StopTheMadness is available now in the Mac App Store.

A Record 13 Weeks
1 Feb 2018 | original ↗

Exactly a year ago I wrote a blog post about Apple's fiscal 2017 first quarter financial results. 2017 Q1 was unusual in that the quarter lasted 14 weeks, 1 week longer than most quarters. I argued that to compare 2017 Q1 with 2016 Q1, it was more useful to start with the weekly averages rather than the quarterly totals. Today Apple released its 2018 Q1 results, and the same concept applies again, because 2018 Q1 goes back to the standard 13 weeks. Here's a chart showing the year-year weekly averages:

A holiday gift
27 Dec 2017 | original ↗

Unless your eyes are really good, you can't see the individual pixels of an image. (How many RGB am I holding up?) For those of us with non-retina retinas, I've written a new open source command line tool called jixel to print detailed information about an image file, including the color values of every pixel. The "j" in jixel stands for … you should know by now. The source code for jixel is my gift to you this unspecified holiday season. The best gifts are homemade, aren't they? Especially when they're cheap. And I'm cheap.

Key difference between Dictionary and NSDictionary
4 Dec 2017 | original ↗

The recent article Strings in Swift 4 by Ole Begemann talked about how Swift String equality is implemented as Unicode canonical equivalence. As a result, two String instances can be equal even if they contain different Unicode code units. This behavior made me worried about my Swift project Bonjeff, a Mac app that shows you a live display of the Bonjour services published on your network, because Bonjour service names are UTF-8 strings. When I audited the equality checks in the source code, I discovered that Bonjour does not compare service names by Unicode canonical equivalence, and thus it's possible to publish multiple NetService instances with canonically equivalent names. Unfortunately, this revealed a bug where Bonjeff did not properly save the individual outline view disclosure states of Bonjour services with canonically equivalent names. The problem was that UserDefaults.standard.dictionary(forKey:) returns [String:Any]?. Since the dictionary uses Swift String keys, it cannot contain more than one value for canonically equivalent Unicode strings. Thus, multiple NetService instances with canonically equivalent names would fail to be distinguished.

The Mystery of the Phantom App Updates
24 Nov 2017 | original ↗

Starting on November 17, many iOS and tvOS apps that had not been updated for a year or two years suddenly received phantom updates in the App Store, without any action by the developers of those apps. The version numbers of the apps did not change. For some of the updates, the release notes were the same as the previous update. For others, the release notes said, "This update is signed with Apple's latest signing certificate. No new features are included." Some people speculated that Bitcode recompilation was performed on the apps. So far, Apple has not published any press release or documentation explaining why it updated all of these apps.

Working without a nib, Part 11: Why?
20 Oct 2017 | original ↗

My infinite part series "Working without a nib" — most recent part here — explains how you can work without a nib, but I haven't spent a lot of time explaining why you should work without a nib. That was left as an exercise for the reader. It turns out, however, that readers tend to be sitting down rather than exercising. They really need to get up and go outside more. (Later, of course, after reading this article.) While I did talk about the issue a bit on a podcast, I'm not sure many people caught that episode, so I've decided to elaborate for the first time in print. Please print out this web page.

Local variables are still free, in Swift
14 Oct 2017 | original ↗

This is part III of my very irregularly scheduled series on compiler optimization. In part II a few (eight) years ago, I explained how the compiler optimizes away local variables in your code. If you haven't read it, TL;DR read it! Apparently the article has achieved cult status, inspiring longtime fans to constantly recite quotations from memory. “An ordinary build spends its time avoiding tense situations. An optimized build spends its time getting into tense situations.”

Free as in app
9 Oct 2017 | original ↗

For analyzing and testing Bonjour services, I've always used the free Mac app Bonjour Browser by Kevin Ballard. However, the most recent update to Bonjour Browser was … 2006? It's amazing that an app so old still mostly works. There are a few bugs, such as the failure to resolve host names of Bonjour services, but the biggest issue is that the app download is rejected by Gatekeeper. Bonjour Browser predated Gatekeeper, which was added in 2012 to Mac OS X (which itself predated macOS), so the app is not codesigned with a Developer ID certificate. There are ways to allow the app to run on your Mac, but the situation is not ideal for distribution.

NSStringEncoding Considered Harmful
1 Sept 2017 | original ↗

It appears that [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding] never returns nil. I learned of this from Cédric Luthi. For instance, the following code unexpectedly returns an NSString with the copyright © symbol, which is non-ASCII:

Go all in with xcconfig
23 Aug 2017 | original ↗

Many Xcode projects are a mess. Just look at your project's build settings. Gross, right? The best way to clean up your build settings is to move them to xcconfig files. Move all of them to xcconfig files. My app Underpass has zero custom build settings in its project.pbxproj file. How is this achieved?

NSNotificationCenter is thread-safe NOT NOT
24 Jul 2017 | original ↗

Nostalgia is now the norm. (Norm!) Since nobody is expected to have original ideas anymore, I thought I would revisit an old blog post of mine: NSNotificationCenter is thread-safe NOT. That post discussed the thread safety of NSNotificationCenter and raised the problem of an object getting deallocated on one thread while it was observing a notification posted on another thread. I've decided it's important to follow up on my old blog post, because the problem it raised has been solved.

Working without a nib, Part 10: Mac Main Menu
29 Jun 2017 | original ↗

Welcome to part 10 of my infinite part series "Working without a nib". You can find part 9 here, and you can find the rest of the parts over there yonder in your favorite search engine. During my (semi-)recent podcast episode, I talked about building an app without a nib. People seem to be especially interested in how you create the main menu of a Mac app without a nib (or xib, or storyboard). Many years ago I posted a sample nibless application on my old blog, but since then … much has changed. Given the renewed interest, I've decided to post a brand new sample application. You can download the Xcode project now. I call the app "High Nibless". No, seriously, it's "NiblessMenu".

I was on a podcast
27 Jun 2017 | original ↗

I was on podcast! I talked about the making of my app Underpass, including topics such as Objective-C vs. Swift and nibs/xibs/storyboards vs. code. You can listen or download the episode at Underpass with Jeff Johnson.

Porting Objective-C to Swift
19 Jun 2017 | original ↗

Objective-C and Swift are said to be interoperable. You can add Swift files to Objective-C projects and vice versa. If you want to port a large Objective-C project to Swift, the sensible way would be piecemeal, file by file. It is well known that rewriting an app from scratch is fraught with peril, and incremental refactoring almost always produces better results. This topic has been discussed extensively elsewhere, so I won't elaborate on it here. I'm just going to talk about the technicalities of porting Objective-C files to Swift.

Problems with Objective-C annotations
15 Apr 2017 | original ↗

In recent years, the clang compiler has added a number of source annotations to Objective-C in order to clarify API intent. For example, NS_DESIGNATED_INITIALIZER formalizes the traditional Objective-C designated initializer pattern. To facilitate interoperability with Swift, Objective-C adopted nullibility annotations: nullable, _Nullable, nonnull, _Nonnull. As with all changes, however, there are tradeoffs. The use of these annotations comes with a price. Consider the following (dummy) code illustrating the designated initializer pattern (and nothing else):

Not just the Mac Pro
4 Apr 2017 | original ↗

I'm sure you've read this morning's news about the Mac Pro. Apple finally admitted what everyone else knew all along: attempting to cram the highest performance professional machine into a diminutive cylinder was a mistake. The real problem, however, is that the Mac Pro is not the real problem. The real problem is the Mac, and the Mac Pro is just one (too) small illustration of the problem. For a larger illustration of the problem, look at the MacRumors Buyer's Guide for the Mac:

Twitter only mutes 100 keywords
2 Apr 2017 | original ↗

This is not a joke. I wish it were. The Twitter topic du jour has been the new eggless default profile photo, and that change was indeed dumb and pointless, but I want to talk another change that has been rolling out over the past few months: keyword muting. Initially, I was thrilled to finally receive this new feature, which had great potential. However, weeks of usage turned my thrill to disappointment. The last straw was when I ran into this today:

Autoresizing UITextView
28 Feb 2017 | original ↗

My recent blog posts have been more business-y than programmer-y, so today we're going to bring back that codin' feelin'. With a twist, since I'm going to talk about iOS, which is blasphemy in these parts, but don't shout. I'm writing an iOS version of Underpass, and I needed a UITextView that automatically resizes vertically like in Messages. Searching the web reveals that, give or take, a million other developers want this too. Unfortunately, Apple does not provide an API for the behavior, instead forcing developers to figure it out for themselves. As a result, a million developers have produced a million subtly different implementations. The paradox of choice is that I couldn't choose one. To stave off death from both hunger and thirst, I decided to write my own millionth and one implementation.

Follow-up on a Record 14 Weeks
4 Feb 2017 | original ↗

This is a follow-up on my recent articles A Record 14 Weeks and Slow Week? I'll talk about several points:

Slow Week?
3 Feb 2017 | original ↗

Yesterday I wrote an article about a fact that has been widely overlooked: Apple's FY2017 Q1 was 14 weeks long rather than the usual 13 weeks. Some people have noted this fact, but there has been an effort to explain it away as a "slow week".

Whither Swift?
1 Feb 2017 | original ↗

I've been asking myself the question, what is Apple's plan for Swift and Objective-C? When Swift became public in 2014, its creator Chris Lattner seemed to claim that Swift and Objective-C would coexist indefinitely. From an xcode-users mailing list post:

A Record 14 Weeks
1 Feb 2017 | original ↗

Yesterday, Apple posted its fiscal 2017 first quarter financial results. Let's look at the raw numbers, comparing with Q1 2016 for year/year changes. (Units are in thousands, revenue is in millions of dollars.)

70 Cents Put Me on the Mac App Store Charts
31 Jan 2017 | original ↗

Disclaimer: The purpose of this post is not to complain about my sales. You can question my strategy, my acumen, my sanity, and those questions may be valid. However, if you take it upon yourself to publicly rip on one poor indie developer, then you are a malicious, pathetic troll who needs to take a hard look at yourself while trying to choke back the vomit. There's no lower scum of the earth than someone who would step on another person when they're down. You have this in writing, and you can quote it back at any villain who ignores my disclaimer. The purpose of this post is to illustrate by example a shortcoming of the Mac App Store top charts.

Working without a nib, Part 9: Shipping without a nib
25 Jan 2017 | original ↗

This blog post is short but sweet. It answers the age-old question (if your age is 6 years old): can you ship an app in the Mac App Store without a nib? In a recent blog post I talked about making a nibless app with ARC on the latest (the only) version of macOS. In an even more recent blog post I talked about releasing Underpass, my new Mac app. Until now, though, I hadn't connected the two.

Inaugurating Underpass
18 Jan 2017 | original ↗

In my last blog post, I preannounced my new Mac app. Today, I'm pleased to postannounce my new Mac app! It's called Underpass, and it's for sale exclusively in the Mac App Store. Underpass should be available now worldwide. I started 20 weeks ago with only an idea and an empty Xcode project, so it's thrilling and satisfying to have an app for sale today.

Preannouncement
12 Dec 2016 | original ↗

If the AirPods situation has taught us anything, it's that you should never preannounce products. Or since Apple is nonetheless the most profitable company on Earth, maybe it has taught us to preannounce everything and ignore the consequences. Therefore, today I'm going to preannounce a product! It may even ship before the AirPods.

Textured Tabbed Windows
5 Dec 2016 | original ↗

I didn't want to begin a paragraph, much less a whole article, with a lowercase character, so this is an unnecessary lead-in to what I originally wanted to say: macOS 10.12 Sierra has introduced a new feature called automatic window tabbing. Apple's SOP nowadays is to make new mac features — err, Mac features — opt-out rather than opt-in. Thus, automatic window tabbing is supposed to Just Work.™ In other words, it almost just works. I discovered through the magic of git-bisect that automatic window tabbing does not work when you programmatically create a textured window. The main menu items "Show Tab Bar", "Merge All Windows", etc., are never enabled for the window. Textured windows, which do not have a toolbar at all (or from another perspective, have toolbar all the way down), are specified by the style mask NSTexturedBackgroundWindowMask. Rather, they were specified by NSTexturedBackgroundWindowMask until that was deprecated in favor of NSWindowStyleMaskTexturedBackground, because why not.

We don't need no stinking badges
31 Oct 2016 | original ↗

This is a follow-up to How to Badge an App’s Icon in the Dock by Matthias Gansrigler, or as he's known in the developer community, "Rig". I want to thank Rig for helping me to solve a problem with NSUserNotification. My app posts notifications to Notification Center using -[NSUserNotificationCenter deliverNotification:], and this worked fine for alerts and sounds, but I couldn't figure out how to handle the "Badge app icon" setting in System Preferences, Notifications. The documentation for NSUserNotification is sparse and implies that Notification Center handles everything automatically. The reality is that developers need to do almost everything themselves. Rig's blog post talked about an app that only shows a Dock badge, so I want to expand on that to talk about an app that shows alerts and plays sounds in addition to badging the Dock icon. Here's the code that I use to show an "unread" count:

Working without a nib, Part 8: The nib awakens
17 Oct 2016 | original ↗

Reboots are de rigueur these days, so I've decided to reboot my series "Working without a nib". Four score and minus seventy-two years ago, I brought forth on this internet a new blog post, conceived in levity, and dedicated to the proposition that no nibs are created. Since then, much has changed in the Mac world. Except of course the Macs themselves, which haven't been updated in a long time. Fortunately, the source code in my Nibless 2.0 project still works on the latest version of Mac OS X. (I hear some murmuring in the audience.) The use of the undocumented method setAppleMenu: has become redundant and unnecessary (or is it the other way around?) starting with Mac OS X 10.6 Snow Leopard (AKA the last good version). From the AppKit release notes:

Translocate Relocated
7 Oct 2016 | original ↗

In an earlier post I mentioned that the API had been removed from the 10.12 SDK in Xcode 8. However, yesterday I stumbled upon a different place where a kind of API for App Translocation still exists in macOS 10.12 Sierra: the security command-line tool. It's not in the man page, so don't bother to RTFM, but you will find it at the end of the usage information, when you simply type security into Terminal:

Distributing Outside the Mac App Store
7 Oct 2016 | original ↗

It is said that distributing apps outside the Mac App Store is safe from meddling by Apple, because they cannot impose arbitrary rules on you or remove your apps from sale. That is true, to an extent. However, the potential still exists for Apple to put you out of business, for all practical purposes. The power to do this resides in Gatekeeper. When a user downloads your app and launches it, Gatekeeper won't allow the app to run unless it was signed by a valid Developer ID certificate. There are ways to bypass Gatekeeper, so the Mac is not completely locked down like iOS, but Gatekeeper does present a seemingly impassable barrier to the average user, so without a valid Developer ID certificate, you are unlikely to be able to sell many copies of your app.

Caveat Formatter
26 Sept 2016 | original ↗

NSFormatter is intended for subclassing. You know what they say, the road to Radar is paved with good intentions. A formatter is particularly useful if you need to restrict input to a text field as the user types. Below I've written a sample NSFormatter subclass that accepts only decimal digits. For the sake of brevity, I've provided simplistic implementations of the required -getObjectValue:forString:errorDescription: and -stringForObjectValue: overrides; depending on your needs, you may want NSNumber as the object instead of NSString. The purpose of this blog post is to point out a caveat with validating partial strings, so let's focus on the final method, which I'll call -isPartialStringValid: for short, because the full method signature is overly long. Also known as "Part-y" among good friends, this method isn't one of those who whine when you give them a nickname.

Symmetric Encryption
25 Sept 2016 | original ↗

I mentioned before that the SecTransform API can be confusing. Needless to say, that is still true. Today I'm offering you a second lesson. For free. Free as in, you are required to stand and salute whenever you see me.

Keychain Sync
18 Sept 2016 | original ↗

I just bought an iPhone 7, and I wanted to sync my Mail and Twitter accounts from my Mac. There used to be an option in iTunes to sync Mail accounts with your iOS device, but that option has been removed, unfortunately. So, what's the new "solution" for this problem? As far as I can tell, Apple now forces you to manually set up all Mail and Twitter accounts on your iOS devices. The account setup process is not particuarly complex, and you can follow your Mac settings as a guide. However, it can be a chore to type in passwords on your iPhone, especially if you follow the best practice of generating long, random passwords containing special characters. I wanted some way to get my passwords from my Mac onto my iPhone, and iTunes sync no longer works. The natural fallback solution is to use a password manager.

MIA: SecTranslocate
17 Aug 2016 | original ↗

I guess I'm the App Translocation Dude. So be it. That makes me a "C" celebrity, and gets me into all the cool hackathons.

Detect App Translocation Without the 10.12 SDK
26 Jul 2016 | original ↗

As I mentioned in an earlier blog post, there's a new API for App Translocation in the 10.12 SDK: . However, if you're sane, you're not shipping your apps yet with the 10.12 SDK. So how can you detect App Translocation in your shipping apps? The trick is that since you can't link against the new functions, you have to load them at runtime. I've provided sample code below.

Trust
30 Jun 2016 | original ↗

This is a follow-up to my guest post on the company blog. My employer graciously gave me the credit — or made me the fall guy — but it was truly a collaborative effort, and any grammatical errors are theirs.

In Memoriam
18 Jun 2016 | original ↗

Functions that we lost this year:

Undo
16 Jun 2016 | original ↗

Yesterday I found a flaw in the new "feature" App Translocation, AKA Gatekeeper Path Randomization. (One could even call it a "protection racket", because you either pay a percentage to be in the crap store, or Apple breaks your software updater.) Today I found another flaw. You know what they say, you've seen one, you've seen them all. (They, circa 20th century, Hearsay Publications Inc.)

Zero Day?
16 Jun 2016 | original ↗

Yesterday I wrote about App Translocation. Then yesterday evening I had a chance to watch the "What's New in Security?" WWDC session, and it filled in some details. What I call "App Translocation", Apple calls "Gatekeeper Path Randomization". I'm going to continue to call it "App Translocation", though, because that's shorter, and "Translocation" is a cool-sounding word. As usual, the Mac "news" media who reported on this got it wrong. They completely misunderstood the behavior. For all the news that's fit to print, just follow my blog.

App Translocation
14 Jun 2016 | original ↗

I was looking through the misnamed "What's New in OS X" document, and something caught my eye under "Security and Privacy Enhancements":

What's Wrong With Twitter
18 Apr 2016 | original ↗

They say you can't go home again. (They being my parents.) In 2012 I famously quit Twitter, because they dropped support for RSS. Recently, though, I experimented with rejoining Twitter. They haven't restored RSS, but I did become somewhat nostalgic in the meantime. As with most nostalgia, it resulted in disappointment. After a few months, I've ended my experiment, and I declare it an utter failure. Twitter continues to be the worst. Even worse than before.

SecTransformExecuteAsync Considered Confusing
29 Dec 2015 | original ↗

According to the API for SecTransformExecuteAsync (which I won't link to because Apple will inevitably break the URL):

The OpenSSL Blues
3 Oct 2015 | original ↗

Apple deprecated OpenSSL in Mac OS X 10.7. So, #pragma clang diagnostic ignored "-Wdeprecated-declarations". Problem solved, right? With the Mac OS X 10.11 SDK, however, Apple took one more step — or giant leap — of removing the OpenSSL headers entirely. New problem.

Checking for El Capitan
2 Aug 2015 | original ↗

Sometimes your app needs to check the Mac OS X version at runtime in order to handle a runtime behavior change in OS X that isn't already handled automatically by the Cocoa API. One standard and Apple-recommended method of checking the runtime version is via NSAppKitVersionNumber. There are constants defined in corresponding to each major OS X version update, as well as a number of minor version updates. For example, this is from the OS X 10.10 SDK:

Validate Project Settings: Never!
3 Apr 2015 | original ↗

Have you ever seen this in Xcode?

Lack of Communication
23 Sept 2014 | original ↗

As I noted in a previous article, Mac OS X 10.9.5 included the biggest change to Gatekeeper since the introduction of Gatekeeper. This was documented, for developers, in a technical note. Unfortunately, it doesn't appear to be documented at all for users. There's nothing mentioned about Gatekeeper on the download page, or the details page, or even on the security content page. But at least we developers knew it was coming. And to some extent, the Mac media helped to publicize it to users in a way that Apple did not.

Breaking the resource rules
5 Aug 2014 | original ↗

Read it and weep: Changes in OS X 10.9.5 and Yosemite Developer Preview 5. Needless to say, this is the biggest change to Gatekeeper since the introduction of Gatekeeper. It's essentially Gatekeeper 2.

NSNotificationCenter is thread-safe NOT
21 Apr 2014 | original ↗

According to Apple's Threading Programming Guide, NSNotificationCenter is a thread-safe class. "You can use the same instance from multiple threads without first acquiring a lock." However, this is extremely misleading. In fact, if your app has multiple threads, then you're almost certainly using NSNotificationCenter wrong. Almost everyone makes the same mistake:

Cancel WWDC
13 Apr 2014 | original ↗

I believe that WWDC should be canceled. And I'm not just saying that because I lost the lottery. Actually, I didn't even want to go; I registered for the WWDC ticket lottery only to maximize my company's chances at getting a ticket. (We didn't get one. 0 for 7, with 7 strikeouts.) I'm not proposing that it be canceled this year, because a lot of attendees have already bought non-refundable plane tickets, but I am suggesting that this should be the final year of WWDC. I think WWDC should be discontinued, permanently.

Dispatch Queues and Run Loop Modes
7 Apr 2014 | original ↗

Have you ever wondered which run loop modes a block will execute in if you submit the block for asynchronous execution on the main queue? Apparently, not many people have wondered this. (That's why you have me.) And of course, it's not documented by Apple. (That's why you have … me.)

Mark Not All as Read
6 Apr 2014 | original ↗

Recently Brent Simmons talked about marking all items as read in your feed reader. This is a solution to falling behind and having too many unread items. For me, as a user, the problem with this strategy is that there are certain feeds that I never want to miss. For example, there are developer blogs that only post items a few times a year. Do you want to go on vacation for a week, fall behind on reading your subscribed feeds, and then miss one of those rare posts because you had to declare "unread bankruptcy" and mark all as read? More important, there are feeds that I use for work. We have a feed of commits to the repository, and I never want to just ignore those.

Winter is Coming
5 Apr 2014 | original ↗

The legends speak of a man — more animal than man, really — who descended upon the web from the far north, slaying all in his path with powerful blog posts. Eventually, however, the n00bie iOS developers rose up and drove him away. They say that he has been slumbering for years, waiting for people to forget him, for complacency to set in, for the right season to return and wreak his vengeance.

The Definitive Guide to Installing Xcode 3 on Mountain Lion (Without Kernel Panics)
5 May 2013 | original ↗

Wow, two articles in two days. Don't expect this to become a habit.

SDK vs. Deployment Target
5 May 2013 | original ↗

I used to have a WordPress blog. I no longer update that blog, because it became a PITA to constantly update WordPress. Also, my desire to help people waned after the infiltration of our little Mac community by the horde of iOS developers. No offense. Well, not much offense. Nonetheless, I occasionally have something helpful to say to people. So, I'm just going to write a self-contained article here, with no promise of any future articles. I'm so serious about no promises that I'm not even setting up an RSS feed for articles, and if you know me, that's telling.

↑ These items are from RSS. Visit the blog itself at https://lapcatsoftware.com/articles/atom.xml to find everything else and to appreciate author's digital home.