Mr. Mioio
Mr. Mioio

Reputation: 21

Swift 3 NSArray compare to nil

I'm trying to migrate an objc project to swift3. I'm not sure how can I compare an array to nil. I have found this topic, but that was 2 years ago and the swift's syntax has changed a lot.

If I have a code like this in swift:

let variable = something as? NSArray
  if variable == nil {
    // do something
  }

It won't let me to compare this variable with nil, causing an error "comparing this variable, always returns false". I have tried comparing variable.description with " ", but does it do the same thing? By "something" i meant:

var variable = dict.object(forKey: someString) as! NSArray

The main thing I wanted to do with this was:

var variable = dict.object(forKey: someString) as! NSArray
  if variable == nil {
    //create 
  }
  else {
    // append
  }

Upvotes: 1

Views: 1062

Answers (4)

James Webster
James Webster

Reputation: 32066

This line indicates that variable is and must be an NSArray. If dict.object(forKey: someString) is not an NSArray, this will cause a crash

var variable = dict.object(forKey: someString) as! NSArray
//                                               ^
// This exclamation mark means you are certain this is an NSArray
// Also, because there is no question mark after NSArray, this variable
// is not optional. It cannot be nil

However, you then use

if variable == nil {

And this is where the warning comes from. The variable can never be nil, because the variable is not optional


What you probably want is:

if let variable = dict.object(forKey:someString) as? NSArray    

This will return false if:

  • dict.object(forKey:someString) returns a nil object
  • the object returned is not an NSArray

After this variable is now a non-optional NSArray. It is guaranteed to be an NSArray and is guaranteed to not be nil. You can use it without unwrapping it. e.g.

if let variable = dict.object(forKey:someString) as? NSArray {
    for element in variable {
    }
}
else {
    //The dict doesn't contain the object yet. `variable` is nil
    //Create a new array and add it to dict
    let newArray = ["First Value"]
    dict[someString] = newArray
}

Upvotes: 1

nayem
nayem

Reputation: 7595

You can also use this format with guard-else:

guard let variable = something as? NSArray else {
    // your variable is nil. Do something if needed
}
// your variable is available in this scope. Do something when variable contains Array

Upvotes: 0

toddg
toddg

Reputation: 2906

That's what the optional unwrapping syntax is for. You can combine the unwrapping and cast into one if statement:

if let variable = something as? NSArray {
    // variable is not nil and is an NSArray
    // Now you can do something with it.
} else {
    // Either something is nil or it is not able to be cast as an NSArray
    // Handle this case.
}

I should also mention that if you don't need to use something in Objective-C, then you should use the Swift-native array type. This can be declared like this:

let someArray = ["string1", "string2"]

Upvotes: 3

DrummerB
DrummerB

Reputation: 40211

let variable = something as? NSArray

With this declaration, variable will be an optional type (NSArray?) and never nil. This is because casting with as? returns an optional value that either contains the successfully casted object or nothing. You can see this by alt-clicking the variable name in Xcode.

If you want to know whether it contains a value, you need to use the if let syntax:

if let variable = variable {
    // variable is guaranteed to be an NSArray here.
}

Upvotes: 0

Related Questions