确定用户是否已启用应用程序的 Safari 内容拦截器扩展

Determine if user has enabled application's Safari content blocker extension

我正在研究 Safari Content Blocking extension。如果扩展被禁用,我打算显示设置说明,如果相反启用,我打算显示设置。如何判断扩展是否被用户启用?

我已经看到 this method 检测自定义键盘是否已激活,但 NSUserDefaults 上没有与 Safari 内容拦截器相关的键。

您可以使用 SFSafariViewController 加载自定义网站。该网站检查它是否能够显示您的内容拦截器应该拦截的内容。然后重定向到您的应用先前注册的相应自定义 url (success/failure)。您甚至可以使用不带动画的隐藏 Safari View Controller 来避免从用户角度来看造成任何干扰(如图所示 here). (I guess this technique is used by former content blocker Peace

步骤

应用

  1. 为 success/failure
  2. 注册自定义 URLs
  3. 使用 NotificationCenter(例如 contentBlockerEnabled)
  4. 使用SFSafariViewController显示自定义网站并在blockerList.json中包含以下规则:

    {
        "action": {
            "type": "css-display-none",
            "selector": ".blocked_selector"
        },
        "trigger": {
            "url-filter": ".*"
        }
    }
    

网站

  1. Check for blocked content:

    if($('.blocked_selector').css('display') == "none") {
       // Content blocker enabled
    }
    
  2. 重定向到自定义 URL (success/failure)

应用

  1. Post 通知来自 application:openURL:options:(success/failure 基于调用 url)

18 月 1 日更新

, I built the proposed solution. I wrote about what I learnt on Medium and you can grab the source files from GitHub 开始。

TL;DR 它可以工作,但由于内容阻止规则数据库更新产生的延迟,所以只能在气质上起作用。一个潜在的解决方法是重定向测试页面以创建人为延迟。

自 iOS 10 起,SFContentBlockerManager 中有一个新方法支持此功能:

getStateOfContentBlocker(withIdentifier:completionHandler:)

你这样称呼它 (Swift 3):

SFContentBlockerManager.getStateOfContentBlocker(withIdentifier: "your.identifier.here", completionHandler: { (state, error) in
    if let error = error {
        // TODO: handle the error
    }
    if let state = state {
        let contentBlockerIsEnabled = state.isEnabled
        // TODO: do something with this value
    }
})