Double question mark, How does it work?

I am learning Swift and, as part of the process, trying to figure out what exactly is going on here. I have a custom segue where I want to place my modal view controller dismissing transition. What used to be in objective-c as:

UIViewController *sourceViewController = self.sourceViewController;
[sourceViewController.presentingViewController dismissViewControllerAnimated:YES completion:nil];

self is an instance of UIStoryboardSegue.
I translated this snippet in Swift as:

  • Low latency input/output AudioQueue
  • How to find UITextView number of lines
  • Where is set the active build configuration in Xcode 4
  • Example or explanation of Core Data Migration with multiple passes?
  • How do I do authorization and login with WeChat using the iOS SDK?
  • Are generics specialized during compilation or they are just like java generics only for compile time checks?
  • self.sourceViewController.presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
    

    getting this error from the compiler:

    ‘UIViewController?’ does not have a member named
    ‘dismissViewControllerAnimated’

    Now, by documentation, the presentingViewController method looks like this:

    var presentingViewController: UIViewController? { get }
    

    From what I understood by the Swift language documentation, ? should unwrap the value, if any. In this case the view controller. The unexplained fact is: if I put a double question mark, it compiles and it works:

    self.sourceViewController.presentingViewController??.dismissViewControllerAnimated(true, completion: nil)
    

    Can someone tell me what I am missing? What should that do?

    Solutions Collect From Internet About “Double question mark, How does it work?”

    The extra ? required is due sourceViewController returning an AnyObject instead of a UIViewController. This is a flaw in the API conversion from Objective-C (in which such property returns a rather meaningless id). It’s still an on-going process that started with iOS 8 beta 5, and apparently those API have not been fixed yet.

    If you provide an appropriate cast, it will work as expected

    (self.sourceViewController as UIViewController).presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
    

    Now, why do we need an extra ? when dealing with AnyObject?

    AnyObject can represent any object type, pretty much as id does in Objective-C. So at compile-time you can invoke any existing method on it, for example sourceViewController.

    When you do so, it triggers an implicit downcast from AnyObject to UIViewController and according to the official guide:

    As with all downcasts in Swift, casting from AnyObject to a more specific object type is not guaranteed to succeed and therefore returns an optional value

    So when you do

    self.sourceViewController.presentingViewController??
    

    it implicitly translates to something like

     let source: UIViewController? = self.sourceViewController as? UIViewController
     let presenting: UIViewController? = source?.presentingViewController
    

    and that’s why you need two ?: one for resolving the downcast and one for the presentingViewController.

    Finally, always according to the documentation:

    Of course, if you are certain of the type of the object (and know that it is not nil), you can force the invocation with the as operator.

    which is exactly my proposed solution above.