Как удалить кеш в WKWebview?

Кто-нибудь работал с WKWebview и пытался очистить кеш? Если да, то как сделать? любой пример?

P.S. : Обычный NSURLCache не работает.


person Sravan    schedule 24.11.2014    source источник


Ответы (12)


В iOS 9

// Optional data
NSSet *websiteDataTypes
= [NSSet setWithArray:@[
                        WKWebsiteDataTypeDiskCache,
                        //WKWebsiteDataTypeOfflineWebApplicationCache,
                        WKWebsiteDataTypeMemoryCache,
                        //WKWebsiteDataTypeLocalStorage,
                        //WKWebsiteDataTypeCookies,
                        //WKWebsiteDataTypeSessionStorage,
                        //WKWebsiteDataTypeIndexedDBDatabases,
                        //WKWebsiteDataTypeWebSQLDatabases,
                        //WKWebsiteDataTypeFetchCache, //(iOS 11.3, *)
                        //WKWebsiteDataTypeServiceWorkerRegistrations, //(iOS 11.3, *)
                        ]];
// All kinds of data
// NSSet *websiteDataTypes = [WKWebsiteDataStore allWebsiteDataTypes];
// Date from
NSDate *dateFrom = [NSDate dateWithTimeIntervalSince1970:0];
// Execute
[[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:websiteDataTypes modifiedSince:dateFrom completionHandler:^{
   // Done
}];
person Shingo Fukuyama    schedule 10.09.2015
comment
Красиво работал. Не забудьте сделать это: #import ‹WebKit/WKWebsiteDataStore.h› - person hnilsen; 12.09.2016
comment
этот код представляет ошибку компиляции: Initializer element is not a compile-time constant - person andrepaulo; 19.05.2017
comment
Я просто хочу отметить, что хотя приведенный выше код хорош, он не сработал для меня на веб-сайте, который я посещал с помощью WKWebView (веб-сайт также находится в стадии разработки). Но выбранный ответ в этом вопросе сработал: stackoverflow.com/questions/31289838/ - person C0D3; 13.11.2017

Обновленная версия Swift 5:

let websiteDataTypes = NSSet(array: [WKWebsiteDataTypeDiskCache, WKWebsiteDataTypeMemoryCache])
let date = Date(timeIntervalSince1970: 0)
WKWebsiteDataStore.default().removeData(ofTypes: websiteDataTypes as! Set<String>, modifiedSince: date, completionHandler:{ })

Версия для Swift:

if #available(iOS 9.0, *) {
  let websiteDataTypes = NSSet(array: [WKWebsiteDataTypeDiskCache, WKWebsiteDataTypeMemoryCache])
  let date = NSDate(timeIntervalSince1970: 0)
  WKWebsiteDataStore.defaultDataStore().removeDataOfTypes(websiteDataTypes as! Set<String>, modifiedSince: date, completionHandler:{ })
} else {
    var libraryPath = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.LibraryDirectory, NSSearchPathDomainMask.UserDomainMask, false).first!
    libraryPath += "/Cookies"

    do {
      try NSFileManager.defaultManager().removeItemAtPath(libraryPath)
    } catch {
      print("error")
    }
    NSURLCache.sharedURLCache().removeAllCachedResponses()
}

Версия Swift 3:

   if #available(iOS 9.0, *)
    {
        let websiteDataTypes = NSSet(array: [WKWebsiteDataTypeDiskCache, WKWebsiteDataTypeMemoryCache])
        let date = NSDate(timeIntervalSince1970: 0)

        WKWebsiteDataStore.default().removeData(ofTypes: websiteDataTypes as! Set<String>, modifiedSince: date as Date, completionHandler:{ })
    }
    else
    {
        var libraryPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.libraryDirectory, FileManager.SearchPathDomainMask.userDomainMask, false).first!
        libraryPath += "/Cookies"

        do {
            try FileManager.default.removeItem(atPath: libraryPath)
        } catch {
            print("error")
        }
        URLCache.shared.removeAllCachedResponses()
    }
person Esqarrouth    schedule 20.12.2015
comment
Мило спасибо. Swift (по крайней мере, 2.0) позволяет делать выводы и упрощать типы: let types = Set([WKWebsiteDataTypeDiskCache, WKWebsiteDataTypeMemoryCache]), а затем не требуется мост в вызове remove - person BaseZen; 01.06.2016
comment
Мне интересно, пробовал ли кто-нибудь версию ‹ 9.0. Это всегда выдает ошибку. Измените последний параметр NSSearchPathForDirectoriesInDomains на true, и это сработало для меня. - person funct7; 24.09.2016
comment
Даже при наличии iOS 9.0 похоже, что WKWebsiteDataStore.default().removeData... не удаляет ресурсы файла манифеста сайта. Мне пришлось использовать как WKWebsiteDataStore.default().removeData, так и URLCache.shared.removeAllCachedResponses(). - person Rodrigo Fava; 05.12.2018
comment
@Esqarrouth, не могли бы вы помочь мне с какой-то проблемой в WKWebView? - person Virani Vivek; 03.04.2019
comment
Почему вы инициируете как NSSet, а затем принудительно используете Set<String>? Вы можете просто инициировать как сет напрямую: let types = Set<String>([WKWebsiteDataTypeDiskCache, WKWebsiteDataTypeMemoryCache]) - person David Seek; 15.03.2021

Удалить кеш и куки

# WKWebView+Clean.swift

import WebKit

extension WKWebView {
    class func clean() {
        guard #available(iOS 9.0, *) else {return}

        HTTPCookieStorage.shared.removeCookies(since: Date.distantPast)

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

Пример:

import WebKit
...
WKWebview.clean()
person Peter Kreinz    schedule 28.05.2019

Мне удалось решить эту проблему, заставив мой WKWebView оценить window.location.reload. У меня есть распознаватель жестов касания в веб-представлении, и всякий раз, когда он обнаруживает двойное нажатие двумя касаниями, я запускаю следующее:

webView.evaluateJavaScript("window.location.reload(true)", completionHandler: nil);

Надеюсь это поможет.

person harrisonlee    schedule 04.09.2015

Вы не можете удалять кеши только с помощью NSURLCache. После долгих проб и ошибок я смог очистить кеши, выполнив следующие шаги (начиная с iOS 8.1.1):

  1. Используйте NSURLCache для удаления кешей так же, как вы делали это в UIWebView. Если вы используете WKProccessPool, повторно инициализируйте его.
  2. Удалить каталог Caches в Library.
  3. Удалить все WKWebViews

В следующий раз, когда вы создадите WKWebView, кеши должны быть очищены.

ShingoFukuyama/WKWebViewTips

person Shingo Fukuyama    schedule 26.11.2014

Нечто подобное для iOS 9.0 и более поздних версий:

let store: WKWebsiteDataStore = WKWebsiteDataStore.default()
let dataTypes: Set<String> = WKWebsiteDataStore.allWebsiteDataTypes()
store.fetchDataRecords(ofTypes: dataTypes, completionHandler: { (records: [WKWebsiteDataRecord]) in
  store.removeData(ofTypes: dataTypes, for: records, completionHandler: {
    // do your thing here
  })
})
person nouatzi    schedule 20.10.2016

Работает
Swift 3. Версия.
Для более старой версии Swift

import Foundation
import WebKit

func removeWebData() {

    if #available(iOS 9.0, *) {

        let websiteDataTypes = WKWebsiteDataStore.allWebsiteDataTypes()
        let date = NSDate(timeIntervalSince1970: 0)

        WKWebsiteDataStore.default().removeData(ofTypes: websiteDataTypes, modifiedSince: date as Date, completionHandler: {
            #if DEBUG

                print("remove all data in iOS9 later")

            #endif
        })

    }else {

        // Remove the basic cache.
        URLCache.shared.removeAllCachedResponses()

        // Delete system cookie store in the app
        let storage = HTTPCookieStorage.shared
        if let cookies = storage.cookies {
            for cookie in cookies {
                storage.deleteCookie(cookie)
            }
        }


        do {
            // folder 를 삭제하는 대신 contents 를 삭제하는 이유?
            // MainVC 가 호출되면 cache, cookie가 발생하므로 로딩시 확인된 cache, cookie 폴더의
            // contents 에 대해서만 삭제 진행.

            // Clear web cache
            try deleteLibraryFolderContents(folder: "Caches")

            // Remove all cookies stored by the site. This includes localStorage, sessionStorage, and WebSQL/IndexedDB.
            try deleteLibraryFolderContents(folder: "Cookies")

            // Removes all app cache storage.
            try deleteLibraryFolder(folder: "WebKit")

        } catch {
            #if DEBUG

                print("Delete library folders error in iOS9 below")

            #endif

        }
    }
}

/**
 Delete folder in library

 - parameter folder: a folder you want to delete

 - throws: throws an error
 */
func deleteLibraryFolder(folder: String) throws {
    let manager = FileManager.default
    let library = manager.urls(for: .libraryDirectory, in: .userDomainMask).first!
    let dir = library.appendingPathComponent(folder)
    try manager.removeItem(at: dir)
}

/**
 Delete contents in library folder

 - parameter folder: target folder

 - throws: throws an error
 */
private func deleteLibraryFolderContents(folder: String) throws {
    let manager = FileManager.default
    let library = manager.urls(for: FileManager.SearchPathDirectory.libraryDirectory, in: .userDomainMask)[0]
    let dir = library.appendingPathComponent(folder)
    let contents = try manager.contentsOfDirectory(atPath: dir.path)
    for content in contents {
        do {
            try manager.removeItem(at: dir.appendingPathComponent(content))
        } catch where ((error as NSError).userInfo[NSUnderlyingErrorKey] as? NSError)?.code == Int(EPERM) {
            // "EPERM: operation is not permitted". We ignore this.
            #if DEBUG

                print("Couldn't delete some library contents.")

            #endif
        }
    }
}
person ZAFAR007    schedule 19.03.2017

свифт5

URLCache.shared.removeAllCachedResponses()
person Kseniya    schedule 29.11.2020

Меня устраивает

 if #available(iOS 9.0, *) {
            let websiteDataTypes = NSSet(array: [WKWebsiteDataTypeDiskCache, WKWebsiteDataTypeMemoryCache])
            let date = NSDate(timeIntervalSince1970: 0)
            WKWebsiteDataStore.defaultDataStore().removeDataOfTypes(websiteDataTypes as! Set<String>, modifiedSince: date, completionHandler:{ })
        }
        else
        {
          NSURLCache.sharedURLCache().removeAllCachedResponses()
        }
person Durai Amuthan.H    schedule 28.01.2016

Swift 3.x версия поста @Esqarrouth

func clearCache() {
    if #available(iOS 9.0, *) {
        let websiteDataTypes = NSSet(array: [WKWebsiteDataTypeDiskCache, WKWebsiteDataTypeMemoryCache])
        let date = NSDate(timeIntervalSince1970: 0)
        WKWebsiteDataStore.default().removeData(ofTypes: websiteDataTypes as! Set<String>, modifiedSince: date as Date, completionHandler:{ })
    } else {
        var libraryPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.libraryDirectory, FileManager.SearchPathDomainMask.userDomainMask, false).first!
        libraryPath += "/Cookies"

        do {
            try FileManager.default.removeItem(atPath: libraryPath)
        } catch {
            print("error")
        }
        URLCache.shared.removeAllCachedResponses()
    }
}
person zingle-dingle    schedule 16.03.2017

Это занимает у меня несколько часов, но это работает для меня! После loadRequest делаю reloadFromOrigin! Поэтому я принудительно очищаю кеш! [WKWebView loadRequest:запрос]; [WKWebView reloadFromOrigin];

person Valentin Thomalla    schedule 17.09.2017

получить путь к словарю кеша и удалить его

   NSFileManager *fileManager = [NSFileManager defaultManager];
   NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];
  NSError *error;
  BOOL success = [fileManager removeItemAtPath:documentsPath error:&error];
    NSLog(@"%d",success);
person Sateesh Pasala    schedule 11.06.2019