[swift-users] So how do you implement a NSTextStorage subclass in Swift?

Michel Fortin michel.fortin at michelf.ca
Thu Feb 9 17:12:09 CST 2017

The `string` property of `NSTextStorage` is of type `String`, but the contract it must implement is that it should return the backing store of the attributed string (the underlying `NSMutableString` used as the backing store). It seems to me that this makes it impossible to implement correctly a subclass of `NSTextStorage` in Swift, because Swift automatically wraps the `NSString` into a `String` and the underlying mutable storage is not passed around.

Here's the documentation for that method:

In case the contract isn't clear from the documentation (it wasn't for me), I got a confirmation as a response in radar 30314719:
> It’s returning a copy of the backing store, but the contract is actually returning the backing store string. The copy storage declaration in the property spec is only used for setter implementation.

So looks like this is impossible to model correctly in Swift due to the automatic bridging to `String`. Some APIs in AppKit expect the `NSString` they receive to mutate when mutating the text storage (touch bar suggestions in `NSTextView`) and will do bad things this isn't the case.

Obviously, I can work around this by writing some Objective-C code, but it'd be better if I could avoid splitting the class implementation between two languages. There's another way using swizzling to map the Objective-C method to a Swift implementation of the same method that has the correct signature, and that's probably what I'll end up doing unless a better solution can be pointed out to me.

Michel Fortin

More information about the swift-users mailing list