[iOS] WKWebViewのCookieとキャッシュを削除したい

2018/06/7

こんにちは。きんくまです。

フォルメモをアップデートしました。
リリース時からバズることなどなくゆっくりとダウンロードされていまして、おかげさまで6万ダウンロードされました。
ありがとうございます。
>> フォルダと メモ帳 フォルメモ

今回のアップデート内容について。
フォルメモにはメモにスクリーンショットやテキストを簡単に追加できる内部ブラウザが入っています。
その内部ブラウザのWKWebViewのCookieとキャッシュを削除できるようにしました。

この記事はそのときのメモでございます。参考サイトです。

>> ios – How to delete WKWebview cookies – Stack Overflow

記事にもあるようにこの方法はiOS9以降が対象です。iOS8以下は削除方法が違います。

WKWebsiteDataStoreを使って消去

WKWebsiteDataStoreからWKWebViewで保存しているデータにアクセスが可能なようです。

>> WKWebsiteDataStore – WebKit | Apple Developer Documentation

fetchDataRecordsで各サイトごとに保存してあるデータを取得して
removeDataで実際に消去します。

fetchしたときに取得できるデータは>> WKWebsiteDataRecordの配列になっています。

これはどんな値なのかというと、CookieとかキャッシュとかlocalStorageとか、サイトごとに保存しているデータです。
>> Available Data Types

実際のコード

ボタンとかを押したときに、確認アラートを表示して、OKだったら削除する流れで書いてみました。

    func startCookieDeletion(){
        let deleteDataTypes:Set<String> = [WKWebsiteDataTypeCookies]
        let confirmMessage = "Cookieを削除するけどOK?"
        let completeMessage = "Cookie削除完了デース"
        startBrowserDataDeletion(deleteDataTypes: deleteDataTypes,
                                 confirmMessage: confirmMessage,
                                 completeMessage: completeMessage)
    }
    
    func startBrowserCacheDeletion(){
        //Cookie以外全部を対象にしたい。全部を取得した後にCookieを抜く
        var deleteDataTypes:Set<String> = WKWebsiteDataStore.allWebsiteDataTypes()
        deleteDataTypes.remove(WKWebsiteDataTypeCookies)
        
        let confirmMessage = "キャッシュ削除するけどOK?"
        let completeMessage = "キャッシュ削除完了デース"
        startBrowserDataDeletion(deleteDataTypes: deleteDataTypes,
                                 confirmMessage: confirmMessage,
                                 completeMessage: completeMessage)
    }
    
    func startBrowserDataDeletion(deleteDataTypes:Set<String>, confirmMessage:String, completeMessage:String){
        let alertController:UIAlertController = UIAlertController(title: nil, message: confirmMessage, preferredStyle: UIAlertControllerStyle.alert)
        
        let cancelAction:UIAlertAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel) { (action:UIAlertAction) -> Void in
            
        }
        alertController.addAction(cancelAction)
        
        let okAction:UIAlertAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default) { [unowned self](action:UIAlertAction) -> Void in
            self.deleteBrowserData(deleteDataTypes: deleteDataTypes, completeMessage: completeMessage)
        }
        alertController.addAction(okAction)
        
        self.present(alertController, animated: true) {() -> Void in
            
        }
    }
    
    //fetchして削除する部分です
    func deleteBrowserData(deleteDataTypes:Set<String>, completeMessage:String){
            
        let dataStore = WKWebsiteDataStore.default()
        dataStore.fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) { (records:[WKWebsiteDataRecord]) in
            
            var clearTargetRecords:[WKWebsiteDataRecord] = []
            
            for record in records {
                for deleteDataType in deleteDataTypes {
                    if record.dataTypes.contains(deleteDataType) {
                        clearTargetRecords.append(record)
                        break
                    }
                }
            }
            if clearTargetRecords.count > 0 {
                dataStore.removeData(ofTypes: deleteDataTypes, for: clearTargetRecords, completionHandler: {
                    [unowned self]() in
                    self.showBrowserDataDeletionComplete(completeMessage: completeMessage)
                })
            } else {
                //1つもなくて削除してないんだけど、安心させるため削除完了アラートだしておく
                self.showBrowserDataDeletionComplete(completeMessage: completeMessage)
            }
        }
    }
    
    func showBrowserDataDeletionComplete(completeMessage:String){
        let alertController:UIAlertController = UIAlertController(title: nil, message: completeMessage, preferredStyle: UIAlertControllerStyle.alert)
        
        let okAction:UIAlertAction = "OK", style: UIAlertActionStyle.default) { (action:UIAlertAction) -> Void in
            
        }
        alertController.addAction(okAction)
        
        self.present(alertController, animated: true) {() -> Void in
            
        }
    }

悩んだところ

いわゆるキャッシュというのが何を指しているのか実は実装上で悩みました。IEとかChromeとかの削除機能を見ていたんだけど、これってCookieの削除はCookieだけを指しているのか?キャッシュの削除というのは何を指しているのか?

結局今回はCookieとそれ以外全部に分けて実装しました。
最初WKWebsiteDataTypeSessionStorageというのがあって、あれ?これってセッション情報に関係するのかな?と思ったんだけど、調べて見たところLocalStorageの仲間の様子。

>> sessionStorageをつかってみる

なのでCookieとそれ以外に分けたという感じです。うーん、合ってるかどうかはわかりませんが、とりあえず貯まっているデータは削除できるのでよしとする。

ではでは。

LINEで送る
Pocket

自作iPhoneアプリ 好評発売中!
フォルメモ - シンプルなフォルダつきメモ帳
ジッピー電卓 - 消費税や割引もサクサク計算!

LINEスタンプ作りました!
毎日使える。とぼけたウサギ。LINEスタンプ販売中! 毎日使える。とぼけたウサギ

ページトップへ戻る