Reputation: 52231
Starting with swift3 I'm having trouble reliably detecting nil/NSNull. In this snippet here, instead of nil
, I'm getting an Optional(_SwiftValue)
value that I don't know how to detect.
I have tried checking classForCoder without luck.
Elsewhere there is talk about id-as-Any causing this kind of problem
func testVotingMachine() {
let vote: String? = nil // Can be a string or nil
//let vote: String? = "president" // Can be a string or nil
var dict = [String: AnyObject?]()
dict["vote"] = vote as AnyObject?
let obj: AnyObject? = dict as AnyObject?
guard let dict2 = obj as? Dictionary<String, AnyObject?> else {
fatalError()
}
let value = dict2["vote"] as AnyObject?
let didVote = notNil(objectOrNil: value)
XCTAssertFalse(didVote) // BOOM! notNil() fails to detect nil
}
func notNil(objectOrNil: AnyObject?) -> Bool {
guard let object: AnyObject = objectOrNil else {
return false
}
if object is NSNull {
return false
}
//if object.classForCoder == NSNull.classForCoder() {
// return false
//}
// TODO: how to check for? Optional(_SwiftValue)
print("class for coder: \(object.classForCoder)")
return true
}
I need to sanitise my data before passing it to JSONSerialization.data()
. Thus I need to detect Optional(_SwiftValue)
Upvotes: 3
Views: 865
Reputation: 93191
An String?
is shorthand for Optional<String>
. When it's nil, it's actually represented as Optional<String>.none
, which qualifies is as a non-nil AnyObject
so your test didn't work.
You can fix it like this:
func notNil(objectOrNil: AnyObject?) -> Bool {
guard let object: AnyObject = objectOrNil,
object as! _OptionalNilComparisonType != AnyObject?.none else {
return false
}
if object is NSNull {
return false
}
//if object.classForCoder == NSNull.classForCoder() {
// return false
//}
// TODO: how to check for? Optional(_SwiftValue)
print("class for coder: \(object.classForCoder)")
return true
}
Upvotes: 2