You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
Hi, I'm trying building an (iOS) app based on WkWebView.
On the first launch, when I use the (web-based) login form, it doesn't work at all, all cookies are dropped!
After I "pause" the app (by hitting the Home button) or after it's been killed, I can use the login form and it works normally. (Well, almost normally, since only one cookie out of 4 is kept, but it's the only mandatory one...)
This behaviour, with my code, is fully reproductible, I've spent about 2 days (full-time) on this, trying to make things work. If I use UIWebView instead, it works fine (except that there are the weird things that come with UI, such as the scrolling events that are not triggered properly). If I use
apache/cordova-plugin-wkwebview-engine
, it's the exact same broken behaviour.
I'm gonna fall back to UIWebView until I find a fix for it. But I'm not fully giving up yet.
Any help, any clue, would be very appreciated!
I have experienced this issue as well on first launch after installing from the App Store or Testflight. For me this only occurs on first install, not on updates.
So far I haven't found a way to work around it without making the login/join forms work without cookies, which is probably a bigger pain than it's worth.
Same here, it's only the first launch after the first installation. When it's updated, it doesn't have the problem (unless there are some specific changes perhaps, I'm not sure).
Login/Join forms not working on the first launch after the first install is a major blocker for me. :(
Anyway, thank you
@bezzer
for reassuring me (and my teammates) on the fact that we're not the only one with this issue! (I have not found anything via Google on this particular matter so far.)
This bug has been there for more than a year in
https://bugs.webkit.org/show_bug.cgi?id=140191
I finally gave up on trying to fix this bug. I'm now using a work-around, which consists in using localStorage to store those cookie stuff.
Realise this may be a bit late
@pwbs
, but I finally got a chance to look into this more closely, and was able to force the cookies to be stored by copying them from the server response into NSHTTPCookieStorage in the WKNavigationDelegate decidePolicyForNavigationResponse implementation.
NSHTTPURLResponse * resp = (NSHTTPURLResponse*)[navigationResponse response];
NSDictionary *diction = [resp allHeaderFields];
NSArray * cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:diction forURL:[resp URL]];
for (NSHTTPCookie *cookie in cookies) {
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
return decisionHandler(YES);
Cookies work on first install after this change for me, but it feels a bit heavy handed to copy them on every response.
@bezzer Thanks for your help. But unfortunately I couldn't make it work on my end.
In fact I'm using another wkwebview as well (cordova-plugin-wkwebview-engine).
I tried adding your code but did not work. Cookies is still not set at first launch after clean install.
@bezzer @chanphillip decidePolicyForNavigationResponse
isn't called for ajax responses, so it doesn't work for me. Doesn't seem to apply to in-app browser responses either. The only time it's ever called in my app is for the cordova root file. e.g. file:///var/containers/Bundle/Application/XXX-XXX-XXX/MyApp.app/www/index.html
My root file uses XHRs to authenticate, and those XHRs don't store cookies properly unless the app is backgrounded and then foregrounded, even with @bezzer's fix. So, still not a fix for me.
@hobzcalvin does this workaround stop working if the cookies on the server change? I'm thinking of applying your hack but I'm worried that the client side cookies that are synced up the first time will eventually becomes stale.
Does anyone know why the heck this only happens on the first install? Is this related to Apple's attempts to thwart cookie tracking?
On Mon, Oct 23, 2017 at 14:43 Dennis Torres ***@***.***> wrote:
@hobzcalvin <
https://github.com/hobzcalvin> does this workaround stop
working if the cookies on the server change? I'm thinking of applying your
hack but I'm worried that the client side cookies that are synced up the
first time will eventually becomes stale.
Does anyone know why the heck this only happens on the first install? Is
this related to Apple's attempts to thwart cookie tracking?
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<
#247 (comment)>,
or mute the thread
<
https://github.com/notifications/unsubscribe-auth/AAFBWVfjraqPdM_r_T6KNyYaX7RgKr9Qks5svQhkgaJpZM4Ip5-J>
If anyone is interested in some backgrounds of this problem you may find this answer on SO very interesting: https://stackoverflow.com/a/49534854/2757879
With this in mind I could make it to work by injecting a dummy cookie (foo=bar) for my domain right before the webview was initialized. After this has been done once the mentioned syncing works reliable ever after.
Based on the mentioned mechanism in my previous post, I have developed an additional plugin that allows to inject a dummy cookie to get the sync process started properly. While this will only work in iOS11 (and above) it solves the issue sufficiently for my client.
The repo can be found here: https://github.com/CWBudde/cordova-plugin-wkwebview-inject-cookie
workaround: with the help of different people, I fixed the problem. here is the cordova plugin that might help someone else too:
https://github.com/imransilvake/Cordova-Plugin-Sync-Cookies
@ryanlin1986 yes, I agree with that. Unless and until Apple fixes this bug, we have to use this workaround, unfortunately.
At least this timeout is for the very first run of the app and not for the rest of the runs.
@ryanlin1986 As mentioned above you could directly inject the cookie, then you don't have to wait for the extra request and for the cookie to get synced properly. It works immediately. Though it's iOS 11 only (which has a market share of about 80%). If you need to support older devices you could add the other workaround as well. Then you only have the delay for older devices.
If anyone is interested in some backgrounds of this problem you may find this answer on SO very interesting: https://stackoverflow.com/a/49534854/2757879
With this in mind I could make it to work by injecting a dummy cookie (foo=bar) for my domain right before the webview was initialized. After this has been done once the mentioned syncing works reliable ever after.
but he does not mention for work around ios 8,9,10
Basically for older iOS the problem is the same, but the workaround doesn't work immediately. It takes some time (or further action like minimizing the app) until the cookies are sync'ed properly.
In case of our app we display a message on the very first start like this: "The app is prepared, please wait a moment". Then in a regular interval we check if the cookies work, otherwise we force the setting again until it works. This sometimes takes about 20-30 seconds and it's pretty ugly, but it works and I guess that people using older iOS versions already get used to a slow loading as long as it works.
Hi FYI i found the workaround for ios less than 11 for cookie sync, let me
explain first. in ios 11 we can use cookies store data easy to sync only
issue is for ios less than 11, just set cookies in request header and also
set up cookie during webview creation using javaScript injection technique
after that it works perfect. i was trying to set only one place but after
setting up on 2 places it works fine.
On Mon, Sep 24, 2018 at 6:39 PM Christian Budde ***@***.***> wrote:
Basically for older iOS the problem is the same, but the workaround
doesn't work immediately. It takes some time (or further action like
minimizing the app) until the cookies are sync'ed properly.
In case of our app we display a message on the very first start like this:
"The app is prepared, please wait a moment". Then in a regular interval we
check if the cookies work, otherwise we force the setting again until it
works. This sometimes takes about 20-30 seconds and it's pretty ugly, but
it works and I guess that people using older iOS versions already get used
to a slow loading as long as it works.
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<
#247 (comment)>,
or mute the thread
<
https://github.com/notifications/unsubscribe-auth/AF56hYEI6XazvGeNZfO_Idb50ftytHC4ks5ueLZ3gaJpZM4Ip5-J>
i wrote my answer that is best and no need to make thread to wait for 20 or 30 seconds , or minimize your app or something that is wired behavior for users, please check my answer on stackoverflow.
https://stackoverflow.com/questions/26573137/can-i-set-the-cookies-to-be-used-by-a-wkwebview/52490200#52490200
We have to do downgrade https://ionicframework.com/docs/wkwebview/#downgrading-to-uiwebview
Yeah... no, no one wants to go back to UIwebview... performance sucks, semantics suck, mostly everything with it sucks, except cookies work better, but it shouldn't be worth the rest of the crap!
After so many attempts I've finally found a reliable way to set WKWebview cookie.
First you have to create an instance of WKProcessPool and set it to the WKWebViewConfiguration that is to be used to initialize the WkWebview itself:
private lazy var mainWebView: WKWebView = {
let webConfiguration = WKWebViewConfiguration()
webConfiguration.processPool = WKProcessPool()
let webView = WKWebView(frame: .zero, configuration: webConfiguration)
webView.navigationDelegate = self
return webView
Setting WKProcessPool is the most important step here. WKWebview makes use of process isolation - which means it runs on a different process than the process of your app. This can sometimes cause conflict and prevent your cookie from being synced properly with the WKWebview.
Now let's look at the definition of WKProcessPool
The process pool associated with a web view is specified by its web view configuration. Each web view is given its own Web Content process until an implementation-defined process limit is reached; after that, web views with the same process pool end up sharing Web Content processes.
Pay attention to the last sentence if you plan to use the same WKWebview for subsequence requests
web views with the same process pool end up sharing Web Content
processes
what I means is that if you don't use the same instance of WKProcessPool each time you configure a WKWebView for the same domain (maybe you have a VC A that contains a WKWebView and you want to create different instances of VC A in different places), there can be conflict setting cookies. To solve the problem, after the first creation of the WKProcessPool for a WKWebView that loads domain B, I save it in a singleton and use that same WKProcessPool every time I have to create a WKWebView that loads the same domain B
private lazy var mainWebView: WKWebView = {
let webConfiguration = WKWebViewConfiguration()
if Enviroment.shared.processPool == nil {
Enviroment.shared.processPool = WKProcessPool()
webConfiguration.processPool = Enviroment.shared.processPool!
webConfiguration.processPool = WKProcessPool()
let webView = WKWebView(frame: .zero, configuration: webConfiguration)
webView.navigationDelegate = self
return webView
After the initialization process, you can load an URLRequest inside the completion block of httpCookieStore.setCookie
. Here, you have to attach the cookie to the request header otherwise it won't work.
mainWebView.configuration.websiteDataStore.httpCookieStore.setCookie(your_cookie) {
self.mainWebView.load(your_request, with: [your_cookie])
extension WKWebView {
func load(_ request: URLRequest, with cookies: [HTTPCookie]) {
var request = request
let headers = HTTPCookie.requestHeaderFields(with: cookies)
for (name, value) in headers {
request.addValue(value, forHTTPHeaderField: name)
load(request)
After upgrading to WKWebView
, we're actually not able to see any cookies at all. I'm surprised that many folks are able to set cookies within their iOS WKWebView. Any tips on how to make this happen?
Before we were using UIWebView
, where our auth service would set cookies in our browser (http-only
), however, after the upgrade, none of the cookies are read or set.
After upgrading to WKWebView
, we're actually not able to see any cookies at all. I'm surprised that many folks are able to set cookies within their iOS WKWebView. Any tips on how to make this happen?
Before we were using UIWebView
, where our auth service would set cookies in our browser (http-only
), however, after the upgrade, none of the cookies are read or set.
Can you show some code or elaborate what you have so far?
Sure thing, @TaLinh! Here's a snippet of code:
I'm making a simple request with the following:
// index.js inside of Cordova application
const xhr = new XMLHttpRequest();
xhr.addEventListener('loadend', function(evt) {
console.log({ evt, response: this.response });
});
xhr.open('GET', 'http://localhost:8000/api');
xhr.send();
And here's the mockserver attaching cookies to every request:
// server.js
const cors = require('cors');
const express = require('express');
const cookieParser = require('cookie-parser');
const app = express();
app.use(cookieParser());
app.use(cors());
app.get('*', (req, res) => {
res.cookie('username', 'john doe', { maxAge: 900000, httpOnly: true });
res.send('Hello World!');
});
Now when I inspect the DevTools, I can see the Set-Cookies
in the response but I don't see the cookies actually set in the browser.
I don't see anything wrong with the code snippet above. Have you tried my approach above for injecting cookies into WKWebview? This is how I construct a cookie to use for my webView:
let cookie = HTTPCookie(properties: [
.domain: "your_domain",
.path: "/",
.name: "your_auth_token_field_name",
.value: "your_auth_token_value"
Guys, I was having the same problem with my app using WKWebView on IOS 12.4
I came across your post when I was struggling to find a solution but your solutions did not work for me. Still grateful to you guys for guiding me in the right direction. 👍🏼
After a lot of trial and error, I just hit the hammer on the head and found that all I had to do was to load the WebView initially with the host url and it started to work without any problems.
Code below:
class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {
var webView: WKWebView!
let screenSize: CGRect = UIScreen.main.bounds
let hostURL: String = "REPLACE_WITH_HOST_URL" // as in https://mycompany.com
var firstTime: Bool = true
@IBOutlet weak var myView: UIView!
func loadUrl(oURL:String){
if let url = URL(string: oURL) {
var request = URLRequest(url: url)
request.httpShouldHandleCookies = true // not required it is by default true
self.webView.load(request)
private func setupWebView(iURL: String) {
let configuration = WKWebViewConfiguration()
configuration.processPool = WKProcessPool()
let contentController = WKUserContentController()
configuration.userContentController = contentController
self.webView = WKWebView(frame : myView.frame , configuration : configuration)
self.webView.isUserInteractionEnabled = true
self.webView.allowsBackForwardNavigationGestures = true
self.webView.navigationDelegate = self
self.webView.uiDelegate = self
self.view.addSubview(self.webView)
self.loadUrl(oURL: iURL)
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if self.firstTime {
self.setupWebView(iURL: self.hostURL)
self.firstTime = false
override func viewDidLoad() {
super.viewDidLoad()
Hope it is helpful for you guys as well.
I am facing a similar issue, cookies in my project are not working in ionic-1 ios apps with wkwebview
Does anyone have any solution?