无法转换‘NSAttributedString.DocumentAttributeKey’类型值,新旧应用差异问题求助
Hey there! This is super common when working across different Xcode/SDK versions, so let’s break down what changed and why you’re seeing that "cannot convert 'NSAttributedString.DocumentAttributeKey'" error.
The Root Cause: API Type Safety Overhaul
Apple has been gradually replacing string-based attribute keys in Foundation with strongly typed structs/enums to reduce bugs from typos and improve compile-time checks. For NSAttributedString, this means the old string constants (like NSDocumentTypeDocumentAttribute) have been replaced by the NSAttributedString.DocumentAttributeKey struct and its static properties (like .documentType).
Why Old Apps Still Compile
Your existing app is likely using an older deployment target, Swift version, or Xcode SDK that still allows the legacy string-based keys. The compiler in older setups was more lenient, allowing implicit conversions between the string keys and the newer DocumentAttributeKey type.
New apps, though, default to the latest SDK and Swift version, where the compiler enforces strict type matching—no more implicit conversions. So if your code is still using the old string keys (or trying to cast them to DocumentAttributeKey), it throws that conversion error.
Example of the Fix
Let’s say your old code looked like this:
// Legacy code that works in older SDKs let htmlOptions: [String: Any] = [ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue ] let attributedString = try? NSAttributedString(data: htmlData, options: htmlOptions, documentAttributes: nil)
In the latest SDKs, you need to update it to use the strongly typed keys:
// Updated code for modern SDKs let htmlOptions: [NSAttributedString.DocumentAttributeKey: Any] = [ .documentType: NSHTMLTextDocumentType, .characterEncoding: String.Encoding.utf8.rawValue ] let attributedString = try? NSAttributedString(data: htmlData, options: htmlOptions, documentAttributes: nil)
Compatibility Tip
If you need your code to work across both old and new SDKs, you can use availability checks:
var htmlOptions: [AnyHashable: Any] if #available(iOS 13.0, macOS 10.15, *) { htmlOptions = [ NSAttributedString.DocumentAttributeKey.documentType: NSHTMLTextDocumentType, NSAttributedString.DocumentAttributeKey.characterEncoding: String.Encoding.utf8.rawValue ] } else { htmlOptions = [ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue ] }
This way, your code will compile and run correctly regardless of the SDK version.
内容的提问来源于stack exchange,提问作者Beth.larson1977

