Sync cookies in multiple WKWebViews on iOS 9 - ios

I am using 2 ViewControllers with 2 WKWebViews.
The WebViews use a shared WKWebViewConfiguration.
extension WKWebViewConfiguration {
static var Shared : WKWebViewConfiguration{
if sharedConfiguration == nil{
sharedConfiguration = WKWebViewConfiguration()
sharedConfiguration.websiteDataStore = WKWebsiteDataStore.default()
sharedConfiguration.processPool = WKProcessPool()
}
return sharedConfiguration
}
private static var sharedConfiguration : WKWebViewConfiguration!
}
I am passing this on each webView and from what I read this should be the solution for shared Cookies.
But because I am doing a login though the webContent I want to have the webViews SYNCHED if the user is logged in or not.
The problem happens when the user logs in. The steps that I follow are the :
1) I have identify the host and the path, and checking the navigationAction.request.url.host and navigationAction.request.url.path
when the user makes a request, and the request happens ONLY if the credentials are correct (So I know the correct host and path) I create a bool var that indicates that the users has logged in
2) After the WebView didFinish : FINISH , I call a func that reloads the webViews that have to get refreshed but the WebViews are not acting like they have the cookies.
3) after some seconds(different everytime) ,adding manual the code .reload() the web views in each preview , the webViews are synched.
I am working on iOS 9 since these are the requirements.
It looks that the cookies are asynced, and eventually they arrive to the shared processPool or websiteDataStore from my understanding.
Anyone have a solid solution?

You don't need to share same web configuration, you just need to share processPool and KWebsiteDataStore.default() after creating each webview configuration. To verify you can check cookies from Safari developer tool.
As #PS mentioned no workaround is working for him to sync cookies. I also encounter the same problem. but I tried some unexpected things to fix this issue and that is work 100%
Cookie sync takes some time to sync with cookie store for wkwebview. so my fix is just made dummy web request that will sync cookie on app start and after that, wherever you have to use your sign In or Sign Out call you can use without making any further modification.

Related

iOS - Enable Private Browsing in WebView

I want to show private browsing mode like safari with the help of UIWebView. I want to show the same UI as Safari has for private browsing. Screenshot attached.
I have tried to use web view configuration to nonPersistent for websiteDataStore. But it will only help to not store the data.
According to the NSHTTPCookieStorage docs, cookies are not shared
between applications:
Yes, UIWebView does have the private browsing mode by default. The
Cookie data is accessible by the App only.
NSHTTPCookie's singleton instance stores the Cookie information of
the UIWebView. You may need to use deleteCookie: method to clear the
cached data
I totally agree with #Scriptable For UI like Safari you need to
design as per your requirements

Cookies in xamarin forms WebView

I have developed a simple Xamarin Forms App( targeting IOS and Android) with just a WebView and displaying an ASP.NET website in it.
It works as expected.
Now, my requirement is to store the authentication cookie when user logs in for the first time and attach that cookie every time the App gets opened so that the user does not need to login each time.
I have tried creating Custom WebView Render following the below code, but it doesn't seem to work for my scenario.
https://forums.xamarin.com/discussion/41039/setting-cookies-in-a-webview
I am able to access all cookies on WebView, but how do I store the necessary cookie and attach that cookie to WebView when the App gets opened again?
Any help would be appreciated.
android, in the onFinishLoad of the webview client:
CookieManager.Instance.Flush();
IOS:
in the onFinishLoad of the webview client to get yours cookies
(NSString)NSUserDefaults.StandardUserDefaults.ValueForKey((NSString)"CookiePZ8") ?? string.Empty
but you need to ad this line in your create of the OnElementChanged of your webview render
request["Cookie"] = (string)((NSString)NSUserDefaults.StandardUserDefaults.ValueForKey((NSString)"CookiePZ8") ?? string.Empty);
his.loadUrl(request);

Clearing Cookies for WKWebView on iOS 8.4

I'm building an app that uses Single Sign On for users to log in. After the user enters a successful ID and password, the web side of things returns headers which I grab and store in my app. The WKWebView also sets a cookie that the user successfully logged in. This is what I want to avoid or undo.
The undesired behavior that I'm seeing is that if I log in a user, everything goes well, and then I log them out and go to log back in again, the WKWebView thinks the user is still logged in and takes them to an undesired URL.
In iOS 9, mitigating this is fairly simple:
let config = WKWebViewConfiguration()
config.websiteDataStore = WKWebsiteDataStore.nonPersistentDataStore()
let webView = WKWebView(frame: .zero, configuration: config)
However in iOS 8.4, making making sure the cookies are clear each time the user goes in to load the Single Sign On URL is more complicated.
I've tried approaches where I loop through cookies in NSHTTPCookieStorage.sharedHTTPCookieStorage() and remove them. Unfortunately, the cookie count is 0.
I've also tried removing the /Cookies directory in NSFileManager.defaultManager(). This also does not work.
One thing that kind of worked was doing the following. Although this approach didn't allow me to get the headers because a redirect after login needed to happen and this interfered (in iOS 9+ and 8.4)
req = NSMutableURLRequest(URL: url)
req?.HTTPShouldHandleCookies = false
let webView = WKWebView()
webView.loadRequest(req ?? NSURLRequest(URL: url))
I'd prefer to clear cookies in the deinit of my view that holds my WKWebView if that's a possible solution here.
This might be a longshot, but what about overriding the cookie accept policy to reject all cookies at the time of sign in?
NSHTTPCookieStorage.sharedHTTPCookieStorage().cookieAcceptPolicy = .Never
Another idea would be to manually mange the cookies with a custom WKProcessPool subclass (which is not really documented). I believe that's how Firefox manages any cookie issues.
Even if you mention it, is this the approach you've already tried in your deinit?
let storage = NSHTTPCookieStorage.sharedHTTPCookieStorage()
for cookie in storage.cookies! {
storage.deleteCookie(cookie)
}

Webpage cookies are not detected by UIWebView

I am developing iOS app that loads a webpage using UIWebView
The web page sets four cookies:
Two for Google Analytics, _ga and _gat
One for my web application unique vistors counter
One for my webpage to detect whether user has voted or not.
If this cookie available then display the poll results.
From Firefox's Storage Inspector I see all my cookies as expected, see screenshot:
However, from iOS I printed NSHTTPCookieStorage.sharedHTTPCookieStorage().cookies from inside webViewDidFinishLoad and there is only two of four expected cookies, also iOS users can vote as many times as they wanted because cookies are not detected (or not stored in iOS device):
if let cookies = NSHTTPCookieStorage.sharedHTTPCookieStorage().cookies {
for c in cookies {
print("*******************")
print("name: \(c.name)")
print("domain: \(c.domain)")
print("value: \(c.value)")
print("path: \(c.path)")
print("expiresDate: \(c.expiresDate)")
}
}
Why my iOS app does not detect my custom cookies and only detects my Google Analytics ones?
NOTE 1: I have also added this code to my app:
func applicationDidBecomeActive(application: UIApplication) {
NSHTTPCookieStorage.sharedHTTPCookieStorage().cookieAcceptPolicy = NSHTTPCookieAcceptPolicy.Always
}
NOTE 2: My backend is SharePoint web application
A few ideas:
The device's Safari "Block Cookies" settings override any changes to the cookieAcceptPolicy. The default policy of this setting on the device is "Allow from Websites I Visit," which depending on your iOS device's version, allows third-party cookies. Testing with iOS 9.3.x shows that third party cookies are persisted in a UIWebView with the default settings, but do not persist with the settings "Allow from Current Website Only" or "Always Block."
Check if the device persists your cookie with the different Safari cookie settings.
Additionally, does your cookie have an expiration date set? I've found that cookies without an expiration date set are treated as session cookies in a UIWebView, which only persist with the lifecycle of the web view that received it.

How to Enable Cookies in UIWebView for iOS Swift

I have an app that uses Instagram Integration. The App has been in the App Store for a few months with multiple version all working fine. Suddenly, the latest version I submitted to Apple was rejected because apple doesn't like the fact that Safari is launched for a User to Login to Instagram. As per their words, they care about the user experience.
The problem is I need to request an Access Token and that is how I know it has to be done. Since my App was rejected, I can't be the only one who may have faced this so I thought I should ask. Does any one know of some other method perhaps I don't know of whereby you can authenticate a users Instagram and get the required Access Token, without Launching Safari?
EDIT #1: The only other option I can think of is to use a UIWebView within my app to open the Instagram authentication process. I tried this and it just seems to be mad slow and the callback process to my app doesn't seem to initiate. So I don't know if I'm doing something wrong.
EDIT #2: Doing more research as to why the Instagram login is not working in my UIWebView, it seems to be something with how the UIWebView handles Cookies, apparently it does not recognize Cookies or something along those lines. I still don't know what exactly to do to fix this, so if anyone has a solution please provide.
Looks like this is something that could help you. You haven't given many infos about your app so I can't think of something outside the box, but try looking into Instagram iPhone Hooks and see if you can use them to trigger login when the user does something.
I'm sure this can be optimized a little bit, I probably do not need the for loop. But either way, I've spent almost a day on this issue and just don't want to touch it anymore since I was finally able to get this to work by doing the following before loading the UIWebView:
var req = NSURLRequest(URL: NSURL(string: urlString)!)
var cookies = NSHTTPCookieStorage.sharedHTTPCookieStorage().cookies as! [NSHTTPCookie]
var reqCookies:[AnyObject] = []
for aCookie in cookies {
reqCookies += [aCookie]
}
var headers = NSHTTPCookie.requestHeaderFieldsWithCookies(reqCookies)
self.webView.loadRequest(req)

Resources