I've started getting dozens of crashes related to the NSOutlineView implementation, with many different types of crash report signatures, which all seem internal to Swift and/or NSOutlineView.
Thanks for the heads up. I haven't deployed my code at all yet. I think I've seen some comments that Apple is replacing lower-level Objective-C code with Swift. Your crash logs look like that.
I made a thread about this here and filed a feedback, but haven't received any response: https://developer.apple.com/forums/thread/767447
Not surprising.
I basically need the sidebar to show what on iOS would be done with a sectioned UITableView (which doesn't exist on macOS).
You should be able to do that easily enough. macOS uses header rows instead of sections. But you can float and style them and they'll look nice. As far as that goes, if you want to be clever with styling, you could probably draw the row backgrounds so that it looks identical to iOS.
I use a dictionary to drive the NSOutlineView.
That sounds very bad. Table and outline views should be driven from an array. In outline views, the root is an array. Each element has an array of children.
It loads fine, but if something changes, I have to update the 'count' of the item (by updating the count property of the item in the dictionary) and call outlineView.reloadItem, which ends up causing the crash in 1% of the cases.
Both of your crashes involve parent/child relationships. I saw another post recently here in the forum that suggested dictionaries on Swift aren't entirely stable. It sounds like your data model is changing underneath the UI.
In my opinion, the only time you would ever call reloadItem is to update an item. Never use it to update children. Update children in some other fashion where it can be animated. I think this may be the problem. Table and outline views are really old. They still support old usage methods that don't require animation. That may be hiding bugs that you would have seen if you had done the extra work to make sure everything is animated. That can be a whole lot of extra work and could even require a change of architecture.
I have a similar implementation on iOS so it would improve consistency as well. But it doesn't seem to be possible with NSOutlineView, only NSTableView (or collection view)
When I did that on iOS, it seemed like the hierarchical representation was the flakiest part of it. I seem to have gotten it to work, but I don't have much confidence in it. You can certainly try it if you want to, but it would still be a Mac implementation. You've already seen how much anyone cares about Mac issues.
replace it with a SwiftUI view
I started my project in SwiftUI. But after a certain level of hacks, I realized that it just wasn't going to work. When considering the amount of work this will take, also consider the amount of work it will take to reimplement it later without SwiftUI. Plus, these kinds of Split View displays have changed significantly in SwiftUI and could change again.
It sounds like trying to use a dictionary as a data source is the problem here. NSOutlineView is more primitive than UICollectionView. If an item isn't expanded, then you don't need to update the UI for changes to children. But if an item is expanded, then you'll need to manually add rows to accommodate what has already been changed in the data model.
The way I did it, I have a "data source" wrapper around the various diffable data source snapshots on iOS. I have a similar "data source" wrapper on the Mac side with a very similar interface. But the Mac "data source" actually does some UI manipulation just due to the ancient, kludgy nature of outline views. From from a higher level, view controller perspective, both platforms are virtually identical.
That's really the way it works anyway. On iOS, you have your data model and then the diffable data source is just an opaque structure of identifiers that has to match the data source. On the Mac, the outline view itself plays that role in maintaining a structure for the underlying items.