diff --git a/docs/Reference.md b/docs/Reference.md index 2ce7f1e..a41487f 100644 --- a/docs/Reference.md +++ b/docs/Reference.md @@ -17,6 +17,7 @@ This document lays out the current public properties and methods for the React N - [`onHttpError`](Reference.md#onhttperror) - [`onMessage`](Reference.md#onmessage) - [`onNavigationStateChange`](Reference.md#onnavigationstatechange) +- [`onContentProcessDidTerminate`](Reference.md#oncontentprocessdidterminate) - [`originWhitelist`](Reference.md#originwhitelist) - [`renderError`](Reference.md#rendererror) - [`renderLoading`](Reference.md#renderloading) @@ -433,6 +434,40 @@ Note that this method will not be invoked on hash URL changes (e.g. from `https: --- +### `onContentProcessDidTerminate` + +Function that is invoked when the `WebView` content process is terminated. + +| Type | Required | Platform | +| -------- | -------- | ------------- | +| function | No | iOS WKWebView | + +Example: + +```jsx + { + const { nativeEvent } = syntheticEvent; + console.warn('Content process terminated, reloading', nativeEvent); + this.refs.webview.reload() + }} +/> +``` + +Function passed to onContentProcessDidTerminate is called with a SyntheticEvent wrapping a nativeEvent with these properties: + +``` +canGoBack +canGoForward +loading +target +title +url +``` + +--- + ### `originWhitelist` 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://*". diff --git a/ios/RNCWebView.m b/ios/RNCWebView.m index ec098b4..0a5b70b 100644 --- a/ios/RNCWebView.m +++ b/ios/RNCWebView.m @@ -37,6 +37,7 @@ static NSDictionary* customCertificatesForHost; @property (nonatomic, copy) RCTDirectEventBlock onHttpError; @property (nonatomic, copy) RCTDirectEventBlock onMessage; @property (nonatomic, copy) RCTDirectEventBlock onScroll; +@property (nonatomic, copy) RCTDirectEventBlock onContentProcessDidTerminate; @property (nonatomic, copy) WKWebView *webView; @end @@ -833,6 +834,19 @@ static NSDictionary* customCertificatesForHost; decisionHandler(WKNavigationResponsePolicyAllow); } +/** + * Called when the web view’s content process is terminated. + * @see https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455639-webviewwebcontentprocessdidtermi?language=objc + */ +- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView +{ + RCTLogWarn(@"Webview Process Terminated"); + if (_onContentProcessDidTerminate) { + NSMutableDictionary *event = [self baseEvent]; + _onContentProcessDidTerminate(event); + } +} + /** * Decides whether to allow or cancel a navigation after its response is known. * @see https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455643-webview?language=objc diff --git a/ios/RNCWebViewManager.m b/ios/RNCWebViewManager.m index 03c7890..5fe6dc9 100644 --- a/ios/RNCWebViewManager.m +++ b/ios/RNCWebViewManager.m @@ -49,6 +49,7 @@ RCT_EXPORT_VIEW_PROPERTY(onLoadingError, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(onLoadingProgress, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(onHttpError, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(onShouldStartLoadWithRequest, RCTDirectEventBlock) +RCT_EXPORT_VIEW_PROPERTY(onContentProcessDidTerminate, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(injectedJavaScript, NSString) RCT_EXPORT_VIEW_PROPERTY(javaScriptEnabled, BOOL) RCT_EXPORT_VIEW_PROPERTY(allowsInlineMediaPlayback, BOOL) diff --git a/src/WebView.ios.tsx b/src/WebView.ios.tsx index 553c217..edb4e64 100644 --- a/src/WebView.ios.tsx +++ b/src/WebView.ios.tsx @@ -22,6 +22,7 @@ import { WebViewMessageEvent, WebViewNavigationEvent, WebViewProgressEvent, + WebViewTerminatedEvent, IOSWebViewProps, DecelerationRateConstant, NativeWebViewIOS, @@ -255,6 +256,13 @@ class WebView extends React.Component { viewManager.startLoadWithResult(!!shouldStart, lockIdentifier); }; + onContentProcessDidTerminate = (event: WebViewTerminatedEvent) => { + const { onContentProcessDidTerminate } = this.props; + if (onContentProcessDidTerminate) { + onContentProcessDidTerminate(event); + } + }; + componentDidUpdate(prevProps: IOSWebViewProps) { this.showRedboxOnPropChanges(prevProps, 'allowsInlineMediaPlayback'); this.showRedboxOnPropChanges(prevProps, 'incognito'); @@ -333,6 +341,7 @@ class WebView extends React.Component { onMessage={this.onMessage} onScroll={this.props.onScroll} onShouldStartLoadWithRequest={onShouldStartLoadWithRequest} + onContentProcessDidTerminate={this.onContentProcessDidTerminate} ref={this.webViewRef} // TODO: find a better way to type this. source={resolveAssetSource(this.props.source as ImageSourcePropType)} diff --git a/src/WebViewTypes.ts b/src/WebViewTypes.ts index 3cec75f..7bfe61c 100644 --- a/src/WebViewTypes.ts +++ b/src/WebViewTypes.ts @@ -126,6 +126,8 @@ export type WebViewMessageEvent = NativeSyntheticEvent; export type WebViewErrorEvent = NativeSyntheticEvent; +export type WebViewTerminatedEvent = NativeSyntheticEvent; + export type WebViewHttpErrorEvent = NativeSyntheticEvent; export type DataDetectorTypes = @@ -269,6 +271,7 @@ export interface IOSNativeWebViewProps extends CommonNativeWebViewProps { pagingEnabled?: boolean; scrollEnabled?: boolean; useSharedProcessPool?: boolean; + onContentProcessDidTerminate: (event: WebViewTerminatedEvent) => void; } export interface IOSWebViewProps extends WebViewSharedProps { @@ -442,6 +445,12 @@ export interface IOSWebViewProps extends WebViewSharedProps { * @platform ios */ allowingReadAccessToURL?: string; + + /** + * Function that is invoked when the WebKit WebView content process gets terminated. + * @platform ios + */ + onContentProcessDidTerminate: (event: WebViewTerminatedEvent) => void; } export interface AndroidWebViewProps extends WebViewSharedProps {