Swift 4 Conversion error - NSAttributedStringKey: Any

Eazy picture Eazy · Sep 20, 2017 · Viewed 31.5k times · Source

I converted my app recently and I keep getting the error

"Cannot convert value of type '[String : Any]' to expected argument type '[NSAttributedStringKey: Any]?'

barButtonItem.setTitleTextAttributes(attributes, for: .normal)

Whole code:

 class func getBarButtonItem(title:String) -> UIBarButtonItem {
    let barButtonItem = UIBarButtonItem.init(title: title, style: .plain, target: nil, action: nil)
    let attributes = [NSAttributedStringKey.font.rawValue:  UIFont(name: "Helvetica-Bold", size: 15.0)!, NSAttributedStringKey.foregroundColor: UIColor.white] as! [String : Any]
    barButtonItem.setTitleTextAttributes(attributes, for: .normal)

    return barButtonItem
}

Answer

Fangming picture Fangming · Sep 28, 2017

Why you got this error

Previously, your attributes is defined as [String: Any], where the key comes from NSAttributedStringKey as a string or NSAttributedString.Key in Swift 4.2

During the migration, the compiler tries to keep the [String: Any] type. However, NSAttributedStringKey becomes a struct in swift 4. So the compiler tries to change that to string by getting its raw value.

In this case, setTitleTextAttributes is looking for [NSAttributedStringKey: Any] but you provided [String: Any]

To fix this error:

Remove .rawValue and cast your attributes as [NSAttributedStringKey: Any]

Namely, change this following line

let attributes = [NSAttributedStringKey.font.rawValue:
    UIFont(name: "Helvetica-Bold", size: 15.0)!, 
    NSAttributedStringKey.foregroundColor: UIColor.white] as! [String : Any]

to

let attributes = [NSAttributedStringKey.font:
    UIFont(name: "Helvetica-Bold", size: 15.0)!, 
    NSAttributedStringKey.foregroundColor: UIColor.white] as! [NSAttributedStringKey: Any]

And in Swift 4.2,

 let attributes = [NSAttributedString.Key.font:
    UIFont(name: "Helvetica-Bold", size: 15.0)!, 
    NSAttributedString.Key.foregroundColor: UIColor.white] as! [NSAttributedStringKey: Any]