Search code examples
iosnsattributedstringios11

NSAttributedStringKey.attachment versus NSAttachmentAttributeName


I'm having problems with NSAttributedStringKey.attachment versus NSAttachmentAttributeName. Here's the relevant code:

    var key: Any?
    if #available(iOS 11, *) {
        key = NSAttributedStringKey.attachment
    }
    else {
        key = NSAttachmentAttributeName
    }

One of two things are happening. In the actual place where I'm trying to use this code (a Cococapod of my own design, with a deployment target of iOS 8 and now building with Xcode 9), I get an error:

Type 'NSAttributedStringKey' (aka 'NSString') has no member 'attachment'

Or, if I just make a new example project and set the deployment target at iOS 8, I get:

'NSAttachmentAttributeName' has been renamed to 'NSAttributedStringKey.attachment'

This is not the behavior I'd expect with #available. Thoughts?


Solution

  • This String vs struct difference is between Swift 3 (uses Strings such as NSAttachmentAttributeName) and Swift 4 (uses struct static attributes such as NSAttributedStringKey.attachment), not between iOS <11 and iOS >=11. For instance, you can use NSAttributedStringKey.attachment and similar in any supporting version of iOS (e.g. .attachment is available since iOS 7) within a Swift 4 project. #available doesn't apply because it's a Swift language version difference rather than an OS version difference.

    Ensure your pod is set to the correct Swift version and it should then work as expected. You can tell CocoaPods that by adding a .swift-version file at the top of your project:

    $ echo 4.0 >.swift-version
    

    This magical version file is mentioned in passing in a CocoaPods blog post from last year: http://blog.cocoapods.org/CocoaPods-1.1.0/