Search code examples
swiftsafarisafari-extensionsfsafariviewcontroller

Accessing Current Page Information in Safari 12 Extension Popover


I'm trying to get the active tab's page information to be displayed in a popover. I'm able to get it to show the URL or Title of the page currently, but it requires opening and closing the extension popover twice.

I believe it's because to get that information, the below code relies on completionHandler which makes it async.

SFSafariApplication.getActiveWindow { (window) in
    window?.getActiveTab { (tab) in
        tab?.getActivePage(completionHandler: { (page) in
            page?.getPropertiesWithCompletionHandler( { (properties) in
                self.pageTitle = properties?.title ?? "Unknown"
                self.ActivePageTitle.stringValue =  self.pageTitle
            })
        })
    }
}

The first time you open the popover it shows a blank text region, but the second time it will have loaded in the information before and shows it correctly.

I've tried running it in viewDidLoad() but that only fires the first time the popover is opened.

When running it in viewWillAppear() I get the below error:

pid(17738)/euid(501) is calling TIS/TSM in non-main thread environment,
ERROR : This is NOT allowed. Please call TIS/TSM in main thread!!!

I thought maybe switching the extension to use a command instead would work but then realized you can't programatically open the popover window.

Do I have to switch to UITableView or something that has a reloadData() function to run once the async request for data is complete?

MacOS 10.14.4 | Safari 12.1 | Xcode 10.2


Solution

  • Try updating your UI code on the main thread. Wrap the page title updates in DispatchQueue. I had almost the exact same issue, and this worked for me.

    SFSafariApplication.getActiveWindow { (window) in
        window?.getActiveTab { (tab) in
            tab?.getActivePage(completionHandler: { (page) in
                page?.getPropertiesWithCompletionHandler( { (properties) in
                    DispatchQueue.main.async {
                        self.pageTitle = properties?.title ?? "Unknown"
                        self.ActivePageTitle.stringValue =  self.pageTitle
                    }
                })
            })
        }
    }
    

    To give proper credit, I found the answer while digging through this code on GitHub (check out the updateDataLabels() method): https://github.com/otzbergnet/tabCount/blob/master/tabCount%20Extension/SafariExtensionViewController.swift