web-dev-qa-db-ja.com

WKWebview Cookieを削除する方法

今のところ私はこのようにしています

    NSHTTPCookie *cookie;
    NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    for (cookie in [storage cookies])
    {
        [storage deleteCookie:cookie];
    }

ただし、iOS 8、64ビットデバイスでは動作しません。

他の方法でWKWebviewのCookieを削除しますか?任意の助けをいただければ幸いです。ありがとう。

22
Pankaj Gaikar

AppleはiOS 9の新しいAPIをリリースしたため、WKWebViewに保存されているドメイン固有のCookieを削除できるようになりました=以下のコードで、ただしこれはiOSバージョン9orlater

WKWebsiteDataStore *dateStore = [WKWebsiteDataStore defaultDataStore];
[dateStore
   fetchDataRecordsOfTypes:[WKWebsiteDataStore allWebsiteDataTypes]
   completionHandler:^(NSArray<WKWebsiteDataRecord *> * __nonnull records) {
     for (WKWebsiteDataRecord *record  in records) {
       if ( [record.displayName containsString:@"facebook"]) {
         [[WKWebsiteDataStore defaultDataStore]
             removeDataOfTypes:record.dataTypes
             forDataRecords:@[record]
             completionHandler:^{
               NSLog(@"Cookies for %@ deleted successfully",record.displayName);
             }
         ];
       }
     }
   }
 ];

上記のスニペットはiOS 9以降で動作します。残念ながらWKWebViewを使用する場合iOS 9、以下のように従来の方法に固執し、Cookieストレージ全体を削除する必要があります。

NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *cookiesFolderPath = [libraryPath stringByAppendingString:@"/Cookies"];
NSError *errors;
[[NSFileManager defaultManager] removeItemAtPath:cookiesFolderPath error:&errors];

以下はSwift 3バージョン

let dataStore = WKWebsiteDataStore.default()
    dataStore.fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) { (records) in
        for record in records {
            if record.displayName.contains("facebook") {
                dataStore.removeData(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes(), for: [record], completionHandler: {
                    print("Deleted: " + record.displayName);
                })
            }
        }
    }

そしてSwift 4:

let dataStore = WKWebsiteDataStore.default()
dataStore.fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) { records in
  dataStore.removeData(
    ofTypes: WKWebsiteDataStore.allWebsiteDataTypes(),
    for: records.filter { $0.displayName.contains("facebook") },
    completionHandler: completion
  )
}
37
Pankaj Gaikar

Saratの回答のSwift 3バージョン:

let dataStore = WKWebsiteDataStore.default()
dataStore.fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) { (records) in
    for record in records {
        if record.displayName.contains("facebook") {
            dataStore.removeData(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes(), for: [record], completionHandler: {
                print("Deleted: " + record.displayName);
            })
        }
    }
}
19
Simon Epskamp

IOS9の場合:

//// Optional data
NSSet *websiteDataTypes
= [NSSet setWithArray:@[
                        WKWebsiteDataTypeDiskCache,
                        //WKWebsiteDataTypeOfflineWebApplicationCache,
                        WKWebsiteDataTypeMemoryCache,
                        //WKWebsiteDataTypeLocalStorage,
                        //WKWebsiteDataTypeCookies,
                        //WKWebsiteDataTypeSessionStorage,
                        //WKWebsiteDataTypeIndexedDBDatabases,
                        //WKWebsiteDataTypeWebSQLDatabases
                        ]];
//// All kinds of data
//NSSet *websiteDataTypes = [WKWebsiteDataStore allWebsiteDataTypes];
//// Date from
NSDate *dateFrom = [NSDate dateWithTimeIntervalSince1970:0];
//// Execute
[[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:websiteDataTypes modifiedSince:dateFrom completionHandler:^{
    // Done
    NSLog(@"remove done");
}];
5
Kingiol

これらのオプションはどれも私にとってはうまくいきませんでしたが、私はそれを見つけました:

let config = WKWebViewConfiguration()
if #available(iOS 9.0, *) {
    config.websiteDataStore = WKWebsiteDataStore.nonPersistentDataStore()
} else {
     // I have no idea what to do for iOS 8 yet but this works in 9.
}

let webView = WKWebView(frame: .zero, configuration: config)
4
Zack Shapiro

iOS 11.0以降をサポート

次の解決策は私にとってうまくいった:

手順1. HTTPCookieStorageからCookieを削除する

ステップ2. WKWebsiteDataStoreからデータレコードを取得して削除します。

ステップ3.新しいWKProcessPoolを作成する

WKWebView拡張機能の作成:

extension WKWebView {

    func cleanAllCookies() {
        HTTPCookieStorage.shared.removeCookies(since: Date.distantPast)
        print("All cookies deleted")

        WKWebsiteDataStore.default().fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) { records in
            records.forEach { record in
                WKWebsiteDataStore.default().removeData(ofTypes: record.dataTypes, for: [record], completionHandler: {})
                print("Cookie ::: \(record) deleted")
            }
        }
    }

    func refreshCookies() {
        self.configuration.processPool = WKProcessPool()
    }
}

使用法:

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)
        webView.cleanAllCookies()
        webView.refreshCookies()
    }
3
Shubham Mishra

Swift 4以下のバージョン:

let dataStore = WKWebsiteDataStore.default()
dataStore.fetchDataRecords(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes()) { records in
    dataStore.removeData(ofTypes: WKWebsiteDataStore.allWebsiteDataTypes(),
                         for: records.filter { $0.displayName.contains("facebook") },
                         completionHandler: completion)
}
1
Sergi Gracia

共有Cookieストレージ内のCookieをクリアすることに加えて、キャッシュ(NSURLCache)をクリアしてWKWebViewを破棄し、新しいWKProcessPoolで新しいCookieを作成してみます

1
Subbu

必要に応じて、Cookieを正しくクリアするために、NSHTTPCookieStorageがiOS 8.2で現在使用されているようです。 WKWebViewベースのログインを開く前にこのコードを実行するアプリを出荷しました。

NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (NSHTTPCookie *cookie in [storage cookies])
{
    [storage deleteCookie:cookie];
}

IOS 8.2より前のWebサイトでは、保存されたCookieを使用して自動ログインしていましたが、ユーザーに再ログインを正しく要求するようになりました。このすべては、私がアプリの更新を出荷しなくても起こりました。 :)

0
Rohit suvagiya

[NSHTTPCookieStorage sharedHTTPCookieStorage]内に何も保存しないWKWebview。

WKWebsiteDataStoreをクリアすると、この問題の解決策になります。

それでもWKwebviewを使用しているIOS8の場合、この方法は適用できません。

0
Jeba Moses

Esqarrouthの答えは部分的に正しいだけです。
正しいSwiftバージョンは:

var libraryPath : String = NSFileManager().URLsForDirectory(.LibraryDirectory, inDomains: .UserDomainMask).first!.path!
libraryPath += "/Cookies"
do {
    try NSFileManager.defaultManager().removeItemAtPath(libraryPath)
} catch {
    print("error")
}
NSURLCache.sharedURLCache().removeAllCachedResponses()
0
ykonda