Swift: Testing Optionals for Nil

Swift: Testing optionals for nil

In Xcode Beta 5, they no longer let you do:

var xyz : NSString?

if xyz {
// Do something using `xyz`.
}

This produces an error:

does not conform to protocol 'BooleanType.Protocol'

You have to use one of these forms:

if xyz != nil {
// Do something using `xyz`.
}

if let xy = xyz {
// Do something using `xy`.
}

Best way to check non-optional values for nil in Swift

Even Apple's APIs sometimes return nil for a type that is not marked in the API as Optional. The solution is to assign to an Optional.

For example, for a while traitCollectionDidChange returned a UITraitCollection even though it could in fact be nil. You couldn't check it for nil because Swift won't let you check a non-Optional for nil.

The workaround was to assign the returned value immediately to a UITraitCollection? and check that for nil. That sort of thing should work for whatever your use case is as well (though your mail example is not a use case, because you're doing it wrong from the get-go).

How to check nil for Swift Optionals with out unwrap it?

First of all firstName is an Optional therefore you cannot pass it to a function which only takes String.

In addition this line:

str.characters.count > 0 ? "\(str)" : ""

Is equivalent to just returning str so you don't check whether it is an Optional.

Solution

In this case it is way easier to use the nil coalescing operator:

let addressstr = address?.firstName ?? ""

If address is not nil firstName gets unwrapped and bind to addressstr. Otherwise this string gets assigned to it: ""

How to check object is nil or not in swift?

If abc is an optional, then the usual way to do this would be to attempt to unwrap it in an if statement:

if let variableName = abc { // If casting, use, eg, if let var = abc as? NSString
// variableName will be abc, unwrapped
} else {
// abc is nil
}

However, to answer your actual question, your problem is that you're typing the variable such that it can never be optional.

Remember that in Swift, nil is a value which can only apply to optionals.

Since you've declared your variable as:

var abc: NSString ...

it is not optional, and cannot be nil.

Try declaring it as:

var abc: NSString? ...

or alternatively letting the compiler infer the type.

Swift UnitTesting testing 2 optional variables

If you have two optional properties of different type, say a and b, you can switch over the tuple (a, b) for a case (.none, .none), which would correspond to both properties being nil. If not matching this case, at least one of the properties are non-nil). E.g.

let a: Int? = 1
let b: String? = nil

// ...

switch (a, b) {
case (.none, .none): XCTFail("...") // fail case
case _ : () // otherwise _at least_ one of 'a' and 'b'
// is non-nil
}

Or, simply

// fail case w.r.t. 'nil'-ness?
if case (.none, .none) = (a, b) {
XCTFail("...")
}

If both of your optional properties are of the same type, say Int?, then you can simply test the the nil-ness of the expression a ?? b, which will be nil only if both a and b are nil.

let a: Int? = 1
let b: Int? = nil

// ...

XCTAssertNotNil(a ?? b, "Both properties are nil ...")


Related Topics



Leave a reply



Submit