Browse Source

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 years ago
parent
commit
83ce79ff89

+ 18
- 0
android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java View File

1
 package com.reactnativecommunity.webview;
1
 package com.reactnativecommunity.webview;
2
 
2
 
3
+import android.annotation.SuppressLint;
3
 import android.annotation.TargetApi;
4
 import android.annotation.TargetApi;
4
 import android.app.DownloadManager;
5
 import android.app.DownloadManager;
5
 import android.content.Context;
6
 import android.content.Context;
7
+
6
 import com.facebook.react.uimanager.UIManagerModule;
8
 import com.facebook.react.uimanager.UIManagerModule;
7
 
9
 
8
 import java.net.MalformedURLException;
10
 import java.net.MalformedURLException;
303
       return new RNCWebViewBridge(webView);
305
       return new RNCWebViewBridge(webView);
304
     }
306
     }
305
 
307
 
308
+    @SuppressLint("AddJavascriptInterface")
306
     public void setMessagingEnabled(boolean enabled) {
309
     public void setMessagingEnabled(boolean enabled) {
307
       if (messagingEnabled == enabled) {
310
       if (messagingEnabled == enabled) {
308
         return;
311
         return;
519
     view.getSettings().setJavaScriptEnabled(enabled);
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
   @ReactProp(name = "androidHardwareAccelerationDisabled")
540
   @ReactProp(name = "androidHardwareAccelerationDisabled")
523
   public void setHardwareAccelerationDisabled(WebView view, boolean disabled) {
541
   public void setHardwareAccelerationDisabled(WebView view, boolean disabled) {
524
     if (disabled) {
542
     if (disabled) {

+ 14
- 3
docs/Reference.md View File

48
 - [`incognito`](Reference.md#incognito)
48
 - [`incognito`](Reference.md#incognito)
49
 - [`allowFileAccess`](Reference.md#allowFileAccess)
49
 - [`allowFileAccess`](Reference.md#allowFileAccess)
50
 - [`saveFormDataDisabled`](Reference.md#saveFormDataDisabled)
50
 - [`saveFormDataDisabled`](Reference.md#saveFormDataDisabled)
51
+- [`cacheEnabled`](Reference.md#cacheEnabled)
51
 - [`pagingEnabled`](Reference.md#pagingEnabled)
52
 - [`pagingEnabled`](Reference.md#pagingEnabled)
52
 - [`allowsLinkPreview`](Reference.md#allowsLinkPreview)
53
 - [`allowsLinkPreview`](Reference.md#allowsLinkPreview)
53
 
54
 
360
 
361
 
361
 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
 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
 
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
 ### `pagingEnabled`
567
 ### `pagingEnabled`
557
 
568
 
558
 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.
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 View File

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

+ 3
- 1
ios/RNCWKWebView.m View File

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

+ 1
- 0
ios/RNCWKWebViewManager.m View File

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

+ 7
- 3
js/WebView.android.js View File

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

+ 7
- 6
js/WebView.ios.js View File

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

+ 5
- 0
js/WebViewTypes.js View File

488
    */
488
    */
489
   nativeConfig?: ?WebViewNativeConfig,
489
   nativeConfig?: ?WebViewNativeConfig,
490
 
490
 
491
+  /**
492
+   * Should caching be enabled. Default is true.
493
+   */
494
+  cacheEnabled?: ?boolean,
495
+
491
   style?: ViewStyleProp,
496
   style?: ViewStyleProp,
492
   children: Node,
497
   children: Node,
493
 |}>;
498
 |}>;