Browse Source

feat(iOS): Add callback for webViewWebContentProcessDidTerminate (#774)

* Add callback for WKWebView's onContentProcessDidTerminate

* Add platform information to docs

* Add new WebViewTerminatedEvent type
Samuel Sieg 4 years ago
parent
commit
a76811da93
5 changed files with 68 additions and 0 deletions
  1. 35
    0
      docs/Reference.md
  2. 14
    0
      ios/RNCWebView.m
  3. 1
    0
      ios/RNCWebViewManager.m
  4. 9
    0
      src/WebView.ios.tsx
  5. 9
    0
      src/WebViewTypes.ts

+ 35
- 0
docs/Reference.md View File

17
 - [`onHttpError`](Reference.md#onhttperror)
17
 - [`onHttpError`](Reference.md#onhttperror)
18
 - [`onMessage`](Reference.md#onmessage)
18
 - [`onMessage`](Reference.md#onmessage)
19
 - [`onNavigationStateChange`](Reference.md#onnavigationstatechange)
19
 - [`onNavigationStateChange`](Reference.md#onnavigationstatechange)
20
+- [`onContentProcessDidTerminate`](Reference.md#oncontentprocessdidterminate)
20
 - [`originWhitelist`](Reference.md#originwhitelist)
21
 - [`originWhitelist`](Reference.md#originwhitelist)
21
 - [`renderError`](Reference.md#rendererror)
22
 - [`renderError`](Reference.md#rendererror)
22
 - [`renderLoading`](Reference.md#renderloading)
23
 - [`renderLoading`](Reference.md#renderloading)
433
 
434
 
434
 ---
435
 ---
435
 
436
 
437
+### `onContentProcessDidTerminate`
438
+
439
+Function that is invoked when the `WebView` content process is terminated.
440
+
441
+| Type     | Required | Platform      |
442
+| -------- | -------- | ------------- |
443
+| function | No       | iOS WKWebView |
444
+
445
+Example:
446
+
447
+```jsx
448
+<WebView
449
+  source={{ uri: 'https://facebook.github.io/react-native' }}
450
+  onContentProcessDidTerminate={syntheticEvent => {
451
+    const { nativeEvent } = syntheticEvent;
452
+    console.warn('Content process terminated, reloading', nativeEvent);
453
+    this.refs.webview.reload()
454
+  }}
455
+/>
456
+```
457
+
458
+Function passed to onContentProcessDidTerminate is called with a SyntheticEvent wrapping a nativeEvent with these properties:
459
+
460
+```
461
+canGoBack
462
+canGoForward
463
+loading
464
+target
465
+title
466
+url
467
+```
468
+
469
+---
470
+
436
 ### `originWhitelist`
471
 ### `originWhitelist`
437
 
472
 
438
 List of origin strings to allow being navigated to. The strings allow wildcards and get matched against _just_ the origin (not the full URL). If the user taps to navigate to a new page but the new page is not in this whitelist, the URL will be handled by the OS. The default whitelisted origins are "http://*" and "https://*".
473
 List of origin strings to allow being navigated to. The strings allow wildcards and get matched against _just_ the origin (not the full URL). If the user taps to navigate to a new page but the new page is not in this whitelist, the URL will be handled by the OS. The default whitelisted origins are "http://*" and "https://*".

+ 14
- 0
ios/RNCWebView.m View File

37
 @property (nonatomic, copy) RCTDirectEventBlock onHttpError;
37
 @property (nonatomic, copy) RCTDirectEventBlock onHttpError;
38
 @property (nonatomic, copy) RCTDirectEventBlock onMessage;
38
 @property (nonatomic, copy) RCTDirectEventBlock onMessage;
39
 @property (nonatomic, copy) RCTDirectEventBlock onScroll;
39
 @property (nonatomic, copy) RCTDirectEventBlock onScroll;
40
+@property (nonatomic, copy) RCTDirectEventBlock onContentProcessDidTerminate;
40
 @property (nonatomic, copy) WKWebView *webView;
41
 @property (nonatomic, copy) WKWebView *webView;
41
 @end
42
 @end
42
 
43
 
833
   decisionHandler(WKNavigationResponsePolicyAllow);
834
   decisionHandler(WKNavigationResponsePolicyAllow);
834
 }
835
 }
835
 
836
 
837
+/**
838
+ * Called when the web view’s content process is terminated.
839
+ * @see https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455639-webviewwebcontentprocessdidtermi?language=objc
840
+ */
841
+- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView
842
+{
843
+  RCTLogWarn(@"Webview Process Terminated");
844
+  if (_onContentProcessDidTerminate) {
845
+    NSMutableDictionary<NSString *, id> *event = [self baseEvent];
846
+    _onContentProcessDidTerminate(event);
847
+  }
848
+}
849
+
836
 /**
850
 /**
837
  * Decides whether to allow or cancel a navigation after its response is known.
851
  * Decides whether to allow or cancel a navigation after its response is known.
838
  * @see https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455643-webview?language=objc
852
  * @see https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455643-webview?language=objc

+ 1
- 0
ios/RNCWebViewManager.m View File

49
 RCT_EXPORT_VIEW_PROPERTY(onLoadingProgress, RCTDirectEventBlock)
49
 RCT_EXPORT_VIEW_PROPERTY(onLoadingProgress, RCTDirectEventBlock)
50
 RCT_EXPORT_VIEW_PROPERTY(onHttpError, RCTDirectEventBlock)
50
 RCT_EXPORT_VIEW_PROPERTY(onHttpError, RCTDirectEventBlock)
51
 RCT_EXPORT_VIEW_PROPERTY(onShouldStartLoadWithRequest, RCTDirectEventBlock)
51
 RCT_EXPORT_VIEW_PROPERTY(onShouldStartLoadWithRequest, RCTDirectEventBlock)
52
+RCT_EXPORT_VIEW_PROPERTY(onContentProcessDidTerminate, RCTDirectEventBlock)
52
 RCT_EXPORT_VIEW_PROPERTY(injectedJavaScript, NSString)
53
 RCT_EXPORT_VIEW_PROPERTY(injectedJavaScript, NSString)
53
 RCT_EXPORT_VIEW_PROPERTY(javaScriptEnabled, BOOL)
54
 RCT_EXPORT_VIEW_PROPERTY(javaScriptEnabled, BOOL)
54
 RCT_EXPORT_VIEW_PROPERTY(allowsInlineMediaPlayback, BOOL)
55
 RCT_EXPORT_VIEW_PROPERTY(allowsInlineMediaPlayback, BOOL)

+ 9
- 0
src/WebView.ios.tsx View File

22
   WebViewMessageEvent,
22
   WebViewMessageEvent,
23
   WebViewNavigationEvent,
23
   WebViewNavigationEvent,
24
   WebViewProgressEvent,
24
   WebViewProgressEvent,
25
+  WebViewTerminatedEvent,
25
   IOSWebViewProps,
26
   IOSWebViewProps,
26
   DecelerationRateConstant,
27
   DecelerationRateConstant,
27
   NativeWebViewIOS,
28
   NativeWebViewIOS,
255
     viewManager.startLoadWithResult(!!shouldStart, lockIdentifier);
256
     viewManager.startLoadWithResult(!!shouldStart, lockIdentifier);
256
   };
257
   };
257
 
258
 
259
+  onContentProcessDidTerminate = (event: WebViewTerminatedEvent) => {
260
+    const { onContentProcessDidTerminate } = this.props;
261
+    if (onContentProcessDidTerminate) {
262
+      onContentProcessDidTerminate(event);
263
+    }
264
+  };
265
+
258
   componentDidUpdate(prevProps: IOSWebViewProps) {
266
   componentDidUpdate(prevProps: IOSWebViewProps) {
259
     this.showRedboxOnPropChanges(prevProps, 'allowsInlineMediaPlayback');
267
     this.showRedboxOnPropChanges(prevProps, 'allowsInlineMediaPlayback');
260
     this.showRedboxOnPropChanges(prevProps, 'incognito');
268
     this.showRedboxOnPropChanges(prevProps, 'incognito');
333
         onMessage={this.onMessage}
341
         onMessage={this.onMessage}
334
         onScroll={this.props.onScroll}
342
         onScroll={this.props.onScroll}
335
         onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
343
         onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
344
+        onContentProcessDidTerminate={this.onContentProcessDidTerminate}
336
         ref={this.webViewRef}
345
         ref={this.webViewRef}
337
         // TODO: find a better way to type this.
346
         // TODO: find a better way to type this.
338
         source={resolveAssetSource(this.props.source as ImageSourcePropType)}
347
         source={resolveAssetSource(this.props.source as ImageSourcePropType)}

+ 9
- 0
src/WebViewTypes.ts View File

126
 
126
 
127
 export type WebViewErrorEvent = NativeSyntheticEvent<WebViewError>;
127
 export type WebViewErrorEvent = NativeSyntheticEvent<WebViewError>;
128
 
128
 
129
+export type WebViewTerminatedEvent = NativeSyntheticEvent<WebViewNativeEvent>;
130
+
129
 export type WebViewHttpErrorEvent = NativeSyntheticEvent<WebViewHttpError>;
131
 export type WebViewHttpErrorEvent = NativeSyntheticEvent<WebViewHttpError>;
130
 
132
 
131
 export type DataDetectorTypes =
133
 export type DataDetectorTypes =
269
   pagingEnabled?: boolean;
271
   pagingEnabled?: boolean;
270
   scrollEnabled?: boolean;
272
   scrollEnabled?: boolean;
271
   useSharedProcessPool?: boolean;
273
   useSharedProcessPool?: boolean;
274
+  onContentProcessDidTerminate: (event: WebViewTerminatedEvent) => void;
272
 }
275
 }
273
 
276
 
274
 export interface IOSWebViewProps extends WebViewSharedProps {
277
 export interface IOSWebViewProps extends WebViewSharedProps {
442
    * @platform ios
445
    * @platform ios
443
    */
446
    */
444
   allowingReadAccessToURL?: string;
447
   allowingReadAccessToURL?: string;
448
+
449
+  /**
450
+   * Function that is invoked when the WebKit WebView content process gets terminated.
451
+   * @platform ios
452
+   */
453
+  onContentProcessDidTerminate: (event: WebViewTerminatedEvent) => void;
445
 }
454
 }
446
 
455
 
447
 export interface AndroidWebViewProps extends WebViewSharedProps {
456
 export interface AndroidWebViewProps extends WebViewSharedProps {