One of the Apple Api's return the following result:
▿ Optional<Any>
- some : nil
And I would like to have my function to return in case of wrapped underlying item is nil
Unfortunately during the process I found couple of things very confusing.
So my question is more about how to understand those things in a simplified way.
To reproduce the the input I used the following:
let dict:[String: Any] = ["x": Optional<Any>(nil)]
let any = dict["x"]
//OR
let any: Any?? = Optional<Any>(nil)
Q1
Why the above produce the desired input? (I would anticipate to get <Optional <Optional(nil)>>)
So I tried couple of possible solutions that I thought should be straight forward.
private func collectScreenAttributes(child:Any? ) {
//That obviosly wont work as we unwrap an optional and get a value nil
guard let child = child else {
return
}
if let x = child {
if x == nil {
//Q2 I would assume that might work as I see in the debugger that x is nil, but that doesnt work, with a warning that make sense "Comparing non-optional value of type 'Any' to 'nil' always returns false",
print("\(x)")
} else {
print("not nil")
}
}
switch child {
case .none:
break
case .some(nil):
//Q3 I would assume that it will stop here as the pattern seems to match but am wrong
break
case .some(_):
// it stops here
break
case .some(.none)
//Q4 That will not compile "Type '_ErrorCodeProtocol' has no member 'none'", what that error means (I would assume that its like a second case)?
break
}
//I also tried the flatMap but that basically the same
//that works
let result:Any? = deepUnwrap(child)
if result == nil {
return
}
}
In the end I followed that solution:
private protocol _OptionalProtocol {
var _deepUnwrapped: Any? { get }
}
extension Optional: _OptionalProtocol {
fileprivate var _deepUnwrapped: Any? {
if let wrapped = self {
return deepUnwrap(wrapped)
}
return nil
}
}
func deepUnwrap(_ any: Any) -> Any? {
if let optional = any as? _OptionalProtocol {
print("optional: \(optional)")
return optional._deepUnwrapped
}
return any
}
Although there are 4 question in one, but I believe all of them has the same root cause, that I don't understand on how it really work.
I have read:
Optionals Case Study: valuesForKeys
How to unwrap double optionals?
How to unwrap an optional value from Any type? (very similar to mine)
Why non optional Any can hold nil?
Thanks