I’m currently developing an application using WKWebView.
After updating to iOS 26.2 Developer Beta, the following Web API started returning false:
isUserVerifyingPlatformAuthenticatorAvailable
MDN: https://developer.mozilla.org/ja/docs/Web/API/PublicKeyCredential/isUserVerifyingPlatformAuthenticatorAvailable_static
This issue did not occur on iOS 26.1 — it only happens on the beta version.
Has anyone else encountered this problem or is aware of any related changes?
OS: iOS 26.2 beta 3 (23C5044b)
WebKit
RSS for tagDisplay web content in windows and implement browser features using WebKit.
Posts under WebKit tag
200 Posts
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Create shortcut to open chrome with url and put it on the desktop.
Tap the shortcut.
Tap the username text field.
When launching Safari from an iOS shortcut on an iOS device with a valid passkey registered, the passkey suggestion does not appear; instead, the password suggestion appears sometimes.
Topic:
Safari & Web
SubTopic:
General
Tags:
WebKit
Safari
Safari and Web
Passkeys in iCloud Keychain
Hi everyone,
I want users not to see the system context menu when long-pressing text on a page in Safari on iOS. I found on MDN that the CSS property -webkit-touch-callout: none; can achieve this. But in reality, it doesn't really work.
MDN documents URL: https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/-webkit-touch-callout
Here’s a minimal example:
function preventIOSSafariContextMenu() {
if (document.getElementById(STYLE_ELEMENT_ID)) return;
if (!IS_TOUCH_DEVICE) return;
const style = document.createElement("style");
style.id = STYLE_ELEMENT_ID;
style.textContent = `
html, body {
-webkit-touch-callout: none !important;
}
`;
(document.head || document.documentElement).appendChild(style);
}
The context menu persists.
Has anyone else encountered this? Is this an intentional change in WebKit, or could it be a regression? If it’s intentional, is there a recommended alternative?
Thanks in advance for any insights!
I am using WebView and WebPage to display web pages. Some web pages have content fixed to the top of the screen (like apple.com). When this happens, content is under the status bar (like menu buttons), and I cannot tap them.
My work around is to put the WebView in a VStack with the top being Color.clear.frame(height: 44). It isn't very elegant, especially since it is applied to all pages and not just pages with fixed content at the top.
Is there a more Apple-y way to solve this?
For example, Safari seems to detect these situations and puts something like Color.clear.frame(height: 44) in those cases but not other cases.
Here is sample code:
import SwiftUI
import WebKit
struct ContentView: View {
@State private var page: WebPage
init() {
let configuration = WebPage.Configuration()
page = WebPage(configuration: configuration)
let url = URL(string: "https://www.apple.com")!
let request = URLRequest(url: url)
page.load(request)
}
var body: some View {
WebView(page)
}
}
Here is a screenshot of Apple's page in WebView with the menu
Here is a screenshot of Apple's page in Safari. It appears to have inserted a spacer frame at the top for Apple's page (but not, for example, my own web site which doesn't have this problem).
Reproducibility
100% on iOS 15.4 and iOS 16.6
Zero crash on iOS 18.6
Xcode
26.1
Steps to Reproduce
Xcode 26.1 → New iOS App
Replace ViewController.swift with the 20-line code below
Run on real device
• iPhone XR iOS 15.4
• iPhone 13 iOS 16.6
Tap the link → breakpoint in decidePolicyFor
lldb → po navigationAction.sourceFrame
Actual Result
(lldb) po navigationAction.sourceFrame
nil
Swift declaration lies:
public var sourceFrame: WKFrameInfo { get } // non-optional
→ Instant EXC_BREAKPOINT
libswiftFoundation.dylib`URLRequest._unconditionallyBridgeFromObjectiveC
Objective-C tells the truth:
po [(WKNavigationAction *)navigationAction fixedSourceFrame]
nil
iOS 18.6 → same code prints a valid WKFrameInfo, no crash.
Expected
sourceFrame must be declared WKFrameInfo? in Swift
or at least documented “can be nil on iOS 15–16”.
Impact
Every WKWebView app that touches sourceFrame on iOS 15.4 & 16.6 ships with a latent crash.
Production Workaround
@implementation WKNavigationAction (Safe)
(WKFrameInfo *)fixedSourceFrame {
return self.sourceFrame ? self.sourceFrame : nil;
}
@end
Minimal Test (copy-paste)
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
lazy var web = WKWebView(frame: view.bounds)
override func viewDidLoad() {
super.viewDidLoad()
web.navigationDelegate = self
view.addSubview(web)
web.load(URLRequest(url: URL(string: "https://www.apple.com")!))
}
func webView(_ webView: WKWebView,
decidePolicyFor navigationAction: WKNavigationAction,
preferences: WKWebpagePreferences,
decisionHandler: @escaping (WKNavigationActionPolicy, WKWebpagePreferences)->Void) {
print(navigationAction.sourceFrame) // ← crashes on 15.4 & 16.6
decisionHandler(.allow, preferences)
}
}
I'm building a progressive web app (PWA) and came to the conclusion that almost nobody knows that this feature exists - Add to Home Screen. Not many people even understand what a PWA is or that you can add it to the home screen. This feels unnatural compared to installing an app from a store. Why do we make it so hard for users? Could we not make this easier by having the ability to call this installation or show an install notification?
Right now, when users visit a PWA on iOS, there's no way for developers to let them know they can install it. The "Add to Home Screen" option is tucked away in the Share menu, and most users never find it. I'd really like to be able to show them a friendly prompt.
Comparing to other browsers, this is possible via the beforeinstallprompt event. This would make a huge difference for user experience. Right now the only way is to show iOS users a separate set of instructions with screenshots, which feels clunky compared to what's possible on other platforms.
I'm curious - is there any reason why this hasn't been added to Safari yet? Other browsers have supported this for years now. Is there any progress being made on this, or is it being considered for the roadmap? It would be really helpful to know if this is something that will be worked on in the future.
I know there's a lot on the roadmap, but this would really help developers create better installation experiences for our users.
Thanks for considering this!
Such a simple piece of code:
import SwiftUI
import WebKit
struct ContentView: View {
var body: some View {
WebView(url: URL(string: "https://www.apple.com"))
}
}
When I run this, the web content shows under the top notch’s safe area, and buttons inside that region aren’t tappable. I tried a bunch of things and the only “fix” that seems to work is .padding(.top, 1), but that leaves a noticeable white strip in non-portrait orientations.
What’s the proper way to solve this? Safari handles the safe area correctly and doesn’t render content there.
Crash in UIKeyboardStateManager when repeatedly switching text input focus in WKWebView (hybrid app)
We’re building a hybrid iOS app using Angular (web) rendered inside a WKWebView, hosted by a native Swift app.
Recently, we encountered a crash related to UIKeyboardStateManager in UIKit when switching between text inputs continuously within an Angular screen.
Scenario
The screen contains several text input fields.
A “Next” button focuses the next input field programmatically.
After about 61 continuous input field changes, the app crashes.
It seems like this may be related to UIKit’s internal keyboard management while switching focus rapidly inside a WebView.
crash stack:
Crashed: com.apple.main-thread
0 WebKit 0xfbdad0 <redacted> + 236
1 UIKitCore 0x10b0548 -[UITextInteractionSelectableInputDelegate _moveToStartOfLine:withHistory:] + 96
2 UIKitCore 0xd0fb38 -[UIKBInputDelegateManager _moveToStartOfLine:withHistory:] + 188
3 UIKitCore 0xa16174 __158-[_UIKeyboardStateManager handleMoveCursorToStartOfLine:beforePublicKeyCommands:testOnly:savedHistory:force:canHandleSelectableInputDelegateCommand:keyEvent:]_block_invoke + 52
4 UIKitCore 0xa36ae4 -[_UIKeyboardStateManager performBlockWithTextInputChangesIgnoredForNonMacOS:] + 48
5 UIKitCore 0xa160f0 -[_UIKeyboardStateManager handleMoveCursorToStartOfLine:beforePublicKeyCommands:testOnly:savedHistory:force:canHandleSelectableInputDelegateCommand:keyEvent:] + 440
6 UIKitCore 0xa07010 -[_UIKeyboardStateManager handleKeyCommand:repeatOkay:options:] + 5760
7 UIKitCore 0xa2fb64 -[_UIKeyboardStateManager _handleKeyCommandCommon:options:] + 76
8 UIKitCore 0xa2fb08 -[_UIKeyboardStateManager _handleKeyCommand:] + 20
9 UIKitCore 0xa30684 -[_UIKeyboardStateManager handleKeyEvent:executionContext:] + 2464
10 UIKitCore 0xa2f95c __42-[_UIKeyboardStateManager handleKeyEvent:]_block_invoke + 40
11 UIKitCore 0x4b9460 -[UIKeyboardTaskEntry execute:] + 208
12 UIKitCore 0x4b92f4 -[UIKeyboardTaskQueue continueExecutionOnMainThread] + 356
13 UIKitCore 0x4b8be0 -[UIKeyboardTaskQueue addTask:breadcrumb:] + 120
14 UIKitCore 0x4a9ed0 -[_UIKeyboardStateManager _setupDelegate:delegateSame:hardwareKeyboardStateChanged:endingInputSessionIdentifier:force:delayEndInputSession:] + 3388
15 UIKitCore 0xfa290 -[_UIKeyboardStateManager setDelegate:force:delayEndInputSession:] + 628
16 UIKitCore 0xf617c -[UIKeyboardSceneDelegate _reloadInputViewsForKeyWindowSceneResponder:force:fromBecomeFirstResponder:] + 1140
17 UIKitCore 0xf5c88 -[UIKeyboardSceneDelegate _reloadInputViewsForResponder:force:fromBecomeFirstResponder:] + 88
18 UIKitCore 0x4fe4ac -[UIResponder(UIResponderInputViewAdditions) reloadInputViews] + 84
19 WebKit 0xfbe708 <redacted> + 100
20 WebKit 0xfbf594 <redacted> + 340
21 WebKit 0x8a33d8 <redacted> + 32
22 WebKit 0x8cee04 <redacted> + 144
23 WebKit 0x1c83f0 <redacted> + 22692
24 WebKit 0x73f40 <redacted> + 264
25 WebKit 0x162c7c <redacted> + 40
26 WebKit 0x1623b4 <redacted> + 1608
27 WebKit 0x73298 <redacted> + 268
28 WebKit 0x72e48 <redacted> + 660
29 JavaScriptCore 0xdb00 WTF::RunLoop::performWork() + 524
30 JavaScriptCore 0xd744 WTF::RunLoop::performWork(void*) + 36
31 CoreFoundation 0xf92c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 28
32 CoreFoundation 0xf744 __CFRunLoopDoSource0 + 172
33 CoreFoundation 0xf5a0 __CFRunLoopDoSources0 + 232
34 CoreFoundation 0xff20 __CFRunLoopRun + 840
35 CoreFoundation 0x11adc CFRunLoopRunSpecific + 572
36 GraphicsServices 0x1454 GSEventRunModal + 168
37 UIKitCore 0x135274 -[UIApplication _run] + 816
38 UIKitCore 0x100a28 UIApplicationMain + 336
39 APP1 0xa2ed0 main + 21 (AppDelegate.swift:21)
40 ??? 0x1aa889f08 (シンボルが不足しています)
From reviewing the crash log, it appears that the crash occurs inside UIKeyboardStateManager while handling keyboard or cursor updates.
Questions
Has anyone seen this specific crash pattern involving UIKeyboardStateManager?
Are there known UIKit or WebKit bugs related to UIKeyboardStateManager when continuously changing focus between text fields (especially in WKWebView)?
Any insights or workarounds would be greatly appreciated.
Thanks!
Hello
We've encountered an issue with WKWebView in the latest iOS 26 beta. When loading a PDF URL, the background of the PDF viewer now displays as a dark gray instead of the expected white.
Device: iOS 26 Simulator/Device
Component: WKWebView
Issue: The background color of the loaded PDF is gray.
Expected Behavior: The background should be white, as it has been in all previous iOS versions.
Link for Testing: https://help.apple.com/pdf/security/en_US/apple-platform-security-guide.pdf
We confirmed that the same PDF and code render with a white background on iOS 26 and earlier.
Questions:
Is this an intentional change in iOS 26's WKWebView?
If so, is there a new property or configuration setting available to control the background color of the PDF viewer within WKWebView? We would like to have the ability to set it back to white.
Any insights, workarounds, or information on this matter would be greatly appreciated.
Thank you.
I'm being faced with an issue when using SwiftUI's WebView on iOS 26. In many websites, the top/bottom content is unaccessible due to being under the app's toolbars. It feels like the WebView doesn't really understand the safe areas where it's being shown, because the content should start right below the navigation bar, and only when the user scrolls down, the content should move under the bar (but it's always reachable if the users scroll back up).
Here's a demo of the issue:
Here's a 'fix' by ensuring that the content of the WebView never leaves its bounds. But as you can see, it feels out of place on iOS 26 (would be fine on previous OS versions if you had a fully opaque toolbar):
Code:
struct ContentView: View {
var body: some View {
NavigationStack {
WebView(url: URL(string: "https://apple.com")).toolbar {
ToolbarItem(placement: .primaryAction) {
Button("Top content covered, unaccessible.") {}
}
}
}
}
}
Does anyone know if there's a way to fix it using some sort of view modifier combination or it's just broken as-is?
We have a SAML-based SSO App Extension that uses WKWebView to load the SAML login request. This implementation has been working correctly on iOS versions prior to 26. However, starting with iOS 26, the extension consistently crashes when calling WKWebView.load(_:).
The crash occurs inside WebKit, specifically in:
/Library/Caches/com.apple.xbs/Sources/WebKit/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp
at
WebKit::WebPageProxy::loadRequest(...)
No app-level exception is thrown, and the extension terminates with:
Thread 10: EXC_BREAKPOINT (code=1, subcode=0x1a31dbe00)
It appears that WKWebView initialization or WebsiteDataStore creation is now restricted in extension contexts on iOS 26, but this change is not documented in the SDK release notes. Could you please confirm if this is an intentional sandbox restriction in iOS 26 or a regression in WebKit?
Steps to reproduce:
Implement an App Extension using ASAuthorizationProviderExtensionAuthorizationRequest.
Create a WKWebView instance in the extension.
Attempt to load a SAML login request (POST request with headers).
Observe immediate crash on iOS 26 (works fine on earlier versions).
Expected behavior:
WKWebView should load the request or fail gracefully as in prior releases, without crashing the extension process.
Request:
Please clarify if WKWebView usage inside extensions is officially unsupported as of iOS 26, and if so, recommend an alternative approach for handling SSO flows.
We use an embedded WKWebView for several screens in our app.
Recently, we have been testing keyboard navigation via Full Keyboard Access in our apps. On IOS 18, everything works pretty much as expected. On IOS 26, it does not.
On IOS 26, you can "tab" away from the webview and then never tab back to the webview for keyboard navigation.
Is this a known issue? Are there workarounds for this issue that anyone is aware of?
As the title suggests, given today’s overpowered device performance, shouldn’t Safari and WKWebView allow repainting during window resizing? Currently, all WKWebView-based apps pause page rendering during resize. When a user double-clicks the drag region, the sequence goes: pause rendering → enlarge or shrink the window → leave a blank area → repaint the page. The whole process feels inelegant—especially on devices that support ProMotion.
YouTube now requires a Referer to be sent to be able to embed Youtube videos, otherwise the videos won't work. But WKWebView doesn't send a Referer when using a custom scheme, so Youtube videos stopped working in that case.
This affects Ionic apps, both using Cordova or Capacitor. There's an open issue for Cordova and another one for Capacitor. In these apps, the app is served using a custom scheme like capacitor://localhost or ionic://localhost.
I tried modifying the Ionic WebView source code to force adding a referrer to the URL loaded using WKWebView's loadRequest:
[request addValue:@"https://my.test.app" forHTTPHeaderField:@"Referer"];
[_engineWebView loadRequest:request]
But the Referer is still not sent in the Requests, I guess because the app is using a custom scheme (e.g. capacitor://localhost). However, if I modify this code to force loading an "online URL" (using https) instead of capacitor://localhost, then the my.test.app Referer is sent to the requests.
Is there any way to make WKWebView send a Referer when using a custom scheme?
Since Xcode 26 our tests are crashing due to the Main Thread not being able to deallocate WKNavigationResponse.
Following an example:
import Foundation
import WebKit
final class WKNavigationResponeMock: WKNavigationResponse {
private let urlResponse: URLResponse
override var response: URLResponse { urlResponse }
init(urlResponse: URLResponse) {
self.urlResponse = urlResponse
super.init()
}
convenience init(httpUrlResponse: HTTPURLResponse) {
self.init(urlResponse: httpUrlResponse)
}
convenience init?(url: URL, statusCode: Int) {
guard let httpURLResponse = HTTPURLResponse(url: url, statusCode: statusCode, httpVersion: nil, headerFields: nil) else {
return nil
}
self.init(httpUrlResponse: httpURLResponse)
}
}
import WebKit
import XCTest
final class ExampleTests: XCTestCase {
@MainActor func testAllocAndDeallocWKNavigationResponse() {
let expectedURL = URL(string: "https://galaxus.ch/")!
let expectedStatusCode = 404
let instance = WKNavigationResponeMock()
// here it should dealloc/deinit `instance` automatically
}
Here the call stack:
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 CoreFoundation 0x101f3dd54 CFRetain.cold.1 + 16
1 CoreFoundation 0x101e14860 CFRetain + 104
2 WebKit 0x10864dd24 -[WKNavigationResponse dealloc] + 52
Hello Apple Team,
I love the existing keyboard shortcuts such as Control + Function + Left/Right Arrow which allow moving windows to the left or right half of the screen. It significantly improves window management and productivity.
I would like to kindly request a similar feature to move windows across multiple monitors using a keyboard shortcut. This would be especially helpful for users with multi-monitor setups who want quick and seamless window transitions between displays without using the mouse.
This enhancement could align with Apple's commitment to intuitive and efficient user experience, helping users manage their workspace more effectively.
Thank you for considering this feature request!
I have a visionOS app using Apple's WebView and WebPage to display web content. When viewing a live YouTube stream last night, YouTube put up the warning in the area that would have the chat window:
Oh no!
It looks like you're using an older version of your browser. Please update it to use live chat.
Anyone know if YouTube is generating this from the server based on the WebPage's user agent string, from Javascript running in the browser engine, or something else?
Anyone know if and how it is possible to resolve this?
(See right side of YouTube web page from a screen grab):
I'm hoping that others may be able to assist with my first app submission.
**Guideline 2.1 - Performance - App Completeness
Issue Description**
The app still exhibited one or more bugs that would negatively impact App Store users.
Bug description: The app did not load its content.
Review device details:
Device type: iPad Air (5th generation)
OS version: iPadOS 18.3.1
The app pulls in a website embedded to allow them to login to their accounts/place orders. I've tested it on multiple physical devices and using the simulator. It works fine and loads without any issues. The review team would not give me any other information or support to help get this app approved. Any help would be appreciated.
Hi, it seems that with iOS26 the system displays two entries in the screentime report for apps that use a WKWebView: one for the app itself and one for the website that was displayed in the app. We don't see this behaviour in iOS18.7.
I'm reseaching how to disable the recording for the webviews in one of our apps (written in Swift with UIKit).
The STWebpageController looked promising, especially the field suppressUsageRecording, but the whole class is poorly documented.
We initialized it with the bundle identifier of the app and set the url of the wkwebview as the url in STWebpageController. It looks a bit like this:
webView = WKWebView(frame: .zero, configuration: config)
view.addSubview(webView)
//setup STWebpageController
webpageController = STWebpageController()
do {
try webpageController!.setBundleIdentifier(bundleIdentifier)
} catch{
}
webpageController!.suppressUsageRecording = true
addChild(webpageController!)
view.addSubview(webpageController!.view)
webpageController!.view.frame = view.frame
webpageController!.didMove(toParent: self)
//load url in webView
let request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData)
webview.load(request)
webpageController?.url = request.url
This has no effect on the recorded screentime for the webview inside our app - we still see the same time for the container app and the included webview.
Any suggestions?
Thanks,
Heiko
I'm working on a regular website, in which I'm trying to debug using the (MacOS) Safari Development tools. Since updating my Simulator to iOS 16.4, console.log is no longer displayed in the Console. Even when executing it directly in the console (console.log('test');), it's not printed.
Now, I've read that this is a feature for debugging in-app browser content (https://webkit.org/blog/13936/enabling-the-inspection-of-web-content-in-apps/) but can't find the regular web workaround here.
TL;DR: No longer see console.log in iOS 16.4 Safari when debugging from my Mac.
Thanks in advance for your suggestions!