[iOS9]広告ブロック(Content Blocking Safari Extensions)の作り方


まず、「広告ブロック」とは言ってもコンテンツ制御のうちの一つの呼び名（みんながそう言ってる）であるだけで、単純に広告をブロック出来るわけではない点を理解しておいたほうがいいです。

[Content Blocking Safari Extensions](https://developer.apple.com/library/prerelease/ios/releasenotes/General/WhatsNewInSafari/Articles/Safari_9.html#//apple_ref/doc/uid/TP40014305-CH9-SW8)
[Surfin' Safari - Blog Archive » Introduction to WebKit Content Blockers](https://www.webkit.org/blog/3476/content-blockers-first-look/)

Cookieや画像、リソース、ポップアップなどなどブロックできるコンテンツは様々です。
作成するアプリ（エクステンション）で目的に見合った実装をしていくことになります。

なお、このドキュメントでは個々の実装例は詳しく掲載していません。

サンプルをもとに Content Blocking Safari Extensions の例を流れを追って説明しています。

# 開発の流れ

1. プロジェクト作成
2. エクステンション追加
3. JSONファイルでフィルタリング作成
4. 実行（設定でコンテンツブロッカー有効化）


## 1. プロジェクト作成

まずはプロジェクトを作成します。
サンプルの動作確認のためコードは一切書きませんので、とりあえずシングルビューアプリケーションで作成しておきます。
プロジェクト名は適当に「adblock」としておきました。

![スクリーンショット 2015-09-25 15.59.08.png](https://qiita-image-store.s3.amazonaws.com/0/69402/cc6ba8d8-075e-2206-7f0c-3de5ef9302fa.png "スクリーンショット 2015-09-25 15.59.08.png")


![スクリーンショット 2015-09-25 15.59.26.png](https://qiita-image-store.s3.amazonaws.com/0/69402/3b8f4e50-fc15-1562-f93d-6256e6e3b2e0.png "スクリーンショット 2015-09-25 15.59.26.png")

## 2. エクステンション追加

つづいてエクステンションを追加します。
File > New > Target

![スクリーンショット 2015-09-25 15.41.22.png](https://qiita-image-store.s3.amazonaws.com/0/69402/742d7d75-b803-9300-a46d-14bdafb216bf.png "スクリーンショット 2015-09-25 15.41.22.png")

Application Extension から Content Blocker Extension を選択します。

![スクリーンショット 2015-09-25 15.41.51.png](https://qiita-image-store.s3.amazonaws.com/0/69402/ce3d100e-1b6e-179b-b551-8ce396c5a34f.png "スクリーンショット 2015-09-25 15.41.51.png")

ターゲット名も適当に「adbanner」としておきます。

![スクリーンショット 2015-09-25 15.42.33.png](https://qiita-image-store.s3.amazonaws.com/0/69402/cd9eb312-19ee-f128-2bb1-03a59547d3f9.png "スクリーンショット 2015-09-25 15.42.33.png")

追加が終わるとプロジェクトツリーは次のようになっています。

## 3. JSONファイルでフィルタリング作成

blockerList.json を表示してみるとサンプルのブロックフィルターが設定されているのが確認できます。

サンプルでは webkit.org/images/icon-gold.png をブロックする（非表示にする）設定が書かれています。

**なお、trigger.url-filter, action.type は必須、それ以外はオプショナルです（ action.type= css-display-none のときは selector が必要です）。詳しくはドキュメント最初のブログアーカイブのリンク先や検索にてお調べください。**

![スクリーンショット 2015-09-25 15.40.54.png](https://qiita-image-store.s3.amazonaws.com/0/69402/19319844-abee-e561-e7d9-ef1e7b9cbe51.png "スクリーンショット 2015-09-25 15.40.54.png")

## 4. 実行（設定でコンテンツブロッカー有効化）

ここで一旦、Safari で webkit.org を表示してみましょう。

まだコンテンツブロックがされていない状態でのスクリーンショットでは、左上の画像（これが icon-gold.png です）が表示された状態なのが確認できます。

![IMG_6603.PNG](https://qiita-image-store.s3.amazonaws.com/0/69402/b046b448-0c6a-5329-2de9-bf731737fac3.png "IMG_6603.PNG")

Xcode に戻って先ほどの状態のままビルドしてみます。

Extension をビルドターゲットにしていると実行アプリを聞かれるので Safari を選択して Run してみましょう。（ adblock が表示されているのは一回ビルドしてるためなので、初回ビルド時は一覧にはありません）

![スクリーンショット 2015-09-25 15.40.07.png](https://qiita-image-store.s3.amazonaws.com/0/69402/dededbea-c09a-797d-96e1-ad5b1ece8f0e.png "スクリーンショット 2015-09-25 15.40.07.png")

ビルド状態でページ更新などしてみても画像が消える気配がないので（一応 Safari の設定ではコンテンツブロッカーが有効にはなっている）、一旦実行を停止して設定アプリを開きます。

設定 > Safari

一般の項目に「コンテンツブロッカー」項目が増えているのが確認できます。

![IMG_6604.PNG](https://qiita-image-store.s3.amazonaws.com/0/69402/bca89283-89fc-f61d-3f3a-10cc834b08ba.png "IMG_6604.PNG")

設定をオフ／オンして再度有効化してみます。

![IMG_6602.PNG](https://qiita-image-store.s3.amazonaws.com/0/69402/0282ed94-1b5c-35b4-46d4-03ee7346cd48.png "IMG_6602.PNG")

Safari に戻ってページを更新してみると、画像が消えました。

![IMG_6601.PNG](https://qiita-image-store.s3.amazonaws.com/0/69402/2a587fb3-8048-5676-7b4a-9d9db795bf63.png "IMG_6601.PNG")

以上がコンテンツブロックの基本的な開発の流れになります。

JSON ファイルでフィルタリングすることで、いろいろなコンテンツを制御できるエクステンションの開発が（ iOS9.0 から）可能になりました。

JSON を動的に制御したり？詳しいことはちょっとわかりませんが、ActionRequestHandler.swift ファイルで設定によって JSON ファイルを切り替えたり、正規表現は使えるようなので割りと汎用性のあるブロッキングは簡単に作れそうです。

# 実例

Google広告をブロックする

```JSON:blockerList.json
[
    {
        "action": {
            "type": "css-display-none",
            "selector": ".adsbygoogle"
        },
        "trigger": {
            "url-filter": ".*"
        }
    }
]
```


# 補足

コンテンツブロッカーの設定は UIWebView 内では有効になりません。

iOS9 から追加された SFSafariViewController を利用してウェブページを表示することで Safari の機能（今回の場合、コンテンツブロッカー）を使用できるようです。

**また、コンテンツブロッカーは64ビットデバイスでしか使えないため、（同発の 5c 除く）iPhone5s 以降となります（すみませんが iPad については各自お調べください）。**