emily-curry commented on issue #753:
URL:
https://github.com/apache/cordova-plugin-inappbrowser/issues/753#issuecomment-872372518
I have successfully worked around this issue by doing some method-swizzling
with some of this plugin's internals. What is happening here is that on browser
open, I sync the app's persistent NSHTTPCookieStorage with the new webview's
WKHTTPCookieStore. On browser close, we do the reverse; read from the
WKHTTPCookieStore and write to the persistent NSHTTPCookieStorage (modifying
any properties that would cause the cookies to _not_ persist between app loads,
because that is important to my use case).
```objc
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import "CDVWKInAppBrowser.h"
/**
* A category of CDVWKInAppBrowser that handles persisting cookies from the
WKWebView on close, and reapplying them on load.
*/
@interface CDVWKInAppBrowser (Cookies)
- (void) cookies_open:(NSURL*)url withOptions:(NSString*)options;
- (void) cookies_close;
@end
@implementation CDVWKInAppBrowser (Cookies)
/**
* Swizzles the implementations of openInInAppBrowser:withOptions: and
browserExit with versions that syncronize WKWebView cookies with the app's
NSHTTPCookieStorage.
*/
+ (void) load
{
static dispatch_once_t once_token;
dispatch_once(&once_token, ^{
// ignore undeclared selector warnings, which are caused by
overriding private methods of CDVWKInAppBrowser
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
SEL openSelector = @selector(openInInAppBrowser:withOptions:);
SEL cookiesOpenSelector = @selector(cookies_open:withOptions:);
Method originalOpenMethod = class_getInstanceMethod(self,
openSelector);
Method extendedOpenMethod = class_getInstanceMethod(self,
cookiesOpenSelector);
method_exchangeImplementations(originalOpenMethod,
extendedOpenMethod);
SEL closeSelector = @selector(browserExit);
SEL cookiesCloseSelector = @selector(cookies_close);
Method originalCloseMethod = class_getInstanceMethod(self,
closeSelector);
Method extendedCloseMethod = class_getInstanceMethod(self,
cookiesCloseSelector);
method_exchangeImplementations(originalCloseMethod,
extendedCloseMethod);
#pragma clang diagnostic pop
});
}
/**
* Loads all cookies from the app's NSHTTPCookieStorage instance, and
applies them to the WKHTTPCookieStore.
* The overridden method is called after this happens, so if the webview was
opened with the "clearsession" option, cookies will still be cleared.
*/
- (void) cookies_open:(NSURL*)url withOptions:(NSString*)options
{
WKWebsiteDataStore* dataStore = [WKWebsiteDataStore defaultDataStore];
WKHTTPCookieStore* cookieStore = dataStore.httpCookieStore;
NSHTTPCookieStorage* storage = [NSHTTPCookieStorage
sharedHTTPCookieStorage];
NSHTTPCookie* cookie;
for (cookie in storage.cookies) {
[cookieStore setCookie:cookie completionHandler:nil];
}
[self cookies_open:url withOptions:options];
}
/**
* Loads all cookies from the WKHTTPCookieStore, sets the "Discard" flag to
false, and persists them to the app's NSHTTPCookieStorage instance.
*/
- (void) cookies_close
{
WKWebsiteDataStore* dataStore = [WKWebsiteDataStore defaultDataStore];
WKHTTPCookieStore* cookieStore = dataStore.httpCookieStore;
int secondsToKeep = 60*60*24*90;
[cookieStore getAllCookies:^(NSArray* cookies) {
NSHTTPCookie* cookie;
for(cookie in cookies) {
NSMutableDictionary* cookieDict = [cookie.properties
mutableCopy];
[cookieDict removeObjectForKey:NSHTTPCookieDiscard]; // Remove
the discard flag. If it is set (even to false), the expires date will NOT be
kept.
if (![cookieDict objectForKey:NSHTTPCookieExpires]) { // If the
cookie doesn't have an expiration date, set it to the maximum value. Otherwise,
keep the existing value.
[cookieDict setObject:[NSDate
dateWithTimeIntervalSinceNow:secondsToKeep] forKey:NSHTTPCookieExpires]; //
Expires in 90 days. Only applies to version 0 cookies (rare).
}
if (![cookieDict objectForKey:NSHTTPCookieMaximumAge]) { // If
the cookie doesn't have a max age, set it to the maximum value. Otherwise, keep
the existing value.
[cookieDict setObject:[NSString
stringWithFormat:@"%d",secondsToKeep] forKey:NSHTTPCookieMaximumAge]; //
Expires in 90 days. Only applies to version 1 cookies.
}
NSHTTPCookie* newCookie = [NSHTTPCookie
cookieWithProperties:cookieDict];
[[NSHTTPCookieStorage sharedHTTPCookieStorage]
setCookie:newCookie];
}
}];
[self cookies_close];
}
@end
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]