如何将[String:Any]转换为[NSAttributedStringKey:Any]

问题描述:

处理一些objC API时,我收到一个NSDictionary<NSString *, id> *>,它在Swift中转换为[String : Any],我在NSAttributedString.addAttributes:range:中转换为[String : Any]如何将[String:Any]转换为[NSAttributedStringKey:Any]

但是,此方法签名现已更改为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]

NSAttributedStringKeyan initialiser that takes a String,你可以以建立从键值元组的序列,其中每个键是唯一一本字典使用Dictionaryinit(uniqueKeysWithValues:)初始化器(比如这里的例子)。

我们只需要应用转换到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这里,以避免不必要的中间阵列的创建。

+2

谢谢!为了详尽,我必须做相反的操作('[NSAttributedStringKey:Any]''[String:Any]'),在这种情况下它是'Dictionary(uniqueKeysWithValues:attr.lazy.map {($ 0。 key.rawValue,$ 0.value)})'。 –

+0

@Hamish为什么'懒惰'?在这种情况下'attr.map {/ * ... * /}'不会这样做吗? –

+1

@MatusalemMarques它会达到相同的结果,但使用lazy避免创建一个不必要的中间数组(键值对只是迭代一次,并插入到新的字典中,应用给定的转换)。 – Hamish

可以使用

`NSAttributedStringKey(rawValue: String)` 

初始化。但是,使用它,即使属性字符串不受影响,它也会创建一个对象。例如,

`NSAttributedStringKey(rawValue: fakeAttribute)` 

仍然会为字典创建密钥。此外,这仅适用于iOS 11,因此请谨慎使用,以确保向后兼容。