3

I am trying to use cookies in iOS WKWebView like this:

import UIKit
import WebKit

class ViewWrapper: UIViewController, WKNavigationDelegate{

@IBOutlet weak var viewerWebKit: WKWebView!
var loginToken: String?

override func viewDidLoad() {
    super.viewDidLoad()

    let url = URL(string: "url")!

    let newcookie = HTTPCookie(properties: [
        .domain: "domain",
        .path: "/",
        .name: "cookie name",
        .value: "cookie value",
        .secure: "FALSE",
        .expires: NSDate(timeIntervalSinceNow: 31556926)
        ])

    var request = URLRequest(url: url)
    request.httpShouldHandleCookies = true
    viewerWebKit.configuration.websiteDataStore.httpCookieStore.setCookie(newcookie!, completionHandler: {
        print("cookie setup done")
        self.viewerWebKit.load(request)
    })

    let refresh = UIBarButtonItem(barButtonSystemItem: .refresh, target: webView, action: #selector(viewerWebKit.reload))
    toolbarItems = [refresh]
    navigationController?.isToolbarHidden = false
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

override func loadView() {
    viewerWebKit = WKWebView()
    viewerWebKit.navigationDelegate = self
    view = viewerWebKit
}

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    title = webView.title
}

}

Domain, path, name and value are 100% correct. But when I am trying to get them and print then on my website, no cookies are set. Website printing of cookies works well, because I did an android app for this and it worked well there.

Do I need to do something more to accept or store the cookies?

Matej Košút
  • 590
  • 2
  • 10
  • 27
  • You are setting cookies in WKWebView in your app for a domain and expecting the cookie to be available in safari? Is that the trouble you are facing? – Sandeep Bhandari Oct 15 '18 at 11:13
  • No. I am setting them in WKWebView and I am also trying to print them in that same WKWebView in loaded website. – Matej Košút Oct 15 '18 at 11:18
  • Can you please add the code to show how are you reading them from cookie store? – Sandeep Bhandari Oct 15 '18 at 11:24
  • Website is performing the reading and printing, not app. And as I mentioned, it works fine for android. How can I test and print(log) set cookies in iOS app? – Matej Košút Oct 15 '18 at 11:33
  • Possible duplicate of [WKWebView setting Cookie not possible (iOS 11+)](https://stackoverflow.com/questions/50974353/wkwebview-setting-cookie-not-possible-ios-11) – Gabe Feb 02 '19 at 23:54

2 Answers2

2

Here's a self-contained example of setting a cookie which should be able to be read from a website loaded in the web view. The key points are that the domain must match the website's domain, the cookie expiry must be set to a future date, and this only worked for me with the secure flag set to false, not sure why.

Using the below example I was able to see the cookie in the browser's inspection window.

import UIKit
import WebKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let wv = WKWebView();
        view = wv;
        let cookie = HTTPCookie(properties: [
            .domain: ".example.com",
            .path: "",
            .name: "name",
            .value: "hello world",
            .expires: Date(timeIntervalSince1970: 1639655995)
        ])!
        wv.loadHTMLString("", baseURL: URL(string: "http://www.example.com")!);
        wv.configuration.websiteDataStore.httpCookieStore.setCookie(cookie)
    }
}
paulvs
  • 11,963
  • 3
  • 41
  • 66
1

Set cookie this way, and pass secure flag "FALSE" and path with "/"

let newcookie = HTTPCookie(properties: [
                    .domain: "domain",
                    .path: "/",
                    .name: "cookie name",
                    .value: "cookie value",
                    .secure: "FALSE",
                    .expires: NSDate(timeIntervalSinceNow: 31556926)
                    ])

Set cookie and wait for completion block to load your page.

self.configuration.websiteDataStore.httpCookieStore.setCookie(headerCookie, completionHandler: {
     print("cookie setup done")
     viewerWebKit.load(URLRequest(url: url))

})

After want to see cookie are updated or not just Add cookie change value observer like this way.

 WKWebsiteDataStore.default().httpCookieStore.add(self)


 func cookiesDidChange(in cookieStore: WKHTTPCookieStore) {
    cookieStore.getAllCookies({ (cookies) in
        cookies.forEach({ (cookie) in
            print(cookie.name)
        })
    })
}

Now you can see your cookie in cookiesDidChange method.

Muhammad Shauket
  • 2,643
  • 19
  • 40
  • Thank you for answer. I tried this. Cookies seem to be set. I can also log them with your method cookiesDidChange. But my website is still not able to read them. Website is now printing all cookies. When I am testing on android or normal desktop browser, there are printed cookies. But when testing on simulator, there is nothing. How is it possible? – Matej Košút Oct 16 '18 at 13:31
  • you can check cookie through safari , go to developer tab on safari and select your simulator and check cookie should be there in cookie storage. – Muhammad Shauket Oct 16 '18 at 13:34
  • Exactly through safari. And there is nothing there, it is empty. – Matej Košút Oct 16 '18 at 13:37
  • Then ask server developer to see why cookie not reading although you are setting up.. by the way on which above method only work for iOS 11 or above – Muhammad Shauket Oct 16 '18 at 13:38
  • you can check my answer related to cookie set here, may be your website reading cookie from document.cookie , follow this answer https://stackoverflow.com/questions/26573137/can-i-set-the-cookies-to-be-used-by-a-wkwebview/52490200#52490200 – Muhammad Shauket Oct 16 '18 at 13:42
  • But they are working everywhere else. It just seems be not set only on simulator's app and simulator's safari. Don't I need to allow cookies somehow? I am setting cookies in my app, but can't see them on safari's developer console. It doesn't have anything with backend. They are just not set properly. – Matej Košút Oct 16 '18 at 15:30
  • in wkwebview it is setting up properly otherwise when you get through getallcookies it will never return you cookie, check your request enabled request.httpShouldHandleCookies = true – Muhammad Shauket Oct 16 '18 at 15:33
  • then try to inject cookie in request header or in inject through javascript. – Muhammad Shauket Oct 18 '18 at 05:17