0

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

Mike.R
  • 2,824
  • 2
  • 26
  • 34
  • Just to be clear, you are trying to check if the `child` parameter is `Optional>.some(.none)`. Is that right? – Sweeper Apr 22 '22 at 12:44
  • my child component is `Optionalnil` I just would like to know that the unwrapped value is nil and if yes, return (basically like simple guard but with optional value). – Mike.R Apr 22 '22 at 13:25

0 Answers0