1

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
  }
Community
  • 1
  • 1
Mr. Mioio
  • 21
  • 3

4 Answers4

3

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"]
toddg
  • 2,863
  • 2
  • 18
  • 33
  • I don't remember and cant check it right now. But it was something with object forkey, if I'm right. I will try this tomorrow.And one more thing, I can just type else statement if "variable" is nil? – Mr. Mioio Mar 15 '17 at 16:32
  • Edited to answer your question. – toddg Mar 15 '17 at 16:34
  • by "something" i meant this -> var variable = dict.object(forKey: someString) as! NSArray. Does it changes something or I still can use your example? – Mr. Mioio Mar 16 '17 at 08:21
1

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
}
James Webster
  • 31,873
  • 11
  • 70
  • 114
0
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.
}
DrummerB
  • 39,814
  • 12
  • 105
  • 142
  • 2
    Isn't `nil` a literal value that the compiler translates into `Optional.none` ? AFAIK, you can always compare an Optional to `nil`. – jlehr Mar 15 '17 at 16:04
0

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
nayem
  • 7,285
  • 1
  • 33
  • 51