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.
Moreover, Safari will never stop "helping". You can't tell Safari to just STFU about the Twitter app. Fortunately for you, I will never stop helping either. As the author of StopTheMadness and StopTheNews, I'm your one stop shop for Safari problems, and as usual, I have a solution here. I hadn't investigated this problem until recently, because I'm still using Mojave as my primary macOS version, but I'm always willing to help out friends and customers. Especially friends who are customers, my best friends!
First, some technical details. The annoying Safari prompt is part of a system that Apple calls "Universal Links". The way it works is that an app embeds information in its Info.plist
file and in its code signing entitlements indicating to macOS or iOS that the app supports Universal Links. The app developer must also add an "Apple App Site Association File" on its web site at a specified location. In the case of Twitter, it's https://twitter.com/.well-known/apple-app-site-association. Both of those pieces must be in place if Universal Links are to "work".
As far as I could find, there's no hidden preference (defaults write) to stop Safari from checking for Universal Links. Safari does what it wants, and you don't get a choice in the matter. After spelunking the system frameworks came up empty, I decided next to try a Safari content blocker to prevent Safari from loading the Apple App Site Association File. (PROTIP for developers: You need to double-escape regex in JSON.) Unfortunately, the content blocker was fruitless too. I could prevent https://twitter.com/.well-known/apple-app-site-association from getting loaded in web pages, but apparently Safari loads that file directly for the purpose of Universal Links, bypassing the standard web loading process that includes content blockers.
My final, "insanely devious" idea (as someone called it) was to create a fake Twitter app. When there are multiple apps installed on your Mac with the same bundle identifier, macOS tends to prefer the one with the highest version number. So I opened a new Mac app project in Xcode and gave it the bundle identifier maccatalyst.com.atebits.Tweetie2
, matching the real Twitter app. I gave the new app the bundle version 1000.0.0
, which was arbitrary but likely higher than anything you'll ever see in the real Twitter app, currently at version 8.18.1
. And I added an AppIdentifierPrefix
key with the string "8248RGMF2D.
" to the new app's Info.plist
file, again matching the real Twitter app. The critical difference between the real Twitter app and the fake Twitter app is that I did not add com.apple.developer.associated-domains
to the fake app's entitlements. The associated domains in the real Twitter's entitlements indicates that it supports Universal Links (applinks
). You can see its entitlements with the command codesign --display --entitlements - /Applications/Twitter.app in Terminal. My theory was that Safari would hopefully look at the fake app with the higher version number instead of the real app with the lower version number, and decide that Twitter did not actually support Universal Links.
It appears that my theory was correct! You can download my new app StopTheTwitter, which is notarized for macOS Catalina. Move the app into the /Applications
folder (or whatever the directory actually is now in Catalina's weird dual volume system), and launch the app to register it with Launch Services. You may need to log out and log in again to ensure everything is set. Hopefully the "Open in the Twitter app" prompt in Safari is gone for good!
One caveat: When the real Twitter app is not open, the fake app receives push notifications from Twitter, but the fake app doesn't have any knowledge or access to Twitter API, so it can't handle the notification actions. If you do anything other than close a Twitter push notification, then the fake app simply opens the real Twitter app and quits. Fortunately, when the real Twitter app is open, it handles push notifications itself.
It turns out that StopTheTwitter also removes the extraneous "Open Link" items at the top of the Safari contextual menu when you open it on a Twitter link!