Comparing non-optional value of type 'Bool' to 'nil' always returns true

Viewed 2086

I have an if-else statement where I am checking if the value coming from user defaults is nil or not like this:

 if defaults.bool(forKey: "abcd") != nil{
       //Do something
    }
    else{
        //do something else
    }

But Xcode is giving me an error saying: "Comparing non-optional value of type 'Bool' to 'nil' always returns true"

Can someone explain what's happening here and how to fix this?

6 Answers

bool(forKey:) returns a NON-optional, which cannot be nil. If the key is missing in the user defaults, the return value will be false.

If you want trinary logic here (nil/true/false) use object(forKey:) looking for an NSNumber, and if present, take its boolValue.

As

defaults.bool(forKey: "abcd")

will return false by default check Docs , so it will never be optional

The Boolean value associated with the specified key. If the specified key doesn‘t exist, this method returns false.

The func bool(forKey: "abcd") returns Bool type not optional.

Which means you cant compare it to bool, what you can do is simply:

 if defaults.bool(forKey: "abcd") {
   //Do something
} else {
    //do something else
}

Now if the key exists and has true value it will get into the if statement, if it does not exists or is false it will go to the else.

If you have any doubts you can read about the func in the following Apple developer link: Apple:bool(forKey:)

Objective-c property in swift. If you're using some objective c property in swift and it says something like "Comparing non-optional value of type 'XYZ' to 'nil' always returns true" you have to make that objective c property to "_Nullable" so that property may not be optional anymore. Like @property (strong,nonatomic) NSString *_Nullable someString;

defaults.bool(forKey: "abcd") != nil

The first part, defaults.bool(forKey: "abcd"), returns a non-optional boolean. We know that because bool(forKey:) returns Bool, not Bool?. Therefore, you'll always get a Bool value, i.e. either true or false, never nil. Note the documentation:

If the specified key doesn‘t exist, this method returns false.

"Comparing non-optional value of type 'Bool' to 'nil' always returns true"

The compiler is simply pointing out that it knows that defaults.bool(forKey: "abcd") can't be nil, and since you're comparing it to nil, you're probably making a mistake. Your else block will never execute.

Can someone explain what's happening here and how to fix this?

It depends on what you mean for the code to do. If you want to take different actions depending on whether the value is true or false, then compare it to one of those values. If you want to get an optional value back, use object(forKey:) (which returns an optional) instead.

i solved like this:

if(Userdefaults.standart.bool(forkey: "blablabool"){

}

This works.. When you call this if its null it returns false.

Related