Problem
Currently, iOS PlatformWebViewParams is an empty class with no properties, making it impossible for developers to provide a custom WKUIDelegate implementation. This means JavaScript alert(), confirm(), and prompt() calls are silently ignored on iOS.
Android allows customization through PlatformWebViewParams:
// webview/src/androidMain/.../WebView.android.kt
actual data class PlatformWebViewParams(
val chromeClient: AccompanistWebChromeClient? = null,
)
iOS has no such capability:
// webview/src/iosMain/.../WebView.ios.kt
actual class PlatformWebViewParams // Empty class - no properties!
Additionally, IOSWebView composable doesn't use platformWebViewParams at all, and WKUIDelegate is never set on the WKWebView.
Why This Happens
The key difference between platforms:
- Android - WebChromeClient.onJsAlert() not overridden → System dialog shown automatically
- iOS - WKUIDelegate not set → Silently ignored (no response)
Android's WebChromeClient has built-in default implementations that show system dialogs. iOS's WKWebView has no default behavior - if WKUIDelegate is not set, JavaScript dialogs simply don't work.
Impact
On iOS, when a webpage calls:
alert("message") → Silently ignored
confirm("question") → Returns false immediately
prompt("input") → Returns null immediately
window.open() → Blocked
This creates a significant platform inconsistency between Android and iOS, breaking hybrid apps that rely on JavaScript dialogs.
Proposed Solution
Add uiDelegate property to iOS PlatformWebViewParams:
actual data class PlatformWebViewParams(
val uiDelegate: WKUIDelegateProtocol? = null,
)
Apply the delegate in IOSWebView:
platformWebViewParams?.uiDelegate?.let {
this.setUIDelegate(it)
}
Provide a default AccompanistUIDelegate implementation (similar to AccompanistWebChromeClient) that shows native iOS alerts:
class AccompanistUIDelegate : NSObject(), WKUIDelegateProtocol {
override fun webView(
webView: WKWebView,
runJavaScriptAlertPanelWithMessage: String,
initiatedByFrame: WKFrameInfo,
completionHandler: () -> Unit,
) {
// Show native iOS alert
}
override fun webView(
webView: WKWebView,
runJavaScriptConfirmPanelWithMessage: String,
initiatedByFrame: WKFrameInfo,
completionHandler: (Boolean) -> Unit,
) {
// Show native iOS confirm dialog
}
override fun webView(
webView: WKWebView,
runJavaScriptTextInputPanelWithPrompt: String,
defaultText: String?,
initiatedByFrame: WKFrameInfo,
completionHandler: (String?) -> Unit,
) {
// Show native iOS prompt dialog
}
}
Environment
Library version: latest (main branch)
Kotlin: 2.1.20
Compose Multiplatform: 1.8.0
Usage Example
// iosMain
@Composable
actual fun getPlatformWebViewParams(): PlatformWebViewParams? {
val uiDelegate = remember { AccompanistUIDelegate() }
return PlatformWebViewParams(uiDelegate = uiDelegate)
}
Question
Is there an alternative approach to handle JavaScript alert(), confirm(), and prompt() on iOS within this library that I might have missed? If not, would a PR implementing the proposed solution above be welcome?
Problem
Currently, iOS PlatformWebViewParams is an empty class with no properties, making it impossible for developers to provide a custom WKUIDelegate implementation. This means JavaScript alert(), confirm(), and prompt() calls are silently ignored on iOS.
Android allows customization through PlatformWebViewParams:
iOS has no such capability:
// webview/src/iosMain/.../WebView.ios.kt
Additionally, IOSWebView composable doesn't use platformWebViewParams at all, and WKUIDelegate is never set on the WKWebView.
Why This Happens
The key difference between platforms:
Android's WebChromeClient has built-in default implementations that show system dialogs. iOS's WKWebView has no default behavior - if WKUIDelegate is not set, JavaScript dialogs simply don't work.
Impact
On iOS, when a webpage calls:
alert("message")→ Silently ignoredconfirm("question")→ Returns false immediatelyprompt("input")→ Returns null immediatelywindow.open()→ BlockedThis creates a significant platform inconsistency between Android and iOS, breaking hybrid apps that rely on JavaScript dialogs.
Proposed Solution
Add uiDelegate property to iOS PlatformWebViewParams:
Apply the delegate in IOSWebView:
Provide a default AccompanistUIDelegate implementation (similar to AccompanistWebChromeClient) that shows native iOS alerts:
Environment
Library version: latest (main branch)
Kotlin: 2.1.20
Compose Multiplatform: 1.8.0
Usage Example
// iosMain
Question
Is there an alternative approach to handle JavaScript alert(), confirm(), and prompt() on iOS within this library that I might have missed? If not, would a PR implementing the proposed solution above be welcome?