feat(iOS/Android): Add `cacheEnabled` prop (#152)

Added a new cacheEnabled prop to toggle Android & iOS webview caching behavior.

BREAKING CHANGE:  This change makes caching enabled by default when previously there was no caching behavior which may cause unexpected behaviour changes in your existing implementations.
This commit is contained in:
Michael Diarmid 2019-01-30 09:32:46 +00:00 committed by Thibault Malbranche
parent de4130c7d8
commit 83ce79ff89
8 changed files with 56 additions and 13 deletions

View File

@ -1,8 +1,10 @@
package com.reactnativecommunity.webview;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.DownloadManager;
import android.content.Context;
import com.facebook.react.uimanager.UIManagerModule;
import java.net.MalformedURLException;
@ -303,6 +305,7 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
return new RNCWebViewBridge(webView);
}
@SuppressLint("AddJavascriptInterface")
public void setMessagingEnabled(boolean enabled) {
if (messagingEnabled == enabled) {
return;
@ -519,6 +522,21 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
view.getSettings().setJavaScriptEnabled(enabled);
}
@ReactProp(name = "cacheEnabled")
public void setCacheEnabled(WebView view, boolean enabled) {
if (enabled) {
Context ctx = view.getContext();
if (ctx != null) {
view.getSettings().setAppCachePath(ctx.getCacheDir().getAbsolutePath());
view.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
view.getSettings().setAppCacheEnabled(true);
}
} else {
view.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
view.getSettings().setAppCacheEnabled(false);
}
}
@ReactProp(name = "androidHardwareAccelerationDisabled")
public void setHardwareAccelerationDisabled(WebView view, boolean disabled) {
if (disabled) {

View File

@ -48,6 +48,7 @@ This document lays out the current public properties and methods for the React N
- [`incognito`](Reference.md#incognito)
- [`allowFileAccess`](Reference.md#allowFileAccess)
- [`saveFormDataDisabled`](Reference.md#saveFormDataDisabled)
- [`cacheEnabled`](Reference.md#cacheEnabled)
- [`pagingEnabled`](Reference.md#pagingEnabled)
- [`allowsLinkPreview`](Reference.md#allowsLinkPreview)
@ -360,9 +361,9 @@ Boolean value to enable third party cookies in the `WebView`. Used on Android Lo
Sets the user-agent for the `WebView`. This will only work for iOS if you are using WKWebView, not UIWebView (see https://developer.apple.com/documentation/webkit/wkwebview/1414950-customuseragent).
| Type | Required | Platform |
| ------ | -------- | -------- |
| string | No | Android, iOS WKWebView |
| Type | Required | Platform |
| ------ | -------- | ---------------------- |
| string | No | Android, iOS WKWebView |
---
@ -553,6 +554,16 @@ Sets whether the WebView should disable saving form data. The default value is `
---
### `cacheEnabled`
Sets whether WebView & WKWebView should use browser caching.
| Type | Required | Default |
| ------- | -------- | ------- |
| boolean | No | true |
---
### `pagingEnabled`
If the value of this property is true, the scroll view stops on multiples of the scroll views bounds when the user scrolls. The default value is false.

View File

@ -41,6 +41,7 @@
@property (nonatomic, assign) BOOL incognito;
@property (nonatomic, assign) BOOL useSharedProcessPool;
@property (nonatomic, copy) NSString *userAgent;
@property (nonatomic, assign) BOOL cacheEnabled;
@property (nonatomic, assign) BOOL allowsLinkPreview;
- (void)postMessage:(NSString *)message;

View File

@ -83,9 +83,11 @@ static NSString *const MessageHanderName = @"ReactNative";
WKWebViewConfiguration *wkWebViewConfig = [WKWebViewConfiguration new];
if (_incognito) {
wkWebViewConfig.websiteDataStore = [WKWebsiteDataStore nonPersistentDataStore];
} else if (_cacheEnabled) {
wkWebViewConfig.websiteDataStore = [WKWebsiteDataStore defaultDataStore];
}
if(self.useSharedProcessPool) {
wkWebViewConfig.processPool = [[RNCWKProcessPoolManager sharedManager] sharedProcessPool];
wkWebViewConfig.processPool = [[RNCWKProcessPoolManager sharedManager] sharedProcessPool];
}
wkWebViewConfig.userContentController = [WKUserContentController new];
[wkWebViewConfig.userContentController addScriptMessageHandler: self name: MessageHanderName];

View File

@ -48,6 +48,7 @@ RCT_EXPORT_VIEW_PROPERTY(allowsBackForwardNavigationGestures, BOOL)
RCT_EXPORT_VIEW_PROPERTY(incognito, BOOL)
RCT_EXPORT_VIEW_PROPERTY(pagingEnabled, BOOL)
RCT_EXPORT_VIEW_PROPERTY(userAgent, NSString)
RCT_EXPORT_VIEW_PROPERTY(cacheEnabled, BOOL)
RCT_EXPORT_VIEW_PROPERTY(allowsLinkPreview, BOOL)
/**

View File

@ -17,7 +17,7 @@ import ReactNative, {
StyleSheet,
UIManager,
View,
NativeModules
NativeModules,
} from 'react-native';
import invariant from 'fbjs/lib/invariant';
@ -67,6 +67,7 @@ class WebView extends React.Component<WebViewSharedProps, State> {
scalesPageToFit: true,
allowFileAccess: false,
saveFormDataDisabled: false,
cacheEnabled: true,
androidHardwareAccelerationDisabled: false,
originWhitelist: defaultOriginWhitelist,
};
@ -74,7 +75,7 @@ class WebView extends React.Component<WebViewSharedProps, State> {
static isFileUploadSupported = async () => {
// native implementation should return "true" only for Android 5+
return NativeModules.RNCWebView.isFileUploadSupported();
}
};
state = {
viewState: this.props.startInLoadingState
@ -151,10 +152,13 @@ class WebView extends React.Component<WebViewSharedProps, State> {
injectedJavaScript={this.props.injectedJavaScript}
userAgent={this.props.userAgent}
javaScriptEnabled={this.props.javaScriptEnabled}
androidHardwareAccelerationDisabled={this.props.androidHardwareAccelerationDisabled}
androidHardwareAccelerationDisabled={
this.props.androidHardwareAccelerationDisabled
}
thirdPartyCookiesEnabled={this.props.thirdPartyCookiesEnabled}
domStorageEnabled={this.props.domStorageEnabled}
messagingEnabled={typeof this.props.onMessage === 'function'}
cacheEnabled={this.props.cacheEnabled}
onMessage={this.onMessage}
overScrollMode={this.props.overScrollMode}
contentInset={this.props.contentInset}

View File

@ -133,6 +133,7 @@ class WebView extends React.Component<WebViewSharedProps, State> {
static defaultProps = {
useWebKit: true,
cacheEnabled: true,
originWhitelist: defaultOriginWhitelist,
useSharedProcessPool: true,
};
@ -140,7 +141,7 @@ class WebView extends React.Component<WebViewSharedProps, State> {
static isFileUploadSupported = async () => {
// no native implementation for iOS, depends only on permissions
return true;
}
};
state = {
viewState: this.props.startInLoadingState
@ -169,10 +170,7 @@ class WebView extends React.Component<WebViewSharedProps, State> {
);
}
if (
!this.props.useWebKit &&
this.props.incognito
) {
if (!this.props.useWebKit && this.props.incognito) {
console.warn(
'The incognito property is not supported when useWebKit = false',
);
@ -254,13 +252,16 @@ class WebView extends React.Component<WebViewSharedProps, State> {
bounces={this.props.bounces}
scrollEnabled={this.props.scrollEnabled}
pagingEnabled={this.props.pagingEnabled}
cacheEnabled={this.props.cacheEnabled}
decelerationRate={decelerationRate}
contentInset={this.props.contentInset}
automaticallyAdjustContentInsets={
this.props.automaticallyAdjustContentInsets
}
hideKeyboardAccessoryView={this.props.hideKeyboardAccessoryView}
allowsBackForwardNavigationGestures={this.props.allowsBackForwardNavigationGestures}
allowsBackForwardNavigationGestures={
this.props.allowsBackForwardNavigationGestures
}
incognito={this.props.incognito}
userAgent={this.props.userAgent}
onLoadingStart={this._onLoadingStart}

View File

@ -488,6 +488,11 @@ export type WebViewSharedProps = $ReadOnly<{|
*/
nativeConfig?: ?WebViewNativeConfig,
/**
* Should caching be enabled. Default is true.
*/
cacheEnabled?: ?boolean,
style?: ViewStyleProp,
children: Node,
|}>;