在 iOS 平台使用 WKWebView 通过file://协议加载本地 HTML 文件时,存储在localStorage中的数据会在 App 后台切换、进程重启后偶尔丢失;但相同代码在安卓 / 鸿蒙平台无此问题。
现在的文档
仅明确了「默认数据存储(defaultDataStore)可将网站数据持久化到磁盘,非持久化存储(nonPersistent)仅存内存」的基础规则;
未提及「file://协议内容即使使用默认持久化存储,也会被归为临时内存存储」这一关键场景限制;
仅在WKURLSchemeHandler关联说明中隐含「自定义 URL 协议可处理 WebKit 原生不支持的 URL 方案」,但未直接关联file://的存储问题。
我找不到如何处理这个问题的官方文档,仅仅有其他的博客说需要增加http/https加载就没有这个问题。
请提供给我官方文档或者官方回复 关于出现这种file:/加载html出现问题的处理办法
Explore the integration of web technologies within your app. Discuss building web-based apps, leveraging Safari functionalities, and integrating with web services.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
The application I'm currently working on uses WebKit. Based on the crash analytics, we have noticed that some of our users are experiencing an unusual behavior in the app's WebKit view with macOS 15.3.2. These errors are reported for this version of the OS. The error in the crash log is a SIGABRT error, but there is no relevant information available to address it. In some crash logs, we found this error: "NSInternalInconsistencyException: Returned WKWebView was not created with the given configuration" but there is not any particular way to address it. Is there a way to identify the cause of this error? Alternatively, has anyone encountered this issue and found a solution?
OS Version: macOS 15.3.2 (24D81)
Report Version: 104
Exception Type: EXC_CRASH (SIGABRT)
Crashed Thread: 0
Application Specific Information:
Returned WKWebView was not created with the given configuration.
Thread 0 Crashed:
0 CoreFoundation 0x303111e74 __exceptionPreprocess
1 libobjc.A.dylib 0x3027b6cd4 objc_exception_throw
2 CoreFoundation 0x303111d6c +[NSException raise:format:]
3 WebKit 0x34e85cb20 WebKit::UIDelegate::UIClient::createNewPage
4 WebKit 0x34e8a4a80 WebKit::SOAuthorizationCoordinator::tryAuthorize
5 WebKit 0x34e9f04f8 WebKit::WebPageProxy::createNewPage
6 WebKit 0x34ef994c8 WebKit::WebPageProxy::didReceiveSyncMessage
7 WebKit 0x34f0830cc IPC::MessageReceiverMap::dispatchSyncMessage
8 WebKit 0x34ea753b0 WebKit::WebProcessProxy::didReceiveSyncMessage
9 WebKit 0x34f07cfb4 IPC::Connection::dispatchSyncMessage
10 WebKit 0x34f07d3b0 IPC::Connection::dispatchMessage
11 WebKit 0x34f078c50 IPC::Connection::SyncMessageState::ConnectionAndIncomingMessage::dispatch
12 WebKit 0x34f07f4f4 ***::Detail::CallableWrapper<T>::call
13 JavaScriptCore 0x33f3520c0 ***::RunLoop::performWork
14 JavaScriptCore 0x33f352fe8 ***::RunLoop::performWork
15 CoreFoundation 0x30309f8a0 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
16 CoreFoundation 0x30309f834 __CFRunLoopDoSource0
17 CoreFoundation 0x30309f598 __CFRunLoopDoSources0
18 CoreFoundation 0x30309e134 __CFRunLoopRun
19 CoreFoundation 0x30309d730 CFRunLoopRunSpecific
20 HIToolbox 0x319aeb52c RunCurrentEventLoopInMode
21 HIToolbox 0x319af1344 ReceiveNextEventCommon
22 HIToolbox 0x319af1504 _BlockUntilNextEventMatchingListInModeWithFilter
23 AppKit 0x30a7cd844 _DPSNextEvent
24 AppKit 0x30b133c20 -[NSApplication(NSEventRouting) _nextEventMatchingEventMask:untilDate:inMode:dequeue:]
25 AppKit 0x30a7c0870 -[NSApplication run]
26 AppKit 0x30a797064 NSApplicationMain
27 <unknown> 0x182780274 <redacted>
Thread 0 name: t-main-ui Crashed:
0 CoreFoundation 0x303111e74 __exceptionPreprocess
1 libobjc.A.dylib 0x3027b6cd4 objc_exception_throw
2 CoreFoundation 0x303111d6c +[NSException raise:format:]
3 WebKit 0x34e85cb20 WebKit::UIDelegate::UIClient::createNewPage
4 WebKit 0x34e8a4a80 WebKit::SOAuthorizationCoordinator::tryAuthorize
5 WebKit 0x34e9f04f8 WebKit::WebPageProxy::createNewPage
6 WebKit 0x34ef994c8 WebKit::WebPageProxy::didReceiveSyncMessage
7 WebKit 0x34f0830cc IPC::MessageReceiverMap::dispatchSyncMessage
8 WebKit 0x34ea753b0 WebKit::WebProcessProxy::didReceiveSyncMessage
9 WebKit 0x34f07cfb4 IPC::Connection::dispatchSyncMessage
10 WebKit 0x34f07d3b0 IPC::Connection::dispatchMessage
11 WebKit 0x34f078c50 IPC::Connection::SyncMessageState::ConnectionAndIncomingMessage::dispatch
12 WebKit 0x34f07f4f4 ***::Detail::CallableWrapper<T>::call
Is it possible to open the native app from a web extension?
I have tried creating a new tab that uses the app's URL scheme but the UI asking the user to open the app is not shown until the new page UI is dismissed.
Creating a tab with an HTTPS URL that the app is setup to handle does not work and always the link in a new tab.
I tried sending a message to the app extension and using NSExtensionContext.open(_:completionHandler:) but the URL is not opened and the closure received false, indicating it was not handled.
Having the option to link back to the native app would be very useful.
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)
}
}
Currently I am struggling to find a way to read the status of Safari Web Extension from settings as I can not find any public api listed for iOS as it is already available for macOS.
Doc URL: https://developer.apple.com/documentation/applepayontheweb/requesting-an-apple-pay-payment-session
How can I send a POST request using PHP, and what certificates are required?
Currently, I have downloaded the following files on the backend: merchant_id.cer, apple_pay.cer, and a local cert.p12 file
This my code:
Safari is acting up. It’s appearing on my screen as a blank black screen, and then it’s retreating to the homepage.
Topic:
Safari & Web
SubTopic:
General
Animated AVIFs don't work properly on Safari, with inconsistent behavior across iPhone models.
On iPhone 14 Pro (A16, iOS 18.3.1), playback works fine, but on iPhone 15 (A16, iOS 18.3.1), it shows as a still image.
iPhone 16 Pro (A18, iOS 18.4 beta) plays correctly, and M1 Pro MacBook handles it well too.
Oddly, Xcode simulator (M1 Pro) only plays a specific file on iPhone 14 Pro. Is this tied to AV1 decoding differences (hardware vs. software) or a WebKit rendering issue? Any insights or documentation would help!
Note: The tested images are commercial files, so I can’t attach them here, but I’m happy to share those upon request.
Topic:
Safari & Web
SubTopic:
General
Hello,
Recently, there is an issue in my service that after typing korean at input element, first click event is not working.
But i knew that other services are also having same problem.
It happens only on Safari.
Could you guys check this issue?
Thank you.
TLDR: I’m searching for a possibility to allow the usage of passkeys and hardware keys for any website in a wkwebview
INFO: The browser is macOS ONLY
Hi, I couldn’t really find documentation or forums posts on how to implement Webauthn for signin or hardware security keys for a second factor. Or rather where those events are triggered to be handled. In Safari you have that popover, that lets you either authenticate through Passwords or with a security key.
When I visit webauthn.io for testing and click either register or authenticate I get
Told not to present authorization sheet: Error Domain=com.apple.AuthenticationServicesCore.AuthorizationError Code=1 "(null)"
ASAuthorizationController credential request failed with error: Error Domain=com.apple.AuthenticationServices.AuthorizationError Code=1004 "(null)"
If I add
func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping @MainActor (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
and
func webView(_ webView: WKWebView, authenticationChallenge challenge: URLAuthenticationChallenge, shouldAllowDeprecatedTLS decisionHandler: @escaping @MainActor (Bool) -> Void)
it doesn’t seem to change anything.
I found something about the ASWebAuthenticationSessionWebBrowserSupported entitlement, but by my understanding this is used so a browser can get opened upon some other app calling a ASWebAuthenticationSession.
Has anyone some guidance for me? I feel like webauthn and yubikey support are important security measures for our users.
https://codeberg.org/miakoring/Amethyst/src/branch/main/Amethyst/Shared/ViewComponents/WebKit/WebViewModel.swift
is the code for my webviewmodel.
Delegates are in the Delecate folder https://codeberg.org/miakoring/Amethyst/src/branch/main/Amethyst/Shared/ViewComponents/WebKit
Hello WebKit Team,
I’m writing to ask if iOS provides a native way to intercept AJAX (XMLHttpRequest or fetch) calls inside WKWebView.
On Android, this is handled via:
shouldInterceptRequest(WebView view, WebResourceRequest request)
but iOS currently seems to have no equivalent.
We’ve tried:
WKURLSchemeHandler → works only for custom schemes
URLProtocol with WKProcessPool → unreliable for AJAX in WebView
JavaScript injection → partial and unofficial
Could you please clarify:
Is there a recommended native approach to intercept AJAX requests?
If not supported, is it planned for future releases?
Any official workaround or guidance?
This is critical for debugging, analytics, and compliance in hybrid apps.
I'm looking for answer or documentation on gatekeeper and launching a MacOS app via a url scheme/custom protocol.
Our application is delivered via a zip file downloaded from the web. We utilize a url scheme. The act of extracting the app from the zip registers the url scheme with the OS.
From previous research/testing we found we had to break the gatekeeper lock (have the user move the app from the downloaded location) to ensure that the url is honored on first launch of the application. To ensure user compliance, we added a check to make sure that the lock has been removed by looking at the quarantine attribute.
This flow is not ideal. I am looking for alternatives and was previously under the impression that if we were to move to a DMG then that would provide the user a better user experience for moving it. However, now that I am getting
around to looking into it, I am seeing some implied statements that this is not the case and that the quarantine bit will just be moved from the DMG to the app.
Questions:
Does a DMG allow the app to be launched via custom protocol without prior launch or movement?
With a notarized app, will the custom protocol work on a subsequent launch, even without prior movement?
Topic:
Safari & Web
SubTopic:
General
Hello,
According to the documentation:
If you provide your extension in macOS and don’t want to use the Mac App Store for distribution, you can sign and notarize your extension’s app with a Developer ID to distribute it outside the Mac App Store.
However, I found this to be untrue in practice. Even after signing and notarising the Safari extension correctly, it is not possible to enable it in Safari without turning on "allow unsigned extension".
This makes it impossible to distribute your Developer ID–signed and notarized extension outside the Mac App Store.
I would like to distribute my web extension directly to employees in my organization using MDM without having each user manually enable "allow unsigned extension" for it to work. Any way to make it work?
The documentation is quite confusing in this aspect, it says "Safari only supports signed extensions" but my extension is rejected even if notarised and signed.
I have a simple Safari extension which contains only Javascript and no native code.
Currently I have the placeholder SafariWebExtensionHandler.swift that Xcode created when I added the extension. It's not doing anything useful, but simply deleting it doesn't seem to work.
Can I have an extension that includes no native code?
When creating a passkey with the PRF extension on an iPhone 15 Pro Max using Safari on iOS 18.4.1, PublicKeyCredential.getClientExtensionResults reports true; however there is no hmac-secret extension in the authenticator data as required by WebAuthn Level 3.
Hi all,
I'm currently working with WKWebView and implementing the WKNavigationDelegate protocol. In particular, I'm trying to inspect the sourceFrame of a WKNavigationAction to make navigation policy decisions based on the frame's URL path.
Here's the relevant Swift code inside decidePolicyFor:
public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, preferences: WKWebpagePreferences, decisionHandler: @escaping (WKNavigationActionPolicy, WKWebpagePreferences) -> Void) {
// ...
let sourceFrame: WKFrameInfo = navigationAction.sourceFrame
let request: URLRequest = sourceFrame.request // <- SIGABRT occurs here
// ...
}
The issue is that the app crashes with a SIGABRT at runtime when attempting to access sourceFrame.request. According to Swift's type system, neither sourceFrame nor its request property are optional, so at first glance this seems safe. However, the crash report suggests otherwise.
From the crash log, it appears that the issue arises during the bridging from Objective-C to Swift:
Thread 1 Queue : com.apple.main-thread (serial)
#0 0x00000001a127a030 in static Foundation.URLRequest._unconditionallyBridgeFromObjectiveC(Swift.Optional<__C.NSURLRequest>) -> Foundation.URLRequest ()
#1 0x00000001056c48b0 in CustomWebViewController.webView(_:decidePolicyFor:preferences:decisionHandler:)
#2 0x00000001056c4c78 in @objc CustomWebViewController.webView(_:decidePolicyFor:preferences:decisionHandler:) ()
#3 0x00000001b8c66e0c in WebKit::NavigationState::NavigationClient::decidePolicyForNavigationAction ()
#4 0x00000001b8fd14dc in WebKit::WebPageProxy::decidePolicyForNavigationAction ()
#5 0x00000001b8fcfc7c in WebKit::WebPageProxy::decidePolicyForNavigationActionAsyncShared ()
#6 0x00000001b8fcfb18 in WebKit::WebPageProxy::decidePolicyForNavigationActionAsync ()
#7 0x00000001b87ddaa0 in WebKit::WebPageProxy::didReceiveMessage ()
#8 0x00000001b869f474 in IPC::MessageReceiverMap::dispatchMessage ()
#9 0x00000001b878dda4 in WebKit::WebProcessProxy::dispatchMessage ()
#10 0x00000001b878d614 in WebKit::WebProcessProxy::didReceiveMessage ()
#11 0x00000001b869e7e4 in IPC::Connection::dispatchMessage ()
#12 0x00000001b869e358 in IPC::Connection::dispatchIncomingMessages ()
#13 0x00000001b9a96a44 in WTF::RunLoop::performWork ()
#14 0x00000001b9a96688 in WTF::RunLoop::performWork ()
#15 0x00000001a2428b9c in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ ()
#16 0x00000001a24289b4 in __CFRunLoopDoSource0 ()
#17 0x00000001a2428810 in __CFRunLoopDoSources0 ()
#18 0x00000001a2429190 in __CFRunLoopRun ()
#19 0x00000001a242ad4c in CFRunLoopRunSpecific ()
#20 0x00000001ef705454 in GSEventRunModal ()
#21 0x00000001a4e45890 in -[UIApplication _run] ()
#22 0x00000001a4e10cec in UIApplicationMain ()
#23 0x00000001a4ef261c in ___lldb_unnamed_symbol275689 ()
#24 0x00000001059a5104 in static UIApplicationDelegate.main() ()
#25 0x00000001059a5074 in static AppDelegate.$main() ()
#26 0x00000001059a82ec in main ()
#27 0x00000001c940af0c in start ()
This implies that while Swift treats sourceFrame.request as non-optional, the underlying Objective-C implementation may actually return nil—leading to a crash when the non-optional Swift type attempts to force unwrap it.
My question:
Is there a way to safely access navigationAction.sourceFrame.request —- or determine if it’s nil—before Swift attempts the implicit bridging from Objective-C? Or is there an established workaround for safely inspecting this property?
Any guidance or best practices for avoiding this crash would be greatly appreciated!
Thanks in advance.
Hello!
While working with the new Apple Pay SDK for iOS 18, I encountered a bug. When using the Ukrainian language, in the modal displaying the QR code, I noticed that there is a missing bracket for the year variable. This causes incorrect data to be displayed in the QR code.
This seems to be a localization issue specifically with the Ukrainian language in the new SDK, as the bug does not occur with other languages like English.
Has anyone else experienced this? Any advice or information on this bug would be appreciated.
Thanks!
Sometimes Safari is rendering the icon for an active extension in its original provided colored representation, other times Safari is applying an overlay color in line with the system's highlight color.
This difference can even be seen seen on the Safari Extensions Developer home page: https://developer.apple.com/safari/extensions/images/extensions-hero-large_2x.png
You will notice that Grammarly's icon is shown in it's original color format, while the others aren't.
Example of extensions where the icon is shown in color:
Bitwarden
Grammarly
1Password
Consent-O-Matic
I've compared the source code of Bitwarden and Consent-o-Matic with my own extension and cannot find any differences in the settings or image properties (resolution, DPI, file type, color profile). If I take the exact PNG source files from said open source extensions and replace them in my own source code, these icons show up in full color.
Does this perhaps mean there is a bug in Safari's processing of the icons where it fails to overlay the icon with the highlight color in some cases?
I and I assume many developers with me would like to understand what determines this difference. Ideally, there is a consistent UX where the end user has the choice between icons in color or highlight color overlay.
Our iOS app uses React Native Webview (based on top of WKWebView) to display content. This webview stays in memory throughtout the app's lifecycle. We are observing a high number of webview content process terminations - around 15% of our sessions. (https://developer.apple.com/documentation/webkit/wknavigationdelegate/webviewwebcontentprocessdidterminate(_:))
What could be the reasons for it? Is there a way to know for sure?
Is the 15% of sessions number something that other apps also experience, or should this be lower?
Thanks!
Topic:
Safari & Web
SubTopic:
General
Hello - we have a Mac application that uses a browser extension and the web extension JS APIs to communicate with Safari. As of macOS 15.4 / Safari 18.4 the tab OnAttached and tab onDetached events are no longer received.
After some testing we verified that the events were working properly as of macOS 15.3 / Safari 18.3 but appear to have been broken in macOS 15.4. Note a similar issue was reported previously for Safari 17.6 and was fixed in macOS 15.0 (FB14324177).
We have made a TestFlight version of our app (Tabby) available to simplify debugging via https://testflight.apple.com/join/Va8Zdv9d.
To reproduce the issue:
Install the Tabby TestFlight build on macOS 15.4 or 15.4.1
Open Safari, go to Safari settings and select the Extensions tab
Enable the Tabby extension and grant permissions to all windows all the time
Open a Safari window with at least 3 tabs
Note the open window and tabs displayed in Tabby
In Safari, perform a tab detach by dragging a tab out of the window
Expected behavior
Within Safari the detached tab should now be in it’s own window, and via the onDetached event Tabby should update to show the tab in it’s own window AND removed from the original window.
Observed
Safari fails to send the onDetached event and Tabby will continue to display the detached tab in its original window in addition to the new window.
You can also use the repro steps above to observe the onDetached event being received or not by Tabby in the Safari developer console. The same steps but re-attaching the tab to the original window can be used to observe the onAttached event being received or not.
We’ve attached two screen recordings to the Feedback ID below, one showing the events working on macOS 15.3, and one showing the events failing to be received on macOS 15.4.1. Note it also fails on macOS 15.4.
FEEDBACK ID: FB17367977