Hello,
I've filled a radar about this issue: FB7597364 but I'm wondering if anyone has a reliable workaround for this issue.
I have made a Safari app extension which allows users to suspend tabs. Unfortunately, because the baseURI changes each time Safari starts the user sees a "Cannot load page" error in the tabs that were suspended in the previous session, see a suspended page is hosted by the extension it self.
Steps to reproduce:
- Extension opens a new tab with the url, eg: safari-extension://AAAAAAA-0000-1111-2222-A0A0A0A0/7075e8a3/suspended.html
- User restarts Safari
- The tab shows "Page cannot be loaded" beacause the baseURI changed, since, as far as I know, it's not possible to make the baseURI unachangeable like on other browsers.
My temporary workaround (which fails sometimes) is to, when the extension first loads in that session, iterate all tabs and look for urls that match the suspended pattern:
override func validateToolbarItem(in window: SFSafariWindow, validationHandler: @escaping ((Bool, String) -> Void)) {
// This is called when Safari's state changed in some way that would require the extension's toolbar item to be validated again.
if (!SafariExtensionHandler.safariFirstLoad) { // static var
SafariExtensionHandler.safariFirstLoad = true;
print("loaded")
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
SFSafariApplication.getActiveWindow { (activeWindow) in
activeWindow?.getActiveTab { (activeTab) in
SFSafariExtension.getBaseURI { baseURI in
guard let baseURI = baseURI else { return };
SFSafariApplication.getAllWindows { windows in
for window:SFSafariWindow in windows {
window.getAllTabs { tabs in
var i = 1;
for tab:SFSafariTab in tabs {
tab.getActivePage(completionHandler: { page in
page?.getPropertiesWithCompletionHandler( { properties in
if (properties?.url != nil) {
let tabUrl: URL = (properties?.url)!;
i = i+1;
if (tabUrl.scheme == "safari-extension" && tabUrl.path.hasSuffix("suspended.html") && !tabUrl.absoluteString.starts(with: baseURI.absoluteString)) {
tab.activate {
tab.navigate(to: URL(string: "\(baseURI.absoluteString)suspended.html?\(tabUrl.query!)")!);
if (i >= tabs.count) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
activeTab?.activate(completionHandler: {
});
}
}
}
}
}
});
});
}
}
}
}
}
}
}
}
}
validationHandler(true, "");
}
Unfortunately this does not work 100% of the times as page?.getPropertiesWithCompletionHandler returns nil sometimes.
Any ideas on what else I could do?