An Alerting Vista of Sonoma

There’s a new “feature” in Sonoma, and no one besides Apple is quite sure what it is.

Alerts for deprecated APIs are now appearing frequently. Sometimes when you launch an app, and sometimes at random. Here are three I got the other day after waking a MacBook from sleep:

Mysterious Alerts.

From a UI point-of-view, these alerts have serious issues:

  • They are scary and not actionable.
  • The only unique information is the title. The name, however, is not something I recognize.
  • I know what a deprecated API is and how its removal can be a bad thing, but ordinary users won’t.
  • There is no mention of what API caused the alert.
  • I’m advised to contact the developer for an updated version, but there is no information on who that developer is. (In the screenshot above, I’m assuming the developer is Apple itself, so I notified them with FB12560773, FB12560774, FB12560776).

But the UI is just the beginning of the fun. Once the developer is notified, the lack of information for this “feature” prevents the deprecation from being addressed.

This alert is mentioned in the release notes for the first beta for Sonoma. The brevity of that note is surprising for such a prominent and important addition to macOS.

I suspect that the brevity of the alert’s text is to shield the customer from unfamiliar terminology and complexity. It’s like a check engine light in your car: it comes on and you know to get to a mechanic ASAP.

When you get to the mechanic, they have diagnostic tools that let them understand what’s wrong (the engine control unit will typically store a unique code).

The difference with this “feature” is that folks like me are the mechanics and we have no diagnostic code. Supposedly, this alert should only appear with the use of ATS or ATSUI (per the release notes), but I find it hard to believe that modern system framework components shown above are using Apple Type Services that were replaced 13 years ago. But maybe they are – we all embed frameworks into our apps, some where we have source code, others where we do not.

The alerts also have another hideous “feature”. They turn themselves off as soon as you hit the OK button. They never repeat, so it’s impossible to bisect the code to find and verify a fix.

It’s like having your check engine like go off the next time you start the car, and the diagnostic code being removed by the time you get to the repair shop. A developer’s reaction to these reports will be the same as your local mechanic: “I don’t know what’s wrong. Good luck.”

If Apple wants developers to repair these deprecations they need to make major changes:

  • Document the behavior, including all of the APIs that trigger it.
  • Tell developers if this is something that will only appear in the beta or if it will be a part of the final release.
  • Give the customer something to work with when communicating with the developer. A diagnostic code at a minimum.
  • Log information about what caused the issue: remember that it may not be the developer’s own code triggering the alert. Plugins, embedded libraries, and external frameworks should be a part of the log. These logs should be available to customers so they can provide them to developers.
  • Give developers a way to reset the alerts. Make fixes testable.

Without these changes a Mac user’s future is one with a lot of crashes caused by deprecated code.

NOTE: This blog post has been submitted as feedback. If you find this situation intolerable, please submit a duplicate titled “Mysterious deprecation alerts in Sonoma” with a reference to FB12560999 and a link to this blog post.

Announcing Blank

I’m happy to announce the release of a new tvOS app called Blank. It turns your screen black and keeps it that way until you press any button on a remote. Seriously, that’s all it does. Here’s the screen you see when you launch the app for the first time:

That second paragraph hints at why this is important, despite the app’s simplicity.

Sleeping Well

As you get older, a good night’s sleep becomes harder to achieve. One thing that works well for my wife and me is to lower light levels before bedtime.

There has been scientific evidence of this since early in the last decade. Bright light can change your circadian rhythm and affect melatonin production, which can “potentially impact sleep, thermoregulation, blood pressure, and glucose homeostasis.”.

A big ass screen in the living room makes this hard to achieve. If you want to listen to music or a podcast before going to bed, it’s impossible to avoid a bright now playing screen or animated screen saver.

So I wrote Blank as a way to address this problem. Of course, it’s FREE so people besides me and my wife can benefit from it.

New & Improved

The first version I submitted didn’t meet Guideline 4.2 for “Design – Minimum Functionality”. Understandable, because this app was basically the “anti-flashlight” and we all know how that played out.

I took this initial rejection in stride and started working on an update that added some minimal functionality.

When you launch the app, or press any button on the remote, you get a screen with an inspirational quote. After you’ve had time to read it, the message disappears, and the screen goes black. It’s a nice addition and folks who are using the app love it.

I’m glad I did this extra work, and it’s a case where App Review helps a developer improve their product. Here’s what the quote screen looks like:

After some back-and-forth with App Review, the app was approved with these changes. Yay!

But That’s Not All!

An additional benefit became apparent after we started using Blank: it significantly lowers the energy consumption of the screen.

All modern TVs have circuits that detect a blank signal and turn off LEDs to reduce the power required by the device. If you’ve ever felt heat coming off your big screen, Blank makes that go away.

So besides improving your sleep, you’re also helping out our ever warming planet.

There Is None More Black

So there you have it: another addition to our ever growing list of “little apps”. Just open up the App Store on your Apple TV, search for Blank, and click to download the app for FREE.

Simple, beautiful, classic. Enjoy!

The Shit Show

Well, it happened.

We knew it was coming.

A prick pulled the plug. And what bothers me most about it is how Phony Stark did it.

My mom passed away just before Christmas. Her decline was something everyone in the family saw coming and we prepared for her demise. It still hurts like hell, but she left with love and dignity. That makes all the difference when it comes to coping with loss.

Twitterrific is something that we’ve all poured our love into for the past 16 years. I’m not usually one to toot my own horn, but we literally crafted the early experience on the service. We often hear that folks joined up because of our app. Our work was definitive and groundbreaking. We loved this app like I loved my mom.

(Note today’s date and the one on our announcement – the fuckwads missed our 16th anniversary by a couple of days! King Shithead probably thought Friday the 13th was lol. I’d love some proof that the API went down at 04:20 in UTC +1.)

Like my mom, the API has been declining for awhile. Endpoints were removed, new features were unavailable to third parties, and rate limiting restricted what we could do. And like my mom, we struggled on and did the best we could, trying to stay upbeat about it all.

What bothers me about Twitterrific’s final day is that it was not dignified. There was no advance notice for its creators, customers just got a weird error, and no one is explaining what’s going on. We had no chance to thank customers who have been with us for over a decade. Instead, it’s just another scene in their ongoing shit show.

But I guess that’s what you should expect from a shitty person.

Personally, I’m done. And with a vengeance.

First, arrogant bastards love seeing their names on tweets and other media. I want to starve him of the things that money can’t buy: respect and attention. Do the same by simply ignoring him and his kingdom.

Secondly, for the past several months I’ve been thinking about where we go from here. When you see decline, you plan for a demise. It was the last thing mom taught me.

I’ve been active on Mastodon since the billionaire bozo took over. And it makes me think.

One thing I’ve noticed is that everyone is going to great lengths to make something that replaces the clients we’ve known for years. That’s an excellent goal that eases a transition in the short-term, but ignores how a new open standard (ActivityPub) can be leveraged in new and different ways.

Federation exposes a lot of different data sources that you’d want to follow. Not all of these sources will be Mastodon instances: you may want to stay up-to-date with someone’s Micro.blog, or maybe another person’s Tumblr, or someone else’s photo feed. There are many apps and servers for you to choose from.

It feels like the time is right for a truly universal timeline. That notion excites me like the first time I posted XML status to an endpoint.

One thing I remember from these early days: no one had any idea what they were doing. It was all new and things like @screen_name,  #hashtags, or RT hadn’t been invented yet. Heck, we didn’t even call them “tweets” or use a bird icon at first! The best ideas came from people using the service: all of the things mentioned above grew organically from a need.

That’s where I want to be in the future. Exploring unknown territory that empowers others and adapts to the needs of a community.

There’s no sense in clinging to the personal whims of a clown leading a shit show. Especially when his circus will end up being a $44 billion version of MySpace.

SimBuddy – Your Simulator’s BFF

Have you ever added code like this to your app?

print(Bundle.main.resourcePath!)
print(FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.path)

Or maybe you’ve been frustrated that you can’t add that code because you’re in the middle of debugging?

Yeah, me too. Many times.

The locations shown above, and many others, are available from Xcode using the xcrun simctl command. Every application on every device on every platform can be queried. But these lookups are difficult for developers because the information is structured around automatically generated GUIDs. The GUID you’re looking for changes every time a new OS is available, a device is added, or an application is installed. And we do that a lot!

There are other tools available to help you navigate the Simulator, but they all do much more than I really need and take up space in my menu bar even though they are used infrequently. Additionally, none of these tools help find the “On My iPhone/iPad” container used by the Files app: a folder that I use whenever I’m testing import and export code.

By now, you probably know where this is going: yes, I wrote my own utility and call it SimBuddy. It’s a FREE download from the Iconfactory.

A screenshot of SimBuddy's UI showing device and app selections, information about the app, and buttons to open the bundle, data, documents, preferences, and local files for the app.

SimBuddy uses two popup menus for navigation: the top one shows which devices are running in the Simulator and the one below shows all the applications installed on that device (your apps are listed first). Once you make a choice with those popups, you can use the buttons at the bottom of the window to navigate in the Finder. If you are using app group containers for sharing information between an extension/widget and your main app, you open those folders by selecting the ID and using “Open”.

If the Terminal is more your thing, you can hold down the option key while clicking a button and a path to the folder is put on the clipboard. Paste that into a command line and away you go!

It’s not a complicated app, as you can see from the source code, but it’s one that I’m very happy to have in my developer toolbox now. I hope you enjoy it, too!

P.S. I love putting Easter eggs in apps. This time it’s in the app icon.

Managing Xcode Downloads

Beginning with Xcode 14, the Simulators for watchOS and tvOS are available as separate downloads (iOS and macOS are still “built-in”). This reduces the app download size significantly, but it also means that you now have to manage these large (3-4 GB) components yourself.

When you launch Xcode 14 the first time, you are prompted to download additional platforms. Another prompt is displayed when you try to run a target for a platform without a runtime.

But what are these downloads and where are they stored?

The first hint is when you look at Disk Utility. You’ll see a bunch of new “Simulator” volumes mounted under Disk Images:

Disk Utility showing four Simulator runtimes.

When you select these volumes, you’ll see that they all mount at /Library/Developer/CoreSimulator/Volumes. Within each volume you’ll find a legal PDF and a path to a .simruntime package in a Runtimes directory. This structure is the same as additional iOS runtimes in /Library/Developer/CoreSimulator/Profile/Runtimes. These .simruntime packages contain all the information needed to simulate the device.

Now that you know what Xcode is using, you’ll wonder where it’s getting the disk image. It’s located in a sibling directory: /Library/Developer/CoreSimulator/Images. That folder also contains an images.plist file that contains metadata for the disk images. There are only a handful of files there, but on my Mac they use 13 GB of disk space.

And up until a couple of hours ago, that folder contained 7 GB of data that was incompatible with the current version of Xcode. I had to delete these files manually. But how?

The simplest way to manage this space is using the new Platforms panel in Xcode preferences:

Xcode settings showing all built-in and downloaded Simulator runtimes.

This window also shows when you last used the runtime: in the screenshot above it’s clear that I can get rid of the iOS 14 and tvOS 16.0 runtimes and save about 25 GB of storage. It’s easy to get those runtimes back if needed, just press the + button. (After downloading a new runtime, it can be used in the Devices & Simulator windows to create a new test device.)

If the command line is more your thing, you can use xcrun to gather the same information:

$ xcrun simctl runtime list

Add a -v option there if you want more details (from the images.plist mentioned above). To delete any one of the items listed, use the listed GUID in this command:

$ xcrun simctl runtime delete <GUID>

In the end, this short post saved me 32 GB of disk space. If you’re developing for platforms other than the current iOS, you’ll likely see something similar. As time passes, you’ll need to manually keep an eye on this stuff: Xcode can’t clean things up for you because it has no idea what you need.

For additional details, check out Apple’s documentation for installing and managing Simulator runtimes. Thanks go to Jason Yao for helping me figure out a bunch of this stuff!