After a long time researching and trying to figure out how to sync sessions and cookies through many webviews this was the best final working aproach that I came with
... (wip)
- Filter cookies by domain
extension WKWebView { | |
enum Key { | |
static let data = "webview_data_" | |
static let cookie = "webview_cookies_" | |
static let processPool = "webview_processpool_" | |
} | |
// SAVE | |
func saveProcessPool(processPool: WKProcessPool, _ completion: @escaping () -> ()) { | |
saveDataIntoUD(processPool, Key.processPool) { | |
completion() | |
} | |
} | |
func saveCookies(for domain: String, _ completion: @escaping () -> ()) { | |
getCookiesFromWK(for: domain) { cookies in | |
saveDataIntoUD(data, Key.cookie) | |
completion() | |
} | |
} | |
// GET | |
func getProcessPool(_ completion: @escaping (WKProcessPool?) -> ()) { | |
getDataFromUD(Tag.processPool) { processPool in | |
completion(processPool as? WKProcessPool) | |
} | |
} | |
func getCookies(_ completion: @escaping ([HTTPCookie]?) -> ()) { | |
getDataFromUD(Tag.cookie) { cookies in | |
completion(cookies as? [HTTPCookie]) | |
} | |
} | |
// UserDefaults Manager | |
func saveDataIntoUD(data: Any, key: String? = Key.data, _ completion: @escaping () -> ()) { | |
let ud = UserDefaults.standard | |
let archivedData = NSKeyedArchiver.archivedData(withRootObject: data) | |
ud.set(archivedData, forKey: key) | |
completion() | |
} | |
func getDataFromUD(key: String? = Key.data, _ completion: @escaping ([Any]?) -> ()) { | |
let ud = UserDefaults.standard | |
if let data = ud.value(forKey: key) as? Data, | |
let obj = NSKeyedUnarchiver.unarchiveObject(with: data) { | |
completion(obj as? Any) | |
return | |
} | |
} | |
// WKWebView Cookies Manager | |
func getCookiesFromWK(for domain: String, completion: @escaping ([HTTPCookie]) -> ()) { | |
if #available(iOS 11.0, *) { | |
self.configuration.websiteDataStore.httpCookieStore.getAllCookies { cookies in | |
completion(cookies as? [HTTPCookie]) | |
return | |
} | |
} | |
} | |
func loadCookiesIntoWK(completion: @escaping (Bool) -> () = {_ in}) { | |
getCookies() { cookiesUD in | |
if let cookies: [HTTPCookie] = cookiesUD { | |
if #available(iOS 11.0, *) { | |
for cookie in cookies { | |
self.configuration.websiteDataStore.httpCookieStore.setCookie(cookie) | |
} | |
completion(true) | |
return | |
} | |
} | |
completion(false) | |
} | |
} | |
} |