This is an automated email from the ASF dual-hosted git repository.

GitToTheHub pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cordova-ios.git


The following commit(s) were added to refs/heads/master by this push:
     new ba8b9ecb fix(wkwebview): retain UIDelegate to restore 
alert/confirm/prompt (#1686)
ba8b9ecb is described below

commit ba8b9ecb00b62349c5d7be3a83c349292fbcc717
Author: Manuel Beck <[email protected]>
AuthorDate: Fri Aug 7 11:45:43 2026 +0200

    fix(wkwebview): retain UIDelegate to restore alert/confirm/prompt (#1686)
    
    - Fixes a regression introduced by #1664 where the property `uiDelegate` 
was removed from `CDVWebViewEngine`.
    - `WKWebView.UIDelegate` is weak, so the default `CDVWebViewUIDelegate` 
could be deallocated after assignment, which breaks JavaScript 
alert/confirm/prompt handling. Retain the delegate in `CDVWebViewEngine` by a 
strong property `uiDelegate` and clear it during dispose.
    - Add a regression test that verifies the web view engine keeps a non-nil 
uiDelegate.
    - Fixes #1684
    
    * fix: document `uiDelegate`, assign it in `updateWithInfo:`
    
    - The property is not only for retaining the UIDelegate, it's also part of 
the exposed CDVWebViewEngine API as readonly, so callers can inspect what 
delegate is currently installed. It is also set through `updateWithInfo:`, 
which a plugin can call and which is documented in `guides/Setting Delegates, 
Preferences and Script Message Handlers in the WebView.md`
    
    * doc: document `uiDelegate` only in header file
    
    Generated-By: GPT-5.3-Codex
---
 .../Private/Plugins/CDVWebViewEngine/CDVWebViewEngine.h   |  4 ++++
 .../Private/Plugins/CDVWebViewEngine/CDVWebViewEngine.m   | 15 ++++++++++++---
 tests/CordovaLibTests/CDVWebViewEngineTests.swift         | 11 +++++++++++
 3 files changed, 27 insertions(+), 3 deletions(-)

diff --git 
a/CordovaLib/Classes/Private/Plugins/CDVWebViewEngine/CDVWebViewEngine.h 
b/CordovaLib/Classes/Private/Plugins/CDVWebViewEngine/CDVWebViewEngine.h
index 95343b82..84b8ce93 100644
--- a/CordovaLib/Classes/Private/Plugins/CDVWebViewEngine/CDVWebViewEngine.h
+++ b/CordovaLib/Classes/Private/Plugins/CDVWebViewEngine/CDVWebViewEngine.h
@@ -22,6 +22,10 @@
 
 @interface CDVWebViewEngine : CDVPlugin <CDVWebViewEngineProtocol, 
WKScriptMessageHandler, WKNavigationDelegate>
 
+// WKUIDelegate reference for this engine, which can also be set via 
`updateWithInfo:`
+// by a plugin. Additionally it is a helper property to retain the UIDelegate, 
since
+// WKWebView.UIDelegate is weak and would otherwise be deallocated after 
assignment
+// which would cause JavaScript alert/confirm/prompt handling to stop working.
 @property (nonatomic, strong, readonly) id <WKUIDelegate> uiDelegate;
 
 - (void)allowsBackForwardNavigationGestures:(CDVInvokedUrlCommand*)command;
diff --git 
a/CordovaLib/Classes/Private/Plugins/CDVWebViewEngine/CDVWebViewEngine.m 
b/CordovaLib/Classes/Private/Plugins/CDVWebViewEngine/CDVWebViewEngine.m
index 250f2a9b..97f22d2e 100644
--- a/CordovaLib/Classes/Private/Plugins/CDVWebViewEngine/CDVWebViewEngine.m
+++ b/CordovaLib/Classes/Private/Plugins/CDVWebViewEngine/CDVWebViewEngine.m
@@ -43,6 +43,7 @@
 @property (nonatomic, readwrite) NSString *CDV_ASSETS_URL;
 @property (nonatomic, readwrite) Boolean cdvIsFileScheme;
 @property (nullable, nonatomic, strong, readwrite) WKWebViewConfiguration 
*configuration;
+@property (nonatomic, strong, readwrite) id <WKUIDelegate> uiDelegate;
 
 @end
 
@@ -270,7 +271,8 @@
     // CDVWebViewUIDelegate instance. This gives library consumers a way to
     // override the UI delegate and customize behaviour if needed.
     if ([self.viewController conformsToProtocol:@protocol(WKUIDelegate)]) {
-        wkWebView.UIDelegate = (id<WKUIDelegate>)self.viewController;
+        self.uiDelegate = (id<WKUIDelegate>)self.viewController;
+        wkWebView.UIDelegate = self.uiDelegate;
     } else {
         CDVWebViewUIDelegate *uiDelegate = [[CDVWebViewUIDelegate alloc] 
initWithViewController:self.viewController];
 
@@ -278,7 +280,11 @@
         uiDelegate.mediaPermissionGrantType = [self 
parsePermissionGrantType:[settings 
cordovaSettingForKey:@"MediaPermissionGrantType"]];
         uiDelegate.allowNewWindows = [settings 
cordovaBoolSettingForKey:@"AllowNewWindows" defaultValue:NO];
 
-        wkWebView.UIDelegate = uiDelegate;
+        // Assigning to self.uiDelegate keeps a strong reference to the 
delegate,
+        // since WKWebView.UIDelegate is weak and would cause the delegate to 
be
+        // deallocated
+        self.uiDelegate = uiDelegate;
+        wkWebView.UIDelegate = self.uiDelegate;
     }
 
     if ([self.viewController 
conformsToProtocol:@protocol(WKNavigationDelegate)]) {
@@ -301,6 +307,7 @@
 {
     WKWebView* wkWebView = (WKWebView*)_engineWebView;
     [wkWebView.configuration.userContentController 
removeScriptMessageHandlerForName:CDV_BRIDGE_NAME];
+    self.uiDelegate = nil;
     _engineWebView = nil;
 
     [super dispose];
@@ -427,7 +434,9 @@
     }
 
     if (uiDelegate && [uiDelegate conformsToProtocol:@protocol(WKUIDelegate)]) 
{
-        wkWebView.UIDelegate = uiDelegate;
+        // Keep a strong reference to the delegate, since WKWebView.UIDelegate 
is weak
+        self.uiDelegate = uiDelegate;
+        wkWebView.UIDelegate = self.uiDelegate;
     }
 
     if (settings && [settings isKindOfClass:[CDVSettingsDictionary class]]) {
diff --git a/tests/CordovaLibTests/CDVWebViewEngineTests.swift 
b/tests/CordovaLibTests/CDVWebViewEngineTests.swift
index 929acdaf..4a75c28d 100644
--- a/tests/CordovaLibTests/CDVWebViewEngineTests.swift
+++ b/tests/CordovaLibTests/CDVWebViewEngineTests.swift
@@ -38,6 +38,17 @@ class ScriptHandlingViewController: ViewController, 
WKScriptMessageHandler {
 }
 
 class CDVWebViewEngineTests: XCTestCase {
+    @MainActor func testWebViewUIDelegateIsRetained() {
+        let vc = ViewController()
+        vc.webContentFolderName = "www"
+        vc.startPage = "index.html"
+
+        vc.loadViewIfNeeded()
+
+        let uiDelegate = (vc.webViewEngine as AnyObject).value(forKey: 
"uiDelegate")
+        XCTAssertNotNil(uiDelegate)
+    }
+
     @MainActor func testViewControllerScriptMessageHandler() {
         let vc = ScriptHandlingViewController()
         vc.webContentFolderName = "www"


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to