UIWebViewにおけるAdBlockはNSURLCacheを使った実装が有名ですが、iOS8では動いてくれなかったのでNSURLProtocolを使って実装してみました。
ViewController.swift
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var webview: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
// 自前のクラスを登録する
NSURLProtocol.registerClass(FilteredURLProtocol)
let url = NSURL(string: "http://www.yahoo.co.jp")!
let request = NSURLRequest(URL: url)
webview.loadRequest(request)
}
}
FilteredURLProtocol.swift
import UIKit
class FilteredURLProtocol: NSURLProtocol {
override class func canInitWithRequest(request: NSURLRequest) -> Bool {
let host = request.URL.host
// ホスト名が広告配信元か否かを判定
if host?.rangeOfString("ads") != nil {
return true;
}
return false
}
override class func canonicalRequestForRequest (request: NSURLRequest) -> NSURLRequest {
return request;
}
override func startLoading() {
let response = NSURLResponse(URL: self.request.URL,
MIMEType: nil,
expectedContentLength: 0,
textEncodingName: nil)
self.client?.URLProtocol(self,
didReceiveResponse: response,
cacheStoragePolicy: NSURLCacheStoragePolicy.NotAllowed)
self.client?.URLProtocol(self, didLoadData: NSData(bytes: nil, length: 0))
self.client?.URLProtocolDidFinishLoading(self)
}
override func stopLoading() {}
}
canInitWithRequestメソッドでホスト名を確認し、広告を配信するホスト名の場合はtrue、それ以外はfalseを返します。
trueの場合はstartLoadingメソッドが呼ばれ、独自の処理が実行されます。
この場合は、URL先のデータを読みに行かず、空のデータを読み込むようにしています。
ちなみにWKWebViewでは動きません。