Tapestry: What About?

On Mastodon, Alex Chaffee points out some of Tapestry’s shortcomings. These are all valid concerns and I’ll deal them individually here (rather than with a long toot thread).

iOS-only

Building for iOS first is a strategic choice. There is a lot of work to do here, and many new concepts that need to be designed and developed, so we’re picking our battles carefully.

Personally, I’d prefer to do a macOS client first, but iOS is a choice that makes the product available to as many folks as possible.

We also get asked a lot about supporting Android and that’s something, like macOS, that we will look at after we have a strong footing with this new concept.

But what about the web?

Another platform we get asked about frequently: can Tapestry be a web app? We covered this in a FAQ, but I’d like to add a little more detail here.

The only way a web app could be done is if there’s a server to marshal requests to the various services. Since we want the privacy and independence of a device-only design, that option is off the table.

If you’re working in a single browser window as a web app, you put all of your code into a single secure JavaScript context. That’s not a problem, but any code you pull in will need things to communicate with all of the services, and in most cases that will leak private authentication data like OAuth/JWT keys and tokens. All it takes is one malicious plug-in to make your life hell.

The root of the problem is that Tapestry’s fundamental design is different than a web browser. The easiest way to think about: it’s an app that asks a bunch of browser tabs if they have anything new to show. Each tab is secure and none of them know what the others are doing. The results that each tab provides are aggregated and displayed to the user.

This design is wholly different from the web we’ve known, but is just as flexible and adaptable. Building a new thing for the community of the open web is what excites me most about this project. Giving folks tools to be creative is what the web has always been about.

Closed source

Right now, the core of Tapestry is closed source. We have put some components up on GitHub and are also fully documenting an open API to that proprietary core. Teaching is a part of that openness.

Again, we are in the very early days of this project and have no idea where things will head. It’s like if you had asked me in 2006 if a shithead would be running the show in 2024.

I think it’s important to think about how Netscape Navigator was a proprietary product until Mozilla happened. Establishing a new idea is a first step; letting it flourish is another.

All I can say at this point is that I’m fully committed to letting this idea flourish.

Scraping

There is no such thing as a proper web scraper for authenticated content. It’s a cat-and-mouse game where the scrapee wins in the end. We have every reason to believe that Facebook or Instagram will go to great lengths to protect “their” data.

On the other hand, if you want to get standardized information from a page, such as OpenGraph, that’s already something we’re doing.

Posting

The prototype I built (named Muxer) was able to post to Mastodon and Micro.blog. But it’s a harder problem than you first think.

The issue is that each service has a different set of capabilities. On Bluesky, you can’t post video. On Mastodon, you can post polls. With RSS, you can’t post at all. Size limits and file formats differ wildly (including between Mastodon instances).

You quickly end up in a situation where a user interface gets confusing. For example, you have a video ready to post on Mastodon and decide that you’d also like to send it to Bluesky. As soon as you do that, the post button gets disabled and it’s hard to explain to a user why that happened.

It’s also not clear in my mind if cross-posting between services is a good thing or not. Once you have an app that can display information from many different sources, it quickly gets annoying to see duplicates.

As we learn more about this product, and what people want from it, we’ll have a better idea of how to handle posting.

And more…

I’m always happy to talk about Tapestry and explain the thought processes behind it. If you have questions or concerns not covered here, please feel free to reach out on Mastodon.

And, of course, everyone at the Iconfactory would love your support for Project Tapestry.

The Next 40

Last week’s 40th anniversary of the Mac got me thinking. I’ve also been contemplating this week’s release of Apple Vision Pro.

It feels like we’re at a crossroads for platforms, but one that’s impossible to pass.

I was one of the folks who bought a Mac in 1984. At the time I was a member of a team building a Unix workstation from the ground up. We had bigger displays, better networking, faster processors, more memory, and larger disks.

But we were all jealous of what the team at Apple had done. That first Mac and its system software was brimming with new user interface ideas and techniques. Better ways of doing everything we had done.

And you can say the same thing about Apple Vision Pro and visionOS.

Except there is a problem.

Processes

If you’re a software developer, the Apple Vision Pro cannot be used standalone for your work. You’ll be able to use it as much as you do an iPad. You can experiment in Playgrounds and build some simple apps, but you’ll quickly hit a wall.

That’s because developers use a lot of processes. And these processes talk to each other in very creative ways. Maybe it’s as simple as creating child processes to handle work. Maybe it’s a more complicated process like a Docker container running a web server that talks to a database process via a Ruby on Rails process. There are processes everywhere you look.

And in an Apple sandbox, you get one process. You can’t fork and exec a child. And if you query the Mach kernel for information about another process, you get back KERN_FAILURE.

(To get a very good idea of what’s possible at the fringes of a sandbox, take a look at a-Shell on your mobile device. It does an amazing number of things, but you’ll quickly feel frustrated that ps, kill, top, and anything else that deals with processes is missing.)

There is a good reason for apps only having visibility of their own state. Imagine the kind of fingerprinting that Google and Facebook could do by seeing what apps you’re using. We’ve already seen apps trying to do the same thing using URL schemes.

When my pal John Gruber talks about Macs doing the heavy lifting, it’s not just about complex and resource-intensive tasks. It’s also about the security exposure: the Mac is the only “dangerous” Apple platform.

Windows

There is a thing that developers love almost much as processes: windows. We have so damn many. Hundreds on a good day. Thousands on a really good day.

And this is why I get frustrated every time I see a demo of Apple’s headset. I can easily imagine fitting my work into a space with an infinitely large interaction surface.

As it is now, you get to see a screen or two streamed from your Mac. That will surely improve; probably to the point where you have individual windows in your spatial environment.

But you’ll still be carrying the Mac around to get any work done. Somewhat ironically, the Apple Vision Pro is not doing the heavy lifting, but it will be the thing that’s cumbersome in your daily life.

Here’s a comparison of the headset’s carrying case and a MacBook Air:

11.69″ × 8.78″ × 6.5″ vs. 11.97″ × 8.46″ × 0.44″

The Apple Vision Pro is almost 15 times taller than the MacBook Air. Even worse, I can’t even close my backpack, much less fit in a laptop:

“You’re going to need a bigger boat.”

After the Mac was introduced, you didn’t have to carry around an Apple ][ or Lisa to do software development.

Yet here we are because the Apple Vision Pro is locked down. It’s being relegated to being a fancy display for software developers. That’s not necessarily a bad thing and there’s no extra cost for a display stand.

But…

This isn’t a sustainable situation for the next 40 years. Without some low-level structural changes in visionOS, it will never thrive as a developer platform. Just as the iPad has not.

It also doesn’t bode well for the Mac. I’m sure Apple can continue to add incremental changes to satisfy developers, but there won’t be anything revolutionary with how we work. There is also little incentive for Apple to change here: you are buying an Apple Vision Pro along with a MacBook, after all.

One of the extrordinary things that happened back in 1984 was the ability to have more than one terminal window. Even though my Mac had to be connected to a VAX 11/780 over a serial cable (sound familiar?), this was a completely new way of working. We were suddenly free of working within the confines of a single 24×80 character display.

Once we broke free of those limitations, things like visual development environments took hold. I’m pretty sure Apple understands the productivity benefits that came along with these changes.

And here’s the thing: developers don’t come up with these ideas unless they have a place to experiment. Seeing multiple windows that contained code, debugging, and other tools led some folks to start thinking about integrating this environment using the new interaction mechanisms.

Those same kind of folks may find inspiration in spatial computing, but will ultimately get thwarted by the restrictions of a single process. An architecture developed for mobile devices with only one app on the screen is now being used for apps on an infinitely large screen.

Apple Vision Pro is a technical marvel, but ultimately falls short in ways that satisfy the natural curiosity of developers.

That’s a shame. I just hope some smart folks at Apple feel the same frustration I do, because we need a future beyond the Mac.

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.

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!