How to check if NSDictionary is not bottom in Swift 2

I get NSDictionary as a parameter in my function, but I have a problem because I don’t know how to check if this parameter is null.

My function looks like this:

func doSmth(val : NSDictionary) 

Inside my function, I am trying to get some values:

 let action = val["action"] as! String 

But getting the error "fatal error: unexpectedly found nil when expanding an optional value" when accepting the val parameter as nil.

+7
ios swift
source share
4 answers

The error is related to the assumption (forced casting) of the value, which can sometimes be nil. Swift is awesome because it allows conditional sweeps and conditional clicks in very concise expressions. I recommend the following (for Swift 1-3):

Use "if let" to conditionally check the "action" in the dictionary.

Use how? to conditionally translate a value into a string

 if let actionString = val["action"] as? String { // action is not nil, is a String type, and is now stored in actionString } else { // action was either nil, or not a String type } 
+7
source share

You can also access the allKeys property or the allKeys alternative and check if the array contains these elements:

 let dic = NSDictionary() let total = dic.allKeys.count if total > 0 { // Something in there } else { // Nothing in there } 

EDIT

Here's how you can determine if NSDictionary is null if they key exists, and if it tries to get a value to it:

 let yourKey = "yourKey" if let dic = response.someDictionary as? NSDictionary { // We've got a live one. NSDictionary is valid. // Check the existence of key - OR check dic.allKeys.containsObject(yourKey). let keyExists: Bool = false; for var key as String in dic.allKeys { if key == yourKey { keyExists = true; } } // If yourKey exists, access it possible value. if keyExists == true { // Access your value if let value = dic[yourKey] as? AnyObject { // We're in business. We have the value! } else { // yourKey does not contain a value. } } else { // yourKey does not exist in NSDictionary. } } else { // Call an ambulance. NSDictionary is nil. } 
+8
source share

Your dictionary option is probably not zero. Probably the problem is that your dictionary does not contain a value for the "action" key.

When you say val["action"] , the dictionary (being NSDictionary ) returns Optional<AnyObject> . If val contains the "action" key, it returns Some(value) . If val does not contain the "action" key, it returns None , which is zero.

You can expand Optional on your cast and choose the course of action based on whether it was null using the if-let :

 if let action = val["action"] as? String { // action is a String, not an Optional<String> } else { // The dictionary doesn't contain the key "action", and // action isn't declared in this scope. } 

If you really think that val itself may be nil, you need to declare your function this way, and you can unpack val without renaming using the somewhat confusing guard statement:

 func doSmth(val: NSDictionary?) { guard let val = val else { // If val vas passed in as nil, I get here. return } // val is now an NSDictionary, not an Optional<NSDictionary>. ... } 
0
source share

This does not apply to Swift 2.

If the dictionary may be nil declare it as optional

 func doSmth(val : NSDictionary?) 

Then use additional bindings to check

 if let valIsNonOptional = val { let action = valIsNonOptional["action"] as! String } 

The code assumes that there is an action key containing a String value if the dictionary is not nil

0
source share

All Articles