22

I have already updated to XCode 8 and now I need to convert my code from Swift 2 to Swift 3.

Before, when I want to convert NSDictionary to Dictionary, I just wrote the following:

let post_paramsValue = post_params as? Dictionary<String,AnyObject?>

where post_params is NSDictionary.

But now with Swift 3, I am receiving this error:

NSDictionary is not convertible to Dictionary

Why? What's changed?


Edit 1

I've also tried the following:

let post_paramsValue = post_params as Dictionary<String,Any>

But that gives this error:

'NSDictionary!' is not convertible to 'Dictionary<String, Any>'; did you mean to use <code>as!</code> to force downcast?


Edit 2

I've also tried the following:

let post_paramsValue =  post_params as Dictionary<String,Any>

Where I declare NSDictionary instead of NSDictionary!, but it doesn't work; I got this error:

'NSDictionary' is not convertible to 'Dictionary<String, Any>'; did you mean to use <code>as!</code> to force downcast?


Edit 3

I've also tried the following:

let post_paramsValue =  post_params as Dictionary<String,Any>!

But I received this error:

'NSDictionary!' is not convertible to 'Dictionary<String, Any>!'; did you mean to use <code>as!</code> to force downcast?

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
david
  • 3,310
  • 7
  • 36
  • 59
  • tried this ? http://stackoverflow.com/questions/31765875/casting-nsdictionary-as-dictionary-swift – Umair Afzal Nov 01 '16 at 10:57
  • @UmairAfzal thank you for your comment, but why i need to go through dictionary using loop , this is not convenient , why apple need to make things harder ? – david Nov 01 '16 at 10:58
  • Well I do not know why, did you tried ? it works or not ? – Umair Afzal Nov 01 '16 at 11:10
  • @UmairAfzal i didn't try it ,i am pretty sure that it will work but this is not convenient . i need to do it with the best way. thanks – david Nov 01 '16 at 11:13

3 Answers3

25
  • NSDictionary in Objective-C has always non-optional values.
  • AnyObject has become Any in Swift 3.
  • Considering the first two "rules" NSDictionary can be bridge cast to Dictionary

let post_paramsValue = post_params as Dictionary<String,Any>

If the source NSDictionary is an optional you might use as Dictionary<String,Any>? or as? Dictionary<String,Any> or as! Dictionary<String,Any> or as Dictionary<String,Any>! depending on the actual type of the NSDictionary

vadian
  • 274,689
  • 30
  • 353
  • 361
3

For those who have a problem with NSDictionary, simply use this extension:

Swift 3.0

extension NSDictionary {
    var swiftDictionary: Dictionary<String, Any> {
        var swiftDictionary = Dictionary<String, Any>()

        for key : Any in self.allKeys {
            let stringKey = key as! String
            if let keyValue = self.value(forKey: stringKey){
                swiftDictionary[stringKey] = keyValue
            }
        }

        return swiftDictionary
    }
}
Ky -
  • 30,724
  • 51
  • 192
  • 308
Dzeremix
  • 446
  • 1
  • 5
  • 24
0

You just need to declare the NSDictionary properly in objc

For example: NSDictionary<NSString *, NSString*> gets translated automatically to [String: String] in swift interfaces

Exception
  • 785
  • 8
  • 8