在iOS中使用多个WKWebView实例,会存在cookie无法同步问题。解决的基本思路是:创建一个WKWebView单例,用来保存请求返回的cookie,并且所有使用WKWebView的地方替换成单例模式。
1、封装WKWebView公共管理类
#import <Foundation/Foundation.h>
#import <WebKit/WebKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface WKWebViewUtil : NSObject{
}
@property (nonatomic, strong,readonly) WKProcessPool *processPool;
+ (instancetype)sharedSupport;
+ (WKWebView *)createSharableWKWebView;
/*
* 保存cookies
*/
+ (void)storeCookies:(NSHTTPURLResponse *) response;
@end
NS_ASSUME_NONNULL_END
#import "WKWebViewUtil.h"
@interface WKWebViewUtil (){
}
@property (nonatomic, strong) WKProcessPool *processPool;
@end
@implementation WKWebViewUtil
+ (instancetype)sharedSupport {
static WKWebViewUtil *_instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [WKWebViewUtil new];
});
return _instance;
}
- (instancetype)init {
if (self = [super init]) {
self.processPool = [WKProcessPool new];
}
return self;
}
+ (WKWebView *)createSharableWKWebView {
WKUserContentController* userContentController = [WKUserContentController new];
NSMutableString *cookies = [NSMutableString string];
WKUserScript * cookieScript = [[WKUserScript alloc] initWithSource:[cookies copy] injectionTime:WKUserScriptInjectionTimeAtDocumentStart
forMainFrameOnly:NO];
[userContentController addUserScript:cookieScript];
WKWebViewConfiguration *configuration = [WKWebViewConfiguration new];
// 一下两个属性是允许H5视屏自动播放,并且全屏,可忽略
configuration.allowsInlineMediaPlayback = YES;
if (@available(iOS 10.0, *)) {
configuration.mediaTypesRequiringUserActionForPlayback = NO;
} else {
// Fallback on earlier versions
}
// 全局使用同一个processPool
configuration.processPool = [[WKWebViewUtil sharedSupport] processPool];
configuration.userContentController = userContentController;
WKWebView *wk_webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
return wk_webView;
}
+ (void)storeCookies:(NSHTTPURLResponse *) response{
// 获取cookie,并设置到本地
NSArray *cookies =[NSHTTPCookie cookiesWithResponseHeaderFields:[response allHeaderFields] forURL:response.URL];
for (NSHTTPCookie *cookie in cookies) {
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
}
}
@end
2、使用
self.webView = [WKWebViewUtil createSharableWKWebView];
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
NSHTTPURLResponse *response = (NSHTTPURLResponse *)navigationResponse.response;
[WKWebViewUtil storeCookies:response];
decisionHandler(WKNavigationResponsePolicyAllow);
}