<div dir="ltr">Got some clarity on this from Apple folks on Twitter: <a href="https://twitter.com/jtbandes/status/830159670559993856">https://twitter.com/jtbandes/status/830159670559993856</a><div class="gmail_extra">
<br><div class="gmail_quote">On Fri, Feb 10, 2017 at 12:54 PM, Michel Fortin <span dir="ltr">&lt;<a href="mailto:michel.fortin@michelf.ca" target="_blank">michel.fortin@michelf.ca</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word">I did file one (30314719). I might not have explained the problem clearly enough, I suppose, because at the time I was misinterpreting the API contract thinking it was the new AppKit Touch Bar stuff that was violating it instead. That bug now sits closed and I hesitate opening a new bug for the same problem just to ask it to be fixed in another way. Meanwhile I found an acceptable workaround that I attached to the existing bug report in addition and I posted all this to the list. Hopefully someone at the right place will notice.<div><br></div><div>But yeah... maybe I should file another bug, against Foundation&#39;s Swift interface this time, since NSTextStorage&#39;s string property comes from NSAttributedString. I&#39;ll think about it.<div><div class="h5"><br><div><br><div><blockquote type="cite"><div>Le 10 févr. 2017 à 11:36, Jacob Bandes-Storch &lt;<a href="mailto:jtbandes@gmail.com" target="_blank">jtbandes@gmail.com</a>&gt; a écrit :</div><br class="m_3047233416326294474Apple-interchange-newline"><div><div>This seems like a bug (missing feature?) in how the API is imported for Swift. You might consider filing a Radar.</div><div> <br><div class="gmail_quote"><div>On Thu, Feb 9, 2017 at 3:12 PM Michel Fortin via swift-users &lt;<a href="mailto:swift-users@swift.org" target="_blank">swift-users@swift.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">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.<br class="m_3047233416326294474gmail_msg">
<br class="m_3047233416326294474gmail_msg">
Here&#39;s the documentation for that method:<br class="m_3047233416326294474gmail_msg">
<a href="https://developer.apple.com/reference/foundation/nsattributedstring/1412616-string" rel="noreferrer" class="m_3047233416326294474gmail_msg" target="_blank">https://developer.apple.com/<wbr>reference/foundation/<wbr>nsattributedstring/1412616-<wbr>string</a><br class="m_3047233416326294474gmail_msg">
<br class="m_3047233416326294474gmail_msg">
In case the contract isn&#39;t clear from the documentation (it wasn&#39;t for me), I got a confirmation as a response in radar 30314719:<br class="m_3047233416326294474gmail_msg">
&gt; 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.<br class="m_3047233416326294474gmail_msg">
<br class="m_3047233416326294474gmail_msg">
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&#39;t the case.<br class="m_3047233416326294474gmail_msg">
<br class="m_3047233416326294474gmail_msg">
Obviously, I can work around this by writing some Objective-C code, but it&#39;d be better if I could avoid splitting the class implementation between two languages. There&#39;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&#39;s probably what I&#39;ll end up doing unless a better solution can be pointed out to me.<br class="m_3047233416326294474gmail_msg">
<br class="m_3047233416326294474gmail_msg">
<br class="m_3047233416326294474gmail_msg">
--<br class="m_3047233416326294474gmail_msg">
Michel Fortin<br class="m_3047233416326294474gmail_msg">
<a href="https://michelf.ca/" rel="noreferrer" class="m_3047233416326294474gmail_msg" target="_blank">https://michelf.ca</a><br class="m_3047233416326294474gmail_msg">
<br class="m_3047233416326294474gmail_msg">
______________________________<wbr>_________________<br class="m_3047233416326294474gmail_msg">
swift-users mailing list<br class="m_3047233416326294474gmail_msg">
<a href="mailto:swift-users@swift.org" class="m_3047233416326294474gmail_msg" target="_blank">swift-users@swift.org</a><br class="m_3047233416326294474gmail_msg">
<a href="https://lists.swift.org/mailman/listinfo/swift-users" rel="noreferrer" class="m_3047233416326294474gmail_msg" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-users</a><br class="m_3047233416326294474gmail_msg">
</blockquote></div></div>
</div></blockquote></div><br><div>
<div style="color:rgb(0,0,0);letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;word-wrap:break-word"><div style="color:rgb(0,0,0);letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;word-wrap:break-word"><div style="color:rgb(0,0,0);letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;word-wrap:break-word"><div style="color:rgb(0,0,0);font-family:Helvetica;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:-webkit-auto;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;word-wrap:break-word"><span class="m_3047233416326294474Apple-style-span" style="border-collapse:separate;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;line-height:normal;border-spacing:0px"><div style="word-wrap:break-word"><span class="m_3047233416326294474Apple-style-span" style="border-collapse:separate;color:rgb(0,0,0);font-family:Helvetica;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:-webkit-auto;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;border-spacing:0px"><div style="word-wrap:break-word"><span class="m_3047233416326294474Apple-style-span" style="border-collapse:separate;color:rgb(0,0,0);font-family:Helvetica;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:-webkit-auto;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;border-spacing:0px"><div style="word-wrap:break-word">-- <br>Michel Fortin</div><div style="word-wrap:break-word"><span style="text-align:-webkit-auto"><a href="https://michelf.ca" target="_blank">https://michelf.ca</a></span></div></span></div></span></div></span></div></div></div></div>
</div>
<br></div></div></div></div></div></blockquote></div><br></div></div>