safari应用程序扩展:从swift后台进程向所有选项卡广播消息

safari应用程序扩展:从swift后台进程向所有选项卡广播消息,swift,safari,safari-app-extension,Swift,Safari,Safari App Extension,在旧版扩展中,可以迭代safari.application.activeBrowserWindow.tabs,将消息发送到注册该扩展的所有选项卡 新的safari应用程序扩展是否有类似的功能 我一直在浏览文档,但没有找到任何关于如何实现这一基本目标的提示 一个可怕的解决办法是让所有标签都在Swift背景上,但实际上这是一件非常基本的事情,它似乎很荒谬,因为它不可用或不在文档中,我是否遗漏了什么 我还尝试保留“messageReceived”处理程序看到的所有“page”实例的弱映射,希望SFSa

在旧版扩展中,可以迭代
safari.application.activeBrowserWindow.tabs
,将消息发送到注册该扩展的所有选项卡

新的safari应用程序扩展是否有类似的功能

我一直在浏览文档,但没有找到任何关于如何实现这一基本目标的提示

一个可怕的解决办法是让所有标签都在Swift背景上,但实际上这是一件非常基本的事情,它似乎很荒谬,因为它不可用或不在文档中,我是否遗漏了什么

我还尝试保留“messageReceived”处理程序看到的所有“page”实例的弱映射,希望SFSafariPage引用会一直保留到选项卡关闭,但它们几乎立即丢失,这表明它们比实际的Safari页面更多的消息通道。

下一步应该是: 在
injected.js
中,您将消息发送到您的应用程序ext,例如

document.addEventListener("DOMContentLoaded", function (event) {
    safari.extension.dispatchMessage('REGISTER_PAGE')
})
应用程序内的ext使用smth处理它,如下所示:

var pages: [SFSafariPage] = []

class SafariExtensionHandler: SFSafariExtensionHandler {

    override func messageReceived(withName messageName: String, from page: SFSafariPage, userInfo: [String : Any]?) {
        switch messageName {
        case "REGISTER_PAGE":
            if !pages.contains(page) {
                pages.append(page)
            }
        default:
            return
        }
    }

}
for p in pages {
    p.dispatchMessageToScript(withName: "message name", userInfo: userInfo)
}
那么,您可以通过smth在运行时将消息发送到所有打开的页面,如下所示:

var pages: [SFSafariPage] = []

class SafariExtensionHandler: SFSafariExtensionHandler {

    override func messageReceived(withName messageName: String, from page: SFSafariPage, userInfo: [String : Any]?) {
        switch messageName {
        case "REGISTER_PAGE":
            if !pages.contains(page) {
                pages.append(page)
            }
        default:
            return
        }
    }

}
for p in pages {
    p.dispatchMessageToScript(withName: "message name", userInfo: userInfo)
}
它看起来很粗糙,但仍然可行。享受:)

下一条路应该是: 在
injected.js
中,您将消息发送到您的应用程序ext,例如

document.addEventListener("DOMContentLoaded", function (event) {
    safari.extension.dispatchMessage('REGISTER_PAGE')
})
应用程序内的ext使用smth处理它,如下所示:

var pages: [SFSafariPage] = []

class SafariExtensionHandler: SFSafariExtensionHandler {

    override func messageReceived(withName messageName: String, from page: SFSafariPage, userInfo: [String : Any]?) {
        switch messageName {
        case "REGISTER_PAGE":
            if !pages.contains(page) {
                pages.append(page)
            }
        default:
            return
        }
    }

}
for p in pages {
    p.dispatchMessageToScript(withName: "message name", userInfo: userInfo)
}
那么,您可以通过smth在运行时将消息发送到所有打开的页面,如下所示:

var pages: [SFSafariPage] = []

class SafariExtensionHandler: SFSafariExtensionHandler {

    override func messageReceived(withName messageName: String, from page: SFSafariPage, userInfo: [String : Any]?) {
        switch messageName {
        case "REGISTER_PAGE":
            if !pages.contains(page) {
                pages.append(page)
            }
        default:
            return
        }
    }

}
for p in pages {
    p.dispatchMessageToScript(withName: "message name", userInfo: userInfo)
}

它看起来很粗糙,但仍然可行。享受:)

类似于答案的东西可能就是你想要的。不幸的是不是,这是属于同一领域的用户和上下文之间的通信。我需要从swift扩展广播到浏览器中的所有注入选项卡。尝试使用
localStorage
。类似于pen。这不是一个与用户登录网页相关的问题,我编辑了标题以明确这是关于扩展级别的消息。Safari扩展仍然支持本地存储访问,看起来是您唯一的选择。类似于answer的内容可能是您想要的。不幸的是不是,这是属于同一领域的用户和上下文之间的通信。我需要从swift扩展广播到浏览器中的所有注入选项卡。尝试使用
localStorage
。类似于pen。这不是一个与用户登录网页相关的问题,我编辑了标题以明确这是关于扩展级别的消息。Safari扩展仍然支持本地存储访问,看起来是您唯一的选择。每当messageReceived第一次看到页面时,我都会收集“页面”地图。但是如果我们没有办法知道什么时候注销一个页面,我担心这可能会导致非常糟糕的内存泄漏或重影引用。。。我尝试使用weakMap,但对消息页面的引用几乎立即丢失。另外,当使用weakMap时,随着时间的推移,messageReceived将从同一页面接收不同的“页面”指针。。。这就意味着我们保留那些过去的引用是在浪费内存。@paolo.caminiti是的,你说的内存泄漏是完全正确的。为了使解决方案更可靠,您可以在触发
onbeforeunload
事件时从injected.js发送消息。因此,您可以从页面映射中删除目标页面,并只向活动页面发送广播。每当messageReceived第一次看到页面时,我都会收集“页面”的映射。但是如果我们没有办法知道什么时候注销一个页面,我担心这可能会导致非常糟糕的内存泄漏或重影引用。。。我尝试使用weakMap,但对消息页面的引用几乎立即丢失。另外,当使用weakMap时,随着时间的推移,messageReceived将从同一页面接收不同的“页面”指针。。。这就意味着我们保留那些过去的引用是在浪费内存。@paolo.caminiti是的,你说的内存泄漏是完全正确的。为了使解决方案更可靠,您可以在触发
onbeforeunload
事件时从injected.js发送消息。所以,您可以从页面映射中删除目标页面,并仅向活动页面发送广播。