Skip to content

Commit

Permalink
feat(WKWebview): Add shared process pool so cookies and localStorage …
Browse files Browse the repository at this point in the history
…are shared across webviews in iOS (#138)

* fix(WKWebview): [iOS] Add shared process pool so cookies and localStorage are shared across webviews (#68)

* Add optional shared process pool

BREAKING CHANGE: useSharedProcessPool prop is set to true by default. If you want the old behavior, please use useSharedProcessPool={false}
  • Loading branch information
kylemantesso authored and Titozzz committed Jan 7, 2019
1 parent 335792c commit afadc62
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 4 deletions.
15 changes: 15 additions & 0 deletions ios/RNCWKProcessPoolManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#import <WebKit/WebKit.h>

@interface RNCWKProcessPoolManager : NSObject

+ (instancetype) sharedManager;
- (WKProcessPool *)sharedProcessPool;

@end
36 changes: 36 additions & 0 deletions ios/RNCWKProcessPoolManager.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#import <Foundation/Foundation.h>
#import "RNCWKProcessPoolManager.h"

@interface RNCWKProcessPoolManager() {
WKProcessPool *_sharedProcessPool;
}
@end

@implementation RNCWKProcessPoolManager

+ (id) sharedManager {
static RNCWKProcessPoolManager *_sharedManager = nil;
@synchronized(self) {
if(_sharedManager == nil) {
_sharedManager = [[super alloc] init];
}
return _sharedManager;
}
}

- (WKProcessPool *)sharedProcessPool {
if (!_sharedProcessPool) {
_sharedProcessPool = [[WKProcessPool alloc] init];
}
return _sharedProcessPool;
}

@end

3 changes: 2 additions & 1 deletion ios/RNCWKWebView.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
@protocol RNCWKWebViewDelegate <NSObject>

- (BOOL)webView:(RNCWKWebView *)webView
shouldStartLoadForRequest:(NSMutableDictionary<NSString *, id> *)request
shouldStartLoadForRequest:(NSMutableDictionary<NSString *, id> *)request
withCallback:(RCTDirectEventBlock)callback;

@end
Expand All @@ -38,6 +38,7 @@ shouldStartLoadForRequest:(NSMutableDictionary<NSString *, id> *)request
@property (nonatomic, assign) BOOL automaticallyAdjustContentInsets;
@property (nonatomic, assign) BOOL hideKeyboardAccessoryView;
@property (nonatomic, assign) BOOL allowsBackForwardNavigationGestures;
@property (nonatomic, assign) BOOL useSharedProcessPool;
@property (nonatomic, copy) NSString *userAgent;
@property (nonatomic, assign) BOOL allowsLinkPreview;

Expand Down
9 changes: 6 additions & 3 deletions ios/RNCWKWebView.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#import "RNCWKWebView.h"
#import <React/RCTConvert.h>
#import <React/RCTAutoInsetsProtocol.h>
#import "RNCWKProcessPoolManager.h"
#import <UIKit/UIKit.h>

#import "objc/runtime.h"
Expand Down Expand Up @@ -60,7 +61,6 @@ + (BOOL)dynamicallyLoadWebKitIfAvailable
return _webkitAvailable;
}


- (instancetype)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame])) {
Expand All @@ -81,6 +81,9 @@ - (void)didMoveToWindow
};

WKWebViewConfiguration *wkWebViewConfig = [WKWebViewConfiguration new];
if(self.useSharedProcessPool) {
wkWebViewConfig.processPool = [[RNCWKProcessPoolManager sharedManager] sharedProcessPool];
}
wkWebViewConfig.userContentController = [WKUserContentController new];
[wkWebViewConfig.userContentController addScriptMessageHandler: self name: MessageHanderName];
wkWebViewConfig.allowsInlineMediaPlayback = _allowsInlineMediaPlayback;
Expand Down Expand Up @@ -308,8 +311,8 @@ - (void)layoutSubviews
/**
* alert
*/
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler
{
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"" message:message preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
completionHandler();
Expand Down
4 changes: 4 additions & 0 deletions ios/RNCWKWebViewManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ - (UIView *)view
view.bounces = json == nil ? true : [RCTConvert BOOL: json];
}

RCT_CUSTOM_VIEW_PROPERTY(useSharedProcessPool, BOOL, RNCWKWebView) {
view.useSharedProcessPool = json == nil ? true : [RCTConvert BOOL: json];
}

RCT_CUSTOM_VIEW_PROPERTY(scrollEnabled, BOOL, RNCWKWebView) {
view.scrollEnabled = json == nil ? true : [RCTConvert BOOL: json];
}
Expand Down
6 changes: 6 additions & 0 deletions ios/RNCWebView.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
3515965E21A3C86000623BFA /* RNCWKProcessPoolManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3515965D21A3C86000623BFA /* RNCWKProcessPoolManager.m */; };
E914DBF6214474710071092B /* RNCUIWebViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E914DBF3214474710071092B /* RNCUIWebViewManager.m */; };
E914DBF7214474710071092B /* RNCUIWebView.m in Sources */ = {isa = PBXBuildFile; fileRef = E914DBF4214474710071092B /* RNCUIWebView.m */; };
E91B351D21446E6C00F9801F /* RNCWKWebViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E91B351B21446E6C00F9801F /* RNCWKWebViewManager.m */; };
Expand All @@ -27,6 +28,8 @@

/* Begin PBXFileReference section */
134814201AA4EA6300B7C361 /* libRNCWebView.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNCWebView.a; sourceTree = BUILT_PRODUCTS_DIR; };
3515965D21A3C86000623BFA /* RNCWKProcessPoolManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNCWKProcessPoolManager.m; sourceTree = "<group>"; };
3515965F21A3C87E00623BFA /* RNCWKProcessPoolManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNCWKProcessPoolManager.h; sourceTree = "<group>"; };
E914DBF2214474710071092B /* RNCUIWebView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNCUIWebView.h; sourceTree = "<group>"; };
E914DBF3214474710071092B /* RNCUIWebViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNCUIWebViewManager.m; sourceTree = "<group>"; };
E914DBF4214474710071092B /* RNCUIWebView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNCUIWebView.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -67,6 +70,8 @@
E91B351C21446E6C00F9801F /* RNCWKWebView.m */,
E91B351921446E6C00F9801F /* RNCWKWebViewManager.h */,
E91B351B21446E6C00F9801F /* RNCWKWebViewManager.m */,
3515965D21A3C86000623BFA /* RNCWKProcessPoolManager.m */,
3515965F21A3C87E00623BFA /* RNCWKProcessPoolManager.h */,
134814211AA4EA7D00B7C361 /* Products */,
);
sourceTree = "<group>";
Expand Down Expand Up @@ -131,6 +136,7 @@
E914DBF7214474710071092B /* RNCUIWebView.m in Sources */,
E914DBF6214474710071092B /* RNCUIWebViewManager.m in Sources */,
E91B351E21446E6C00F9801F /* RNCWKWebView.m in Sources */,
3515965E21A3C86000623BFA /* RNCWKProcessPoolManager.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
2 changes: 2 additions & 0 deletions js/WebView.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ class WebView extends React.Component<WebViewSharedProps, State> {
static defaultProps = {
useWebKit: true,
originWhitelist: defaultOriginWhitelist,
useSharedProcessPool: true,
};

static isFileUploadSupported = async () => {
Expand Down Expand Up @@ -265,6 +266,7 @@ class WebView extends React.Component<WebViewSharedProps, State> {
this.props.mediaPlaybackRequiresUserAction
}
dataDetectorTypes={this.props.dataDetectorTypes}
useSharedProcessPool={this.props.useSharedProcessPool}
allowsLinkPreview={this.props.allowsLinkPreview}
{...nativeConfig.props}
/>
Expand Down
7 changes: 7 additions & 0 deletions js/WebViewTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,13 @@ export type IOSWebViewProps = $ReadOnly<{|
* back-forward list navigations.
*/
allowsBackForwardNavigationGestures?: ?boolean,
/**
* A Boolean value indicating whether WebKit WebView should be created using a shared
* process pool, enabling WebViews to share cookies and localStorage between each other.
* Default is true but can be set to false for backwards compatibility.
* @platform ios
*/
useSharedProcessPool?: ?boolean,
/**
* The custom user agent string.
*/
Expand Down

0 comments on commit afadc62

Please sign in to comment.