处理了一些objC API,我收到一个NSDictionary<NSString *, id> *>
,转换为Swift中的[String : Any]
,我将其用于NSAttributedString.addAttributes:range:。
但是,此方法签名现在已随Xcode 9更改,现在需要[NSAttributedStringKey : Any]
。
let attr: [String : Any]? = OldPodModule.getMyAttributes()
// Cannot assign value of type '[String : Any]?' to type '[NSAttributedStringKey : Any]?'
let newAttr: [NSAttributedStringKey : Any]? = attr
if let newAttr = newAttr {
myAttributedString.addAttributes(newAttr, range: range)
}
如何将[String : Any]
转换为[NSAttributedStringKey : Any]
?
答案 0 :(得分:14)
NSAttributedStringKey
有an initialiser that takes a String
,您可以使用Dictionary
的{{3}}初始化程序,以便从一系列键值元组中构建字典,其中每个键都是独特的(例如这里的情况)。
我们只需将变换应用于attr
,即在调用String
的初始化程序之前将每个NSAttributedStringKey
密钥转换为Dictionary
。
例如:
let attributes: [String : Any]? = // ...
let attributedString = NSMutableAttributedString(string: "hello world")
let range = NSRange(location: 0, length: attributedString.string.utf16.count)
if let attributes = attributes {
let convertedAttributes = Dictionary(uniqueKeysWithValues:
attributes.lazy.map { (NSAttributedStringKey($0.key), $0.value) }
)
attributedString.addAttributes(convertedAttributes, range: range)
}
我们在这里使用lazy
来避免创建不必要的中间数组。
答案 1 :(得分:0)
您可以使用
`NSAttributedStringKey(rawValue: String)`
初始化。但是,有了这个,它将创建一个对象,即使属性字符串不会受到影响。例如,
`NSAttributedStringKey(rawValue: fakeAttribute)`
仍然会为字典创建一个键。此外,这仅适用于iOS 11,因此请谨慎使用以实现向后兼容。
答案 2 :(得分:0)
虽然Hamish提供了一个完美的Swift答案,但请注意最终I solved直接在Objective-C API级别的问题。如果您无法控制源代码,也可以使用小型Objective-C包装器完成。
我们只需将NSDictionary<NSString *, id> *
替换为NSDictionary<NSAttributedStringKey, id> *
,然后添加typedef
以便与早期版本的Xcode兼容:
#ifndef NS_EXTENSIBLE_STRING_ENUM
// Compatibility with Xcode 7
#define NS_EXTENSIBLE_STRING_ENUM
#endif
// Testing Xcode version (https://stackoverflow.com/a/46927445/1033581)
#if __clang_major__ < 9
// Compatibility with Xcode 8-
typedef NSString * NSAttributedStringKey NS_EXTENSIBLE_STRING_ENUM;
#endif