Swift 4 - Xcode 9 测试版 4 - NSKernAttributeName 与 NSAttributedStringKey

Swift 4 - Xcode 9 beta 4 - NSKernAttributeName vs NSAttributedStringKey

iOS 部署目标:iOS 9.3, 基础 SDK:最新 iOS (iOS 11.0), Xcode 9 测试版 4, Swift 4

以下代码在 Swift 3、Xcode 8 中构建并运行:

    let kern = (CTRunGetAttributes(run) as? [String : Any])?
[NSKernAttributeName] as? CGFloat ?? 0

但是,Swift 4 迁移器将其转换为:

    let kern = (CTRunGetAttributes(run) as? [String : Any])?
[NSAttributedStringKey.kern] as? CGFloat ?? 0

Xcode 9 现在抱怨:

Cannot subscript a value of type '[String : Any]' with an index of type 'NSAttributedStringKey'

根据检查员的说法,“NSAttributedStringKey”仅在 iOS 11 中可用。(请记住,我的目标是 iOS 9)。

如果我将“NSAttributedStringKey.kern”替换为“NSKernAttributeName”,错误仍然存​​在。

Command-clicking on 'NSKernAttributeName' 告诉我它的可用性是 iOS 6。但是,检查员还声称它的类型是 'NSAttributedStringKey',它只可用在 iOS 11 中。我不知道这是否仅仅是 API 演示文稿的一个人工产物,或者是一个东西,或者是我遗漏的东西。

问题:如何使用 NSKernAttributeName(或其现代化版本)向后兼容 iOS 9,以及 Swift 4?

感谢您的帮助。

将字典键入 [NSAttributedStringKey : Any] 而不是 [String : Any]。 Swift 覆盖层中全是糖,因此它甚至可以在较旧的 macOS/OS X 版本上使用。

编辑:我应该稍微澄清一下我的最后一句话。 NSAttributedStringKey,以及 Swift 4 中的所有其他新 "Key" 类型,仅存在于 Swift 中,而不存在于 Objective-C 中。当带有 NSAttributedStringKey 键的字典桥接到 Objective-C 时,所有键都将变成 NSString。由于您正在使用的实际 Foundation、UIKit 等框架是用 C/Objective-C 编写的,这将 "just work",您不必担心文档声称 NSAttributedStringKey 仅适用于 10.11。

textField.defaultTextAttributes[NSAttributedStringKey.kern.rawValue] = 16

Swift 4

如果你不想忽略警告并不管不顾地进行转换,你可以将它们干净地复制到新词典中。

var attributes: [NSAttributedStringKey: Any] = [:]
textField.defaultTextAttributes.forEach{
    attributes[NSAttributedStringKey(rawValue: [=10=].key)] = [=10=].value
}