abroa01 commented on issue #1355: URL: https://github.com/apache/cordova-ios/issues/1355#issuecomment-3206769454
## Update on our findings We've been investigating this issue and have successfully implemented a workaround that's preventing the white screen problem in our app. I wanted to share our findings with the community. ### What we discovered Looking at the logs when the WebKit process crashes, we can confirm that `webViewWebContentProcessDidTerminate` IS being called in our case: ``` 0x112009420 - [PID=15090] WebProcessProxy::didClose: (web process 0 crash) 0x113834e18 - [pageProxyID=19, webPageID=20, PID=15090] WebPageProxy::processDidTerminate: (pid 15090), reason=Crash CDVWebViewEngine: Inside webViewWebContentProcessDidTerminate - Web content process terminated, reloading with cached URL CDVWebViewEngine : Inside webViewWebContentProcessDidTerminate - using cached good URL for process termination reload: http://localhost:12280/?cdvToken=... ``` However, we also see that `shouldReloadWebView` is still being called periodically and returning 0 (false), confirming the original bug about the flawed nil checking logic: ``` CDVWebViewEngine shouldReloadWebView:: CDVWebViewEngine shouldReloadWebView title: Meteor App CDVWebViewEngine shouldReloadWebView location: http://localhost:12280/register CDVWebViewEngine shouldReloadWebView reload: 0 ``` <img width="2892" height="1154" alt="Image" src="https://github.com/user-attachments/assets/7d4c9957-802e-4a26-898c-09325663a0c6" /> ### Our solution: Last good URL caching mechanism We've implemented a URL caching approach that stores successful page loads and uses them during recovery scenarios. Here are the key changes to `CDVWebViewEngine.m`: #### 1. Cache successful navigations ```objc - (void)webView:(WKWebView*)webView didFinishNavigation:(WKNavigation*)navigation { // Always cache successful URL loads if (webView.URL && ![webView.URL.absoluteString isEqualToString:@"about:blank"] && ![webView.URL.absoluteString isEqualToString:@""]) { self.lastGoodURL = webView.URL; NSLog(@"CDVWebViewEngine cached good URL: %@", webView.URL.absoluteString); } [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:CDVPageDidLoadNotification object:webView]]; } ``` #### 2. Enhanced recovery in webViewWebContentProcessDidTerminate ```objc - (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView { NSLog(@"CDVWebViewEngine: Inside webViewWebContentProcessDidTerminate - Web content process terminated, reloading with cached URL"); NSURL* currentURL = webView.URL; NSURL* url; if (self.lastGoodURL) { url = self.lastGoodURL; // Priority 1: Last known good URL NSLog(@"CDVWebViewEngine : Inside webViewWebContentProcessDidTerminate - using cached good URL for process termination reload: %@", url.absoluteString); } else if (currentURL && ![currentURL.absoluteString isEqualToString:@"about:blank"] && ![currentURL.absoluteString isEqualToString:@""]) { url = currentURL; // Priority 2: Current URL NSLog(@"CDVWebViewEngine : Inside webViewWebContentProcessDidTerminate - using current page URL for process termination reload: %@", url.absoluteString); } else { url = [((CDVViewController*) self.viewController) appUrl]; // Priority 3: App URL NSLog(@"CDVWebViewEngine : Inside webViewWebContentProcessDidTerminate - using fallback app URL for process termination reload: %@", url.absoluteString); } NSURLRequest* appReq = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20.0]; [webView loadRequest:appReq]; } ``` #### 3. Same approach for onAppWillEnterForeground ```objc - (void) onAppWillEnterForeground:(NSNotification*)notification { if ([self shouldReloadWebView]) { NSLog(@"%@", @"CDVWebViewEngine reloading!"); WKWebView* wkWebView = (WKWebView*)_engineWebView; NSURL* currentURL = wkWebView.URL; NSURL* url; if (self.lastGoodURL) { url = self.lastGoodURL; NSLog(@"CDVWebViewEngine using cached good URL for reload: %@", url.absoluteString); } else if (currentURL && ![currentURL.absoluteString isEqualToString:@"about:blank"] && ![currentURL.absoluteString isEqualToString:@""]) { url = currentURL; NSLog(@"CDVWebViewEngine using current page URL for reload: %@", url.absoluteString); } else { url = [((CDVViewController*) self.viewController) appUrl]; NSLog(@"CDVWebViewEngine using fallback app URL for reload: %@", url.absoluteString); } NSURLRequest* appReq = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20.0]; [wkWebView loadRequest:appReq]; } } ``` #### 4. Additional safety in shouldReloadWebView ```objc - (BOOL)shouldReloadWebView:(NSURL*)location title:(NSString*)title { BOOL title_is_nil = (title == nil) || [title isEqualToString:@""]; BOOL location_is_blank = [[location absoluteString] isEqualToString:@"about:blank"]; BOOL reload = (title_is_nil || location_is_blank); // Debug logs showing the evaluation NSLog(@"CDVWebViewEngine shouldReloadWebView::"); NSLog(@"CDVWebViewEngine shouldReloadWebView title: %@", title); NSLog(@"CDVWebViewEngine shouldReloadWebView location: %@", [location absoluteString]); NSLog(@"CDVWebViewEngine shouldReloadWebView reload: %u", reload); return reload; } ``` ### What the logs prove From our test session logs: 1. **WebKit process crashes**: `WebProcessProxy::didClose: (web process 0 crash)` 2. **Our handler fires immediately**: `CDVWebViewEngine: Inside webViewWebContentProcessDidTerminate` 3. **Successfully recovers using cached URL**: `using cached good URL for process termination reload: http://localhost:12280/?cdvToken=...` 4. **App reloads without white screen** ✓ This recovery mechanism triggered multiple times during our testing (you can see multiple crash/recovery cycles in the logs), and the app successfully recovered each time. ### Results With these changes, our app now successfully recovers from WebKit process terminations without showing the white screen. The app reloads to the last known good state instead of getting stuck. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: issues-unsubscr...@cordova.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: issues-unsubscr...@cordova.apache.org For additional commands, e-mail: issues-h...@cordova.apache.org