とり研

iPhoneアプリ開発とかプログラミングとかの話題。

SwiftでUIWebViewのカスタムキャッシュを実装する -すべてが鳥になる-

この記事は、仙台iOS開発者勉強会(SWWDC) Advent Calendar 2014 - Qiita 11日目の記事です。

UIWebViewのキャッシュを自前実装する

UIWebViewのキャッシュは、ユーザーがある程度自由に設定できる。

例えば、画像ファイルやcssやjsなど、重くてローディングに時間がかかるファイルを、あらかじめアプリ内に含めておくことで、UIWebViewのローディング速度を向上させる事ができるかもしれない。

参考サイト:Cocoaの日々: [iOS] UIWebView のキャッシュ調査

カスタムキャッシュ作成手順

  1. NSURLCacheのサブクラスを作成し、cachedResponseForRequestをオーバーライドする。このなかに、カスタムのキャッシュ処理を書く。  (例えば、...example.jpg のリクエストが来たら、アプリ内のファイルを読んで返すなど。)
  2. (1.)で作成したクラスを、NSURLCache.setSharedURLCache()で設定する。これでアプリ内のUIWebViewでは、カスタムのキャッシュが使用される。

すべてが鳥になる

カスタムキャッシュを応用すると、Webサイト上のすべての画像を鳥にすることだって可能になる。以下にソースコードを示す。

class CustomCache: NSURLCache {

    override func cachedResponseForRequest(request: NSURLRequest) -> NSCachedURLResponse? {
        let url = request.URL
        
        // 拡張子が jpg or png or gifの場合は、鳥の画像を返す。
        if url.pathExtension == "jpg" || url.pathExtension == "png" || url.pathExtension == "gif" {
            let path = NSBundle.mainBundle().pathForResource("gogogogo_icon", ofType: ".png")
            let filedata = NSData(contentsOfFile: path!)
            
            let response = NSURLResponse(URL: url,
                MIMEType: "image/png",
                expectedContentLength: filedata!.length,
                textEncodingName: nil)

            return NSCachedURLResponse(response: response, data: filedata!)
        }
        
        return super.cachedResponseForRequest(request)
    }
}

CustomCacheクラスは、「拡張子が jpg or png or gifの場合は、鳥の画像に差し替える」という単純なキャッシュ処理を行っている。

上記クラスを作成した上で、didFinishLaunchingWithOptions内で、アプリ内のキャッシュにCustomCacheクラスを使用する設定をする。

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        
        NSURLCache.setSharedURLCache(CustomCache())
        
        return true
    }

これでWebサイトを閲覧すると...(例:はてなのトップページ)これが

f:id:tototti:20141211232928p:plain

こうなる。

f:id:tototti:20141211232953p:plain

すべてが鳥になった。

余談

作成したカスタムキャッシュは、ファイルの拡張子をチェックしているだけなので、画像ファイルに拡張子をつけていないWebサイトではあまり効果が見られないのであった。。。