2

Aim:

I would like to get all the cookies from WKWebView after being redirected to a specific URL.

Problem:

I am not able to get all the cookies, some cookies are missing.

Options tried so far without much success:

1. Observe notification

private func addObserver() {

    NSNotificationCenter.defaultCenter().addObserver(self,
                                                     selector: #selector(didChangeCookiesWithNotification(_:)),
                                                     name: NSHTTPCookieManagerCookiesChangedNotification,
                                                     object: nil)


}

@objc private func didChangeCookiesWithNotification(notification: NSNotification?) {

    print("cookies changed")
    print("Finish cookies location = \(NSHTTPCookieStorage.sharedHTTPCookieStorage())")
    print("Finish cookies count    = \(NSHTTPCookieStorage.sharedHTTPCookieStorage().cookies?.count)")
    print("Finish cookies          = \(NSHTTPCookieStorage.sharedHTTPCookieStorage().cookies?.map { "\($0.name) --- Domain = \($0.properties?["Domain"])" } )")
}

2. Redirect

func webView(webView: WKWebView,
             didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!) {


    print("redirected URL = \(webView.URL)")


    print("Redirect cookies location = \(NSHTTPCookieStorage.sharedHTTPCookieStorage())")
    print("Redirect cookies count    = \(NSHTTPCookieStorage.sharedHTTPCookieStorage().cookies?.count)")
    print("Redirect cookies          = \(NSHTTPCookieStorage.sharedHTTPCookieStorage().cookies?.map { "\($0.name) --- Domain = \($0.properties?["Domain"])" } )")
}

3. Reset process pool

//Inside didReceiveServerRedirectForProvisionalNavigation
webView.configuration.processPool = WKProcessPool()

Questions:

  1. How do I get all the cookies after a redirect to a specific URL ?
  2. Is there a different location on to which where the cookies get written in real time ?
  3. How do I force the cookies to be written ?
  4. How can I be notified when a cookie gets added ?
  5. Do I need to adopt a different approach ?
user1046037
  • 16,755
  • 12
  • 92
  • 138
  • Have you seen this thread? http://stackoverflow.com/questions/33156567/getting-all-cookies-from-wkwebview – Vemonus Aug 18 '16 at 19:29
  • Was my answer helpful? What are you trying to do with cookies? – Roman Ermolov Aug 25 '16 at 00:33
  • I want to know how to know the correct cookie location for `WKWebView` and way to get the cookie. – user1046037 Aug 25 '16 at 05:23
  • @user1046037 ok, but there is no another way to get them directly (I was on lab at wwdc this year and Apple engineer said me that). Could you please clarify the purpose of getting cookies? – Roman Ermolov Aug 25 '16 at 05:46
  • Btw, my answer for [this question](http://stackoverflow.com/questions/39076163/use-shared-wkwebviewcookies-for-a-request/39133763) might be helpful for you. – Roman Ermolov Aug 26 '16 at 10:37

1 Answers1

0

As far as I know, there is only one working approach - getting cookies from JavaScript. You won't be able to get HTTP-cookies, but it would be okay for another types.

You can create background webView with same process pool and load empty html to it using loadHTMLString:baseURL: with redirect URL as base url.

After that, you need to handle the fact of redirecting via webView:didReceiveServerRedirectForProvisionalNavigation:. When receiving notification about redirecting, call JS on background webView - you will receive same cookies.

Roman Ermolov
  • 7,898
  • 5
  • 27
  • 35
  • can you please give some more explanations ? So one must get another (hidden) WKWebView sharing the same WKProcessPool. But how this second WKWebView get called with `webView:didReceiveServerRedirectForProvisionalNavigation:` (I dont understand the *redirect* URL) ? Then just evaluate `document.cookie` to get the JS cookies, right ? – PhilippeT Sep 23 '16 at 12:19
  • @PhilippeT yep, sure. First of all, you need to create 2 webView - one for regular usage (A) and one for getting cookies (B). They should have same processPool. Before using webView A, you need to call `loadHTMLString:baseURL:` on webView B with url of server where is located cookies that you are interested in. If you want to receive cookies on redirect, you need to call `evaluateJavaScript:completionHandler:` with `document.cookie` on webView B, when webView A receives `webView:didReceiveServerRedirectForProvisionalNavigation:`. Is it clear? – Roman Ermolov Sep 23 '16 at 12:32
  • @PhilippeT also, I am not sure, that `didReceiveServerRedirectForProvisionalNavigation:` is the best place to get cookies. May be it would be better to raise flag on this method and get cookies when `didCommitNavigation:` called. – Roman Ermolov Sep 23 '16 at 12:36
  • Hi @Roman, in viewDidLoad, I created B with the processPool shared with A. Then: – PhilippeT Sep 27 '16 at 10:38
  • Hi @Roman, Thanks for your quick answer. I tried this: in viewDidLoad, I created B (with zero rect frame), sharing the processPool with A. Then loadHTML `` into B with myServerURL and loadRequest myServerURL into A. But A's WKWebView delegate dont get called with `webView:didReceiveServerRedirectForProvisionalNavigation:`... Should I wait until B's delegate get called with `webView:didFinishNavigation:` to request myServerURL with A ? Then if B's delegate get called, my main issue is to get the current session ID, that is not available as a javascript cookie... – PhilippeT Sep 27 '16 at 10:57
  • @PhilippeT Lets move from what you need. If I understand you correctly, you want to get `session id` value from your server. What is it? HTTP response header? And one more question - what is the purpose of creation of 2 `webView` with same url (`myServerURL`)? – Roman Ermolov Sep 27 '16 at 11:30
  • @RomanErmolov Can you please check my [question](http://stackoverflow.com/questions/41217020/wkwebview-didt-give-all-cookies-in-navigationresponse)? – ZAFAR007 Dec 20 '16 at 07:46