瀏覽代碼

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.
Michael Diarmid 5 年之前
父節點
當前提交
83ce79ff89

+ 18
- 0
android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java 查看文件

@@ -1,8 +1,10 @@
1 1
 package com.reactnativecommunity.webview;
2 2
 
3
+import android.annotation.SuppressLint;
3 4
 import android.annotation.TargetApi;
4 5
 import android.app.DownloadManager;
5 6
 import android.content.Context;
7
+
6 8
 import com.facebook.react.uimanager.UIManagerModule;
7 9
 
8 10
 import java.net.MalformedURLException;
@@ -303,6 +305,7 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
303 305
       return new RNCWebViewBridge(webView);
304 306
     }
305 307
 
308
+    @SuppressLint("AddJavascriptInterface")
306 309
     public void setMessagingEnabled(boolean enabled) {
307 310
       if (messagingEnabled == enabled) {
308 311
         return;
@@ -519,6 +522,21 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
519 522
     view.getSettings().setJavaScriptEnabled(enabled);
520 523
   }
521 524
 
525
+  @ReactProp(name = "cacheEnabled")
526
+  public void setCacheEnabled(WebView view, boolean enabled) {
527
+    if (enabled) {
528
+      Context ctx = view.getContext();
529
+      if (ctx != null) {
530
+        view.getSettings().setAppCachePath(ctx.getCacheDir().getAbsolutePath());
531
+        view.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
532
+        view.getSettings().setAppCacheEnabled(true);
533
+      }
534
+    } else {
535
+      view.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
536
+      view.getSettings().setAppCacheEnabled(false);
537
+    }
538
+  }
539
+
522 540
   @ReactProp(name = "androidHardwareAccelerationDisabled")
523 541
   public void setHardwareAccelerationDisabled(WebView view, boolean disabled) {
524 542
     if (disabled) {

+ 14
- 3
docs/Reference.md 查看文件

@@ -48,6 +48,7 @@ This document lays out the current public properties and methods for the React N
48 48
 - [`incognito`](Reference.md#incognito)
49 49
 - [`allowFileAccess`](Reference.md#allowFileAccess)
50 50
 - [`saveFormDataDisabled`](Reference.md#saveFormDataDisabled)
51
+- [`cacheEnabled`](Reference.md#cacheEnabled)
51 52
 - [`pagingEnabled`](Reference.md#pagingEnabled)
52 53
 - [`allowsLinkPreview`](Reference.md#allowsLinkPreview)
53 54
 
@@ -360,9 +361,9 @@ Boolean value to enable third party cookies in the `WebView`. Used on Android Lo
360 361
 
361 362
 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).
362 363
 
363
-| Type   | Required | Platform |
364
-| ------ | -------- | -------- |
365
-| string | No       | Android, iOS WKWebView  |
364
+| Type   | Required | Platform               |
365
+| ------ | -------- | ---------------------- |
366
+| string | No       | Android, iOS WKWebView |
366 367
 
367 368
 ---
368 369
 
@@ -553,6 +554,16 @@ Sets whether the WebView should disable saving form data. The default value is `
553 554
 
554 555
 ---
555 556
 
557
+### `cacheEnabled`
558
+
559
+Sets whether WebView & WKWebView should use browser caching.
560
+
561
+| Type    | Required | Default |
562
+| ------- | -------- | ------- |
563
+| boolean | No       | true    |
564
+
565
+---
566
+
556 567
 ### `pagingEnabled`
557 568
 
558 569
 If the value of this property is true, the scroll view stops on multiples of the scroll view’s bounds when the user scrolls. The default value is false.

+ 1
- 0
ios/RNCWKWebView.h 查看文件

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

+ 3
- 1
ios/RNCWKWebView.m 查看文件

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

+ 1
- 0
ios/RNCWKWebViewManager.m 查看文件

@@ -48,6 +48,7 @@ RCT_EXPORT_VIEW_PROPERTY(allowsBackForwardNavigationGestures, BOOL)
48 48
 RCT_EXPORT_VIEW_PROPERTY(incognito, BOOL)
49 49
 RCT_EXPORT_VIEW_PROPERTY(pagingEnabled, BOOL)
50 50
 RCT_EXPORT_VIEW_PROPERTY(userAgent, NSString)
51
+RCT_EXPORT_VIEW_PROPERTY(cacheEnabled, BOOL)
51 52
 RCT_EXPORT_VIEW_PROPERTY(allowsLinkPreview, BOOL)
52 53
 
53 54
 /**

+ 7
- 3
js/WebView.android.js 查看文件

@@ -17,7 +17,7 @@ import ReactNative, {
17 17
   StyleSheet,
18 18
   UIManager,
19 19
   View,
20
-  NativeModules
20
+  NativeModules,
21 21
 } from 'react-native';
22 22
 
23 23
 import invariant from 'fbjs/lib/invariant';
@@ -67,6 +67,7 @@ class WebView extends React.Component<WebViewSharedProps, State> {
67 67
     scalesPageToFit: true,
68 68
     allowFileAccess: false,
69 69
     saveFormDataDisabled: false,
70
+    cacheEnabled: true,
70 71
     androidHardwareAccelerationDisabled: false,
71 72
     originWhitelist: defaultOriginWhitelist,
72 73
   };
@@ -74,7 +75,7 @@ class WebView extends React.Component<WebViewSharedProps, State> {
74 75
   static isFileUploadSupported = async () => {
75 76
     // native implementation should return "true" only for Android 5+
76 77
     return NativeModules.RNCWebView.isFileUploadSupported();
77
-  }
78
+  };
78 79
 
79 80
   state = {
80 81
     viewState: this.props.startInLoadingState
@@ -151,10 +152,13 @@ class WebView extends React.Component<WebViewSharedProps, State> {
151 152
         injectedJavaScript={this.props.injectedJavaScript}
152 153
         userAgent={this.props.userAgent}
153 154
         javaScriptEnabled={this.props.javaScriptEnabled}
154
-        androidHardwareAccelerationDisabled={this.props.androidHardwareAccelerationDisabled}
155
+        androidHardwareAccelerationDisabled={
156
+          this.props.androidHardwareAccelerationDisabled
157
+        }
155 158
         thirdPartyCookiesEnabled={this.props.thirdPartyCookiesEnabled}
156 159
         domStorageEnabled={this.props.domStorageEnabled}
157 160
         messagingEnabled={typeof this.props.onMessage === 'function'}
161
+        cacheEnabled={this.props.cacheEnabled}
158 162
         onMessage={this.onMessage}
159 163
         overScrollMode={this.props.overScrollMode}
160 164
         contentInset={this.props.contentInset}

+ 7
- 6
js/WebView.ios.js 查看文件

@@ -133,6 +133,7 @@ class WebView extends React.Component<WebViewSharedProps, State> {
133 133
 
134 134
   static defaultProps = {
135 135
     useWebKit: true,
136
+    cacheEnabled: true,
136 137
     originWhitelist: defaultOriginWhitelist,
137 138
     useSharedProcessPool: true,
138 139
   };
@@ -140,7 +141,7 @@ class WebView extends React.Component<WebViewSharedProps, State> {
140 141
   static isFileUploadSupported = async () => {
141 142
     // no native implementation for iOS, depends only on permissions
142 143
     return true;
143
-  }
144
+  };
144 145
 
145 146
   state = {
146 147
     viewState: this.props.startInLoadingState
@@ -169,10 +170,7 @@ class WebView extends React.Component<WebViewSharedProps, State> {
169 170
       );
170 171
     }
171 172
 
172
-    if (
173
-      !this.props.useWebKit &&
174
-      this.props.incognito
175
-    ) {
173
+    if (!this.props.useWebKit && this.props.incognito) {
176 174
       console.warn(
177 175
         'The incognito property is not supported when useWebKit = false',
178 176
       );
@@ -254,13 +252,16 @@ class WebView extends React.Component<WebViewSharedProps, State> {
254 252
         bounces={this.props.bounces}
255 253
         scrollEnabled={this.props.scrollEnabled}
256 254
         pagingEnabled={this.props.pagingEnabled}
255
+        cacheEnabled={this.props.cacheEnabled}
257 256
         decelerationRate={decelerationRate}
258 257
         contentInset={this.props.contentInset}
259 258
         automaticallyAdjustContentInsets={
260 259
           this.props.automaticallyAdjustContentInsets
261 260
         }
262 261
         hideKeyboardAccessoryView={this.props.hideKeyboardAccessoryView}
263
-        allowsBackForwardNavigationGestures={this.props.allowsBackForwardNavigationGestures}
262
+        allowsBackForwardNavigationGestures={
263
+          this.props.allowsBackForwardNavigationGestures
264
+        }
264 265
         incognito={this.props.incognito}
265 266
         userAgent={this.props.userAgent}
266 267
         onLoadingStart={this._onLoadingStart}

+ 5
- 0
js/WebViewTypes.js 查看文件

@@ -488,6 +488,11 @@ export type WebViewSharedProps = $ReadOnly<{|
488 488
    */
489 489
   nativeConfig?: ?WebViewNativeConfig,
490 490
 
491
+  /**
492
+   * Should caching be enabled. Default is true.
493
+   */
494
+  cacheEnabled?: ?boolean,
495
+
491 496
   style?: ViewStyleProp,
492 497
   children: Node,
493 498
 |}>;