Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I close a Safari App Extension popover programmatically?

I'm building a Safari App Extension using XCode 8.3 and Swift 3, following the Safari App Extension Programming Guide. The extension includes a popover that appears when the extension's toolbar item is clicked. The popover view contains a few buttons linked to actions the user can perform.

I want clicking one of these buttons to close the popover after its action has been performed. By default, clicking anywhere outside of a popover closes it, but I haven't been able to find any other way to close the popover, either in the guide or in the docs.

I know that NSPopover has a performClose method, but there doesn't appear to be a way to access the popover itself from within the extension: the app extension only lets you provide a SFSafariExtensionViewController, whose contents magically appear within the popover.

I've also tried using dismissViewController as described in this StackOverflow answer, but in my view controller self.presenting is always nil, and self.dismissViewController(self) just crashes the extension with the message:

dismissViewController:: Error: maybe this view controller was not presented?.

Lastly, I noticed a related question about programmatically opening the toolbar item popover has gone unanswered the past 6 months. This leads me to suspect Apple may simply have strict limits on how the popover can be opened and closed. Even if this is the case, it would be nice to know for sure what the limitations are.

like image 257
Aaron Frary Avatar asked May 15 '17 22:05

Aaron Frary


1 Answers

I'll add an answer in case anyone stumbles upon this question.

A dissmissPopover() instance method has been added to the SFSafariExtensionViewController class. This can be used to programatically close the popover.

The default template given when creating a Safari App Extension in XCode gives you a SafariExtensionViewController class that extends SFSafariExtensionViewController and holds a shared instance as a static field called 'shared', so you can call the dismissPopover() method from that instance.

For example:

class SafariExtensionHandler: SFSafariExtensionHandler {
    func myFunc() {
        // do stuff;

        SafariExtensionViewController.shared.dismissPopover()

        // do other stuff;
    }
}
like image 68
Burcea Bogdan Madalin Avatar answered Nov 03 '22 15:11

Burcea Bogdan Madalin