大多数浏览器和
Developer App 均支持流媒体播放。
-
Safari 浏览器扩展的新功能
Safari 浏览器扩展可以在 Safari 浏览器中呈现您 app 的独特功能。探索各项最新功能如何让您的 Safari 浏览器 App 扩展和内容拦截器变得更为强大,如内容拦截通知、用户界面管理,以及对页面、标签页和弹出窗口的控制创新。了解最新的 API,以及在您的扩展和 app 之间进行通信的最佳做法。
资源
-
下载
大家好 我是 Brian Weinstein Safari 浏览器团队的一名工程师 今天 我要谈谈 Safari 浏览器扩展的新功能 Safari 浏览器扩展 允许你拓展 Safari 浏览器的行为 你可以通过 向 Web 页面添加脚本或样式表 阻止内容以及 添加到 Safari 浏览器的 UI 来增强用户的浏览体验
我们将要讨论 如何构建和分发 Safari 浏览器扩展 如何通知你的 Safari App 扩展 内容拦截器(Content Blocker)有什么活动 对于扩展中的窗口 选项卡和页面管理的更好的支持 Safari App 扩展弹窗的改进 以及 Safari 浏览器扩展 与包含此扩展的 App 之间 交流的一些最佳实践
我今天要关注 两种类型的 Safari 浏览器扩展 内容拦截器
和 Safari App 扩展 这两个扩展 都与用 Xcode 构建的 Mac App 捆绑在一起
当你从 Mac App Store 安装一个带有 Safari App 扩展的 App 时 该扩展会立即显示在 Safari 浏览器的偏好设置中 并随时可以启用
你也可以 在 App 通过 Notarization 认证后 直接在你的网站上发布它 经过 Notarization 认证的 App 至少需要启动一次 它们的扩展 才能在 Safari 浏览器中显示 我们十分欣赏你创建的 Safari App 扩展 和内容拦截器 也非常感谢那些 在 Safari 开发者论坛上 提出改进建议 提交 Bug 报告 以及做出评论的人
我们听到的 获得最多诉求的特性之一是 希望扩展可以知道 它们的内容拦截器何时执行操作
内容拦截器提供了 一个声明性规则列表 定义了在使用 Safari 浏览器时 要拦截或隐藏的内容 Safari 浏览器在被打开时 内容拦截器时就会向它 请求规则列表
在用户进行浏览的过程中 当你的内容拦截器 将一个资源标记为 应该被拦截的内容时 现在 在 Safari 浏览器 13 中 Safari 浏览器会与你的内容拦截器 将其告诉你的 Safari App 扩展
如果你的用户 想要查看你的统计数据 那么他们可以打开 相关的 Safari App 扩展 或者他们可以选择 只打开内容拦截器来保持最私密的体验 让我们看看 这有多简单 第一步是在扩展的 Info.plist 文件中 将内容拦截器 与 Safari App 扩展关联起来 为此 你需要在 Safari App 扩展的 Info.plist 的 NSExtension 部分中 添加一个新条目
Key 是 SFSafariAssociatedContentBlockers
它的值是 一个内容拦截器 Bundle 的标识符数组 Safari App 扩展希望得到 关于其内容的通知 一个 Safari App 扩展 可以被多个内容拦截器通知 需要记住的一点是 内容拦截器 和 Safari App 扩展 必须包含在同一个 App 中
在你设置好了 Info.plist 之后 你需要在扩展的主体对象上 实现委托方法 该方法是 contentBlocker( withIdentifier blockedResourcesWithURLs, on page)
这些通知是批量处理的 你只会在 Safari App 扩展 拥有它的 Info.plist 的 网站访问部分的访问权限时 获得 URL 的通知
就是这样 现在 让我们继续谈谈 对窗口 选项卡 和页面管理所进行的改进
第一个增强 来自另一个热门的诉求 它是一个可以告诉你 页面何时执行导航的 API 你可以将其以 与你刚刚所听到的 内容拦截器通知相匹配 从而了解关于新的页面加载的 任何通知
第一个增强 来自另一个热门的诉求 它是一个可以告诉你 页面何时执行导航的 API 你可以将其以 与你刚刚所听到的 内容拦截器通知相匹配 从而了解关于新的页面加载的 任何通知 你也可以通过 在加载特定页面时 跟踪重定向链 以便重定向到 网站的特定版本 或者查看 URL 参数 从而确定你的扩展 是否已经向用户显示了它的 UI 即使扩展没有 访问目标 URL 的权限 它也会在扩展的主体对象上 调用此方法 在这种情况下 URL 将为 nil 如果用户打开了 他们的收藏夹或历史记录 URL 也将为 nil
让我们在示例扩展中 运用这些全新的 API
在之前的 WWDC 上 Safari App 扩展刚刚被引入 我们创建了一个扩展 用熊的表情符号 替换了单词“Bear”(熊) 今天 我想继续拓展这个扩展 能够让熊获得 更便捷的上网体验 到目前为止 我已经制作了一个内容拦截器 它可以拦截 URL 中含有蜂蜜的所有图像 可以消除来自甜食的诱惑 让我们将该内容拦截器 与现有的 Safari App 扩展关联起来 首先打开 Safari App 扩展的 Info.plist 文件 为了关联一个内容拦截器 我将向 NSExtension 部分 添加一个与 SF Safari 关联的 内容拦截器条目 我将打开 XML 查看器 来粘贴源代码
然后回到 plist 查看器
它是一个只有一个条目的数组 也就是我的新内容拦截器的 Bundle 标识符 下一步是 监听内容阻止通知
我们要做的是 在 SFSafariPage 和该页面上已被阻止的资源列表之间 构建一个映射 当我们收到内容拦截器 阻塞资源的通知时 我们会找到 该页面的阻止资源列表 并添加上刚才被告知的资源
当页面导航时 我们希望清除该列表
为此 我们将重写函数 page(_page, willNavigateTo url) 并使用它 清除页面的阻止资源
我们要做的最后一件事 是将 的标记 设置为该页面上 被阻止的资源的数量
当我们被要求 验证窗口的 toolbarItem 时 我们要在窗口中 找到活动选项卡 找到它的活动页面 并从地图中获取该页面上被阻止的资源的数量 让我们看看它是如何运作的 我们将构建并运行 Animalify 以便系统能够发现我们的扩展
一旦我们运行了这个 App 你就可以看到带有一个按钮的启动界面 可以将你的用户引导到 Safari 浏览器的扩展偏好设置 如果你在 Xcode 中 创建带有 Safari 浏览器扩展的 App 你就可以免费获得 App 内的启动界面
让我们启动 Safari 浏览器 它会把我带到我的主页 bearseating.com 这样我就可以每天都获得一些食物的灵感。 由于我只是在 尝试编写 Safari 浏览器扩展 所以目前我还没有 Apple 开发者证书 这是没有问题的 因为我可以通过 打开 Safari 的偏好设置 进入“高级”标签页
然后勾选“在菜单栏中显示‘开发’菜单” 在这之后 打开“开发”菜单
并选中“允许未签名的扩展” 从而暂时告诉 Safari 浏览器运行这些扩展 让我们进入 Safari 浏览器的 扩展偏好设置 打开我们的内容拦截器 和 Safari App 扩展 然后重载 bearseating.com 如你所见 内容拦截器拦截了 熊吃蜂蜜的图片 我们的工具栏时间被标记为数字 3 这意味着有 3 个资源被拦截
如果我们在没有内容拦截器的情况下 重新加载页面 toolbarItem 的标记将被清除 你就可以看到再次被拦截的图像 当你再次加载内容拦截器时 这些图像就消失了 完成内容阻止 和页面导航通知 就是如此的容易
这些只是 Safari App 扩展 提供的众多 新 API 中的一部分 让我们再看看其他的 API
我们还添加了 获取 SFSafariPage 可见内容的功能 你的扩展将需要 访问页面的 URL 以便从这个 API 中获取图像数据
使用最新版本的 Safari 浏览器 如今向用户显示 来自 Safari 浏览器扩展包的内容 变得更加容易 现在 你可以从本地代码 获得扩展的 baseURI 无需再注入脚本
你也可以直接将选项卡 导航到 URL 而不需要注入脚本
最后 Safari 浏览器 可以将 Safari JavaScript 对象 注入到任何装载了 来自扩展的内容的帧中 这意味着这些帧 可以向 Safari App 扩展 发送消息并从中接收消息 Safari 浏览器扩展 现在可以找到 Safari 浏览器中 所有打开的选项卡和窗口 而不仅仅是活动窗口和选项卡
在这里 你可以看到 获取 App 中所有窗口的代码 所有选项卡
你还可以获得 对包含选项卡的页面 和包含窗口的选项卡的引用
例如 为了处理来自内容脚本的消息 你需要更新该窗口中的 toolbarItem 你可以获得包含选项卡的页面 以及包含窗口的选项卡
需要记住的一点是 固定的选项卡将有 一个包含 nil 的窗口 因为它们属于所有窗口 而不是单个父窗口
这些就是对窗口 选项卡和页面管理的改进
最后一组 API 改进 是针对 Safari App 扩展的弹窗的 现在你可以通过编程 显示和关闭弹窗 你可以通过在 SFSafariToolbarItem 上 调用 showPopover() 来显示弹窗 你可以从显示弹窗的窗口中 获得该 toolbarItem 通过弹窗视图控制器 弹窗可以被关闭 你只需要调用 self.dismissPopover()
让我们来看看 我们将如何通过添加这些新 API 来改进我们的扩展
利用这些全新的 API 我想升级我的 Safari 浏览器扩展 当我点按 toolbarItem 时 我希望显示一个 带有表视图的弹窗 每个选项卡 将有一行和两列 左边一列 将是选项卡的屏幕快照 右边一列将显示页面的标题 以及每个域 阻止了多少资源
这个过程的第一步是 在显示弹窗之前 告诉弹窗视图控制器 Safari 浏览器窗口的状态 为此 我将重写 popoverWillShow() 函数 并让它收集此信息
如你所见 这个函数迭代了窗口中的所有选项卡 并填充了 3 个数组 一个用于被阻止的资源 一个用于图像 一个用于标题
对于每个选项卡 我们将得到 页面可见区域的屏幕快照 页面属性中每个页面的标题 以及每个页面的 被阻止资源列表
我们也开始重写 弹窗视图控制器 来返回视图控制器 让我们看一下视图控制器
设置弹窗状态 在类中设置一些实例变量 然后重新加载表视图
我们要做的最后一件事是 当用户点按其中一行时 我们要激活该选项卡 然后关闭弹窗
当表视图选择发生变化时 我们激活用户点按的选项卡 然后关闭弹窗口 现在 让我们再次构建 并运行 Animalify
我们会再次启动 Safari 浏览器 来加载我们的主页 你可以看到 扩展不再打开 这是因为 每次启动 Safari 浏览器时 都必须允许未签名的扩展 让我们在“开发”菜单中进行设置
然后我们打开 App 让它引导我们找到扩展
我们将打开扩展 和内容拦截器 并重新加载页面 我们还会再打开几页
你将注意到 当我们在 bearseating.com 处 更改选项卡时 toolbarItem 的标记就会被清除 让我们打开弹窗
你可以在窗口中看到每个标签 在第一行中 你可以看到我们的内容拦截器拦截了 来自 beardiet.com 的两个资源 和来自 bearseating.com 的一个资源 让我们通过点按第一行 来激活那个选项卡 然后我们回到了那个选项卡 弹窗被关闭 我们今天讨论的 API 只是新 API 的其中一些
最后 我想介绍一些 关于如何在 Safari 浏览器扩展和 App 之间 进行通信的最佳实践
Safari 浏览器 会在必要时启动 App 扩展 这并不能保证 你的 App 正在运行
但是如果你有一个 带有 XPC 服务的 App 你的扩展可能希望与 这个 XPC 服务通信 或者你希望 Safari 浏览器扩展 和 App 之间共享数据 你的扩展可能支持用户 在你的 App 中 进行偏好设置
为此 你需要让你的 Safari 浏览器扩展 和 XPC 服务 处在与你的 App 相同的 App 组中 这将允许你的 Safari 浏览器扩展 在同一 App 组 查找已命名的 Mock 服务 你可以使用 UserDefaults(suiteName:) 初始化器 从而共享整个 App 组的数据
然而 假设用户在 App 中 执行了一个 最好由 Safari App 扩展来处理的操作 例如 你正在编写 密码管理器 用户需要在 App 中选择要填写的凭据 这就不能保证 你的扩展正在运行 或者 Safari 浏览器正在运行
你可以从你的 App 调用一个 API 来向你的 Safari App 扩展发送一条消息 你的 App 调用 SFSafariApplication.dispatchMessage (withName, toExtensionWithIdentifier) 只有在你的扩展被激活 并且扩展必须与 调用 API 的代码 位于同一个 App 包中时 这个方法才会生效
调用这个 API 将向 Safari 浏览器发送一条消息 并且在需要时启动它
Safari 浏览器会将此消息 转发给 Safari App 扩展
你的 Safari App 扩展 可以通过将 来自包含扩展的 App 的消息 实现为 在扩展的主体对象中的用户名信息 来监听这些消息 让我们后退一步 看看你的 App 和 Safari 浏览器扩展 得以通信和共享数据 所有可行的方法
如果你的 App 和 Safari 浏览器扩展 位于同一个 App 中 你可以使用 NSXPCConnection 在它们之间通信 或使用用户默认值共享数据 如果你想从 App 向 Safari App 扩展发送消息 可以使用 SFSafariApplication.dispatchMessage 来发送消息 并监听来自包含 Safari App 扩展的 App 处接收的消息 从而处理消息 你可以通过上述的方法 在你的 App 和 Safari 浏览器扩展之间进行通信
以上就是我们 今天要讲的内容 我希望你们能从这段视频中 学到几件主要的事情 你可以通过 Mac App Store 发布你的 Safari 浏览器扩展 或者通过你的网站 发布通过了 Notarization 认证的 App
你可以将你的内容拦截器 与 Safari App 扩展关联起来 这样你就可以知道 你的内容拦截器 何时执行拦截操作
你可以使用 App 群组 在 Safari 浏览器扩展 和 App 之间进行通信
我们今天讨论的 所有这些 API 的实现 多亏了你的反馈和诉求 请继续提交 改进建议 并在论坛上联系我们 谢谢大家花时间观看我的演讲 我们已经迫不及待地 想看看你们的扩展成果了
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。