4 Replies
      Latest reply on Mar 30, 2020 11:02 AM by bruno.cm
      bruno.cm Level 1 Level 1 (0 points)

        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?