UIDocumentBrowserViewController on Mac Catalyst

tl;dr: If you’re trying to use UIDocumentPickerViewController or UIDocumentBrowserViewController from a Mac Catalyst app and always get stopped in the debugger with the message “this class is not key value coding-compliant for the key cell”, just temporarily disable breakpoints and continue. Everything will work.

I’m embarrassed how much time I lost on this problem.

When I first worked on getting Library Notes ready to submit to the App Store, I figured I should also try this new-fangled “Mac Catalyst” technology and get a version of the app that runs on the Mac, too.

In my notes at the time, I wrote:

Update Jan 14, 2021 — The Catalyst app crashes on launch with an error about an NSView not being key-coding compliant for “cell”, and I have no idea how to debug further. So, I’m just going to ignore making a Mac app for now.

I didn’t pursue the Mac version of this project because, at the time, it worked just as well for me as an iPad / iPhone app.

Fast forward 18 months, and I’m getting ready to go on a long series of back-to-back business and personal trips, and I didn’t want to bring both my iPad Pro and Mac. Suddenly it really bothered me that I didn’t have a Mac version of Library Notes that I could use to continue to update my reading notes while on my trip. There was also a brand-new version of Xcode, and a lot of hubbub about “desktop-class iPad apps” at WWDC. Surely, this problem about an NSView not being key-coding compliant for “cell” is fixed in with the new developer tools, right?

Wrong.

I fire up the Xcode project, set it to target Mac Catalyst, hit Run in Xcode, and almost immediately hit the error message:

Thread 1: ”[<NSView 0x14363e4f0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key cell.”

The frustrating this was this error doesn’t originate in my code. As near as I can tell, it comes from using UIDocumentBrowserViewController in a Catalyst app on a Mac with a Touch Bar. I only found one other person on Twitter who had this problem. Google searches turned up nothing. I tried:

  • Refactoring my code to use UIDocumentPickerViewController instead of UIDocumentBrowserViewController. Same problem as soon as I bring up the picker.
  • I created a custom UIDocumentPickerViewController subclass and used that instead. I tried manipulating every Touch Bar hook in UIViewController to see if I could make the problem go away. No luck.
  • Creating a new sample app that just brought up a UIDocumentBrowserViewController. This one worked, so I systematically started looking for differences between Library Notes and the test app. I changed random Info.plist properties, target SDK versions; really, anything I could think of. This took about a day.
  • Finally, I decided to run my broken Catalyst app in Instruments to see if there’s any code running at app start that I’ve forgotten about. “Maybe,” I thought to myself, “something running at app start is putting things in a funny state?” Imagine my shock when the app worked when connected to Instruments.
  • This is what lead me to discover that everything works when I run the Release build. Something related to optimizations?
  • No! Even dumber. Everything works if I don’t have breakpoints enabled when running the app in the debugger. It’s not enough to just hit “continue” when you run into this problem. It will just happen again. However, if you get this message in the debugger, just disable breakpoints then click Continue. The document picker will work.

This one problem set back the Mac version of Library Notes by over a year. (Facepalm.)