I am encountering an intermittent issue with WKWebView in my iOS app. The problem occurs infrequently, but when it does, the WKWebView consistently displays a white screen and remains in this state until the app is forcefully terminated and relaunched.
To provide more context, here are the key characteristics of the issue:
The white screen problem occurs sporadically and is not easily reproducible.
The WKWebView remains unresponsive despite attempts to interact with it.
Reloading the webpage or navigating to a different URL does not resolve the white screen issue.
The problem persists until the app is terminated and relaunched.
This issue is specific to the WKWebView; other components of the app function correctly.
The WKWebView renders normally, and the main document synchronously loads resources both offline and online without any issues. The bridge and JavaScript execution also work as expected.
However, when interacting with the WKWebView, it becomes unresponsive to user clicks, and the web inspector fails to respond. Additionally, asynchronous network requests also do not receive any response.
The problem occurs exclusively on HTTPS pages, whereas HTTP pages load without any issues. Other components, such as workers, function correctly.
addUserScript injection during WKWebView creation is effective, and evaluateJavaScript during the page loading process works as expected. However, when the document becomes unresponsive, executing evaluateJavaScript only triggers the callback after the WKWebView is destroyed.
I have discovered a reliable method to reproduce the white screen issue in WKWebView. This method involves the following steps and conditions:
Create a WKWebView instance.
Load an HTML page using the loadRequest method(https url request).
Before the WKWebView is attached to the UI (not yet visible to the user), call the evaluateJavaScript function.
This issue has occurred in almost all iOS versions, including the latest iOS 17.x version.
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
I'm trying to use ES6 module imports in a Safari Web Extension, but despite enabling "type": "module" in the manifest, imports are not functioning as expected.
Specifically when working with a project structure that includes multiple directories.
A root directory containing the manifest.json and main entry point scripts
A scripts/ folder housing core functionality modules
A common/ directory for shared utilities, constants, and helper functions
A background.js file in the root that attempts to import from these various directories
When trying to import modules from the scripts/ and common/ directories into my background.js, I'm encountering complete import failures.
How can I correctly implement cross-directory module imports in Safari Web Extensions?
I am currently developing a Chrome, Firefox and Safari web extension, and I am facing a CSP issue on the content script on Safari.
The extension I develop has a content script that injects an img tag in the DOM of web pages the user is visiting. That img tag fetches its content at a specific URL.
On Chrome and on Firefox, the img tag content fetches the content at the URL with no issue on every web pages, including those that set the CSP header img-src.
On Safari, I'm getting the following error on web sites that set the img-src CSP header:
Refused to load https://axxlfrmnpq.cloudimg.io/www.macifavantages.fr/wp-content/uploads/2021/06/Garmin-logo.png?func=bound&w=225&h=113 because it does not appear in the img-src directive of the Content Security Policy.
Here is the actual CSP img-src header content of the web page where, on Safari, the injected img tag does not load the content at https://axxlfrmnpq.cloudimg.io/www.macifavantages.fr/wp-content/uploads/2021/06/Garmin-logo.png?func=bound&w=225&h=113:
Content-Security-Policy: img-src https://secure.adnxs.com https://www.facebook.com https://.garmin.cn 'self' data: .garmin.com .trustarc.com .truste.com https://static.garmincdn.com https://www.google.com https://www.google.co.uk https://prefmgr-cookie.truste-svc.net https://res.cloudinary.com https://res.garmin.com https://.criteo.com https://.doubleclick.net https://www.googleadservices.com https://px.adentifi.com https://rtb.adentifi.com https://.teads.tv https://www.googletagmanager.com https://bat.bing.com https://.yahoo.com https://sync.outbrain.com https://*.google-analytics.com https://stats.g.doubleclick.net https://static.hotjar.com https://script.hotjar.com .akamaihd.net https://.tealiumiq.com https://deploytealium.com https://pixel.mediaiqdigital.com;
My question is, is the page CSP blocking the img tag injected in the web page by the extension's content script?
If so, is this behavior documented somewhere, or is it a Safari bug?
I saw there is a similar post on the forum, but I couldn't find if the issue is a bug or if it's the expected behavior on Safari: https://developer.apple.com/forums/thread/651542?login=true.
Thank you very much for your help.
Hello,
We do not have explicitly set it our website, but still Smart Banner appears since we have universal link setup. (current URL matches the universal link patterns set in your apple-app-site-associations file ). Also, I understand it appears only for users having our app installed.
We do not want to show this banner in any case. is there any way to choose not to show the app banner? either setting additional meta or any other way would work.
regards,
Hussain
Using the PaymentRequestAPI, I see this request element listed, but I can't find any description what these features could be:
sequence <ApplePayFeature> features;
https://developer.apple.com/documentation/apple_pay_on_the_web/applepayrequestbase
https://developer.apple.com/documentation/apple_pay_on_the_web/applepayrequestbase/4224914-features
Hello,
I was going through the Apple Pay API documentation and noticed ambiguity on the exact process to complete merchant validation.
One of the documentation mentions that the validation url will be
Your server posts a request using mutual TLS (mTLS) by calling the Apple Pay server’s Payment Session endpoint.
Endpoint (Global)
POST https://apple-pay-gateway.apple.com/paymentservices/paymentSession
Endpoint (China region)
POST https://cn-apple-pay-gateway.apple.com/paymentservices/paymentSession
Referencing the url: https://developer.apple.com/documentation/apple_pay_on_the_web/apple_pay_js_api/requesting_an_apple_pay_payment_session
whereas the other references that the value should be used as provided by the onvalidatemerchant event object with the property validationURL.
Refer: https://developer.apple.com/documentation/apple_pay_on_the_web/apple_pay_js_api/providing_merchant_validation
Can someone confirm which is the correct approach to follow ?
Good day, please send the code for your application to TestFlight. Rudolf Chejn
Topic:
Safari & Web
SubTopic:
General
使用direct distribution进行分发时,safari web extension 在safari setting 中显示没有权限读取、修改或传输任何网页的内容。
但是我在看公证日志显示插件是正常的公证的
这导致safari extension 无法使用。
公证日志
https://www.coupert.com/img/2025-04-10/notarization-log.json
My Mac app and its Safari web extension share an app group, and I want to notify the web extension native process when the app makes a change to the app group NSUserDefaults, but I can't find a good way to do this.
According to the documentation, "You can use key-value observing to register observers for specific keys of interest in order to be notified of all updates, regardless of whether changes are made within or outside the current process." In my testing, however, this doesn't work in the web extension process. I'm using NSUserDefaults addObserver forKeyPath, but observeValueForKeyPath never gets called.
I've also tried NSDistributedNotificationCenter, but the web extension process doesn't receive the notifications sent by the main app.
Are either of these supposed to work? If not, are there any alternatives?
Having the app localised and configured to Dutch from Belgium (nl_BE), I open a url with WKWebView. The website locale detects Dutch from Netherlands (nl_NL)
When i use adjust redirect:
https://app.adjust.com/xxxxxx?label=xxxxxx&redirect=http%3A%2F%2Fwww.testingmcafeesites.com%2Ftestcat_bu.html
It open 2 links:
https://Fwww.testingmcafeesites.com
then http://www.testingmcafeesites.com/testcat_bu.html
And in my app use redirect link for open a web page. But content in domain url like https://www.testingmcafeesites.com/ not be set. So it talke long time often 1 minute for finish request in first link.
It hapen only in ios 18 i tested in ios 17 and ios 16 it open one link only.
This is a rare occurrence on our site, having only detected 4 instances of it over the past few weeks, where 10s of thousands of transactions have occurred successfully.
We only call the following PaymentRequest API onClick from the <apple-pay-button>:
async function startApplePay(merchantIdentifier, amount) {
...
try {
const request = new PaymentRequest([ applePayMethod ], paymentDetails);
...
catch (e) {
// cancel, just stay here
if (e.name === "AbortError") {
if (consoleLog) console.log("Payment canceled", e);
logServer("INFO", "Payment canceled");
}
else {
handleError("Error caught: " + e.name + ", " + e.cause + ", " + e.message);
}
}
Where the "handleError" else case is what gets triggered:
Error caught: SecurityError, undefined, show() must be triggered by user activation.
All 4 instances have been from iPads, but with that small of a sample size, we can't tell whether that's relevant or coincidence. Different iOS versions, but looks like same Safari version.
Here are the 4 User Agents we've seen thus far:
Mozilla/5.0 (iPad; CPU OS 18_2_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) GSA/352.0.715618234 Mobile/15E148 Safari/604.1
Mozilla/5.0 (iPad; CPU OS 17_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) GSA/352.0.715618234 Mobile/15E148 Safari/604.1
Mozilla/5.0 (iPad; CPU OS 18_3_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/133.0.6943.33 Mobile/15E148 Safari/604.1
Mozilla/5.0 (iPad; CPU OS 18_2_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/133.0.6943.33 Mobile/15E148 Safari/604.1
So I have web Augmented Reality apps hosted on AWS S3. It worked fine for a month, but as soon as the IOS 18.4 update was installed they stopped working. It works on every other device and IOS versions.
The URLs for the mentioned AR experiences:
digitechonline.in/solsprefimaginewt8/
digitechonline.in/solsprefimaginewt8p2/
digitechonline.in/orocarear/
These AR experiences get stuck on the loading screen and either reload or give an error. Ideally the camera is supposed to open.
I have tested it on Safari, Microsoft Edge and Google Chrome browsers.
They were created through Unity webgl and hosted on AWS S3 bucket. Please provide a quick solution to this.
I am using SFSafariViewController to process payments via a Stripe checkout URL. Once the payment is completed, the user is redirected to a success URL. I have also added associated domains for deep linking. Below is my implementation:
func presentCheckout(url: String) {
showProgressHUD()
let checkoutURL = URL(string: url)!
safariVC = SFSafariViewController(url: checkoutURL)
safariVC.delegate = self
self.present(safariVC, animated: true)
}
// Delegate method implementations
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
print("SafariViewController dismissed")
// Handle dismissal
}
func safariViewController(_ controller: SFSafariViewController, initialLoadDidRedirectTo URL: URL) {
print(URL.absoluteString)
if URL.absoluteString.contains("xsworld/payment/stripe/checkout/success") {
controller.dismiss(animated: true) {
if URL.absoluteString.contains("/v1/resources/xsworld/payment/stripe/checkout") {
NotificationCenter.default.post(
name: Notification.Name("StripePaymentStatus"),
object: nil,
userInfo: ["url": URL]
)
}
}
} else if URL.absoluteString.contains("xsworld/payment/stripe/checkout/cancel") {
// Handle failure
NotificationCenter.default.post(
name: Notification.Name("StripePaymentStatus"),
object: nil,
userInfo: ["url": URL]
)
}
}
func safariViewController(_ controller: SFSafariViewController, didCompleteInitialLoad didLoadSuccessfully: Bool) {
if didLoadSuccessfully {
print("Initial page loaded successfully")
} else {
print("Initial page load failed")
}
}
Issue:
The safariViewController(_:initialLoadDidRedirectTo:) method does not always get called after the payment is completed. Sometimes it works as expected, and sometimes it does not trigger at all.
What I’ve Tried:
Ensuring the associated domains for deep linking are correctly set up.
Checking the success and failure URLs.
Debugging to see if the redirect happens but is not detected.
What I Need Help With:
I want to ensure that the redirection always works after the payment process is completed, whether through deep linking or another reliable approach. How can I guarantee that my app correctly detects and handles the redirect every time?
Any guidance or best practices would be greatly appreciated.
Topic:
Safari & Web
SubTopic:
General
Tags:
Safari Developer Tools
Safari Services
Safari
Safari Extensions
Hi,
when I display an HTML page with a on Safari iOS, I get a nice UI. Great! At the first look I see a video frame with an arrow-in-a-circle button in the middle. Very nice. I click on the arrow and I get a fullscreen view while the video begins to play. I watch the video then I pause it then I click on the top-left x button. So I go back to my html page and the video is perfectly there as it was before.
But, there is an annoying new detail. The video frame is really dark, it still presents all the controls and a "different" arrow button to play it again. In other words that nice video-frame, that nice picture, is not longer visible on the page. That nice page with nice pictures has now an almost-black rectangle. Too bad.
Sure I can click on the video (outside the controls) then the controls and the black overlaying frame disappear. I can see that nice picture again. Finally. Well, but the arrow-in-a-circle button to play the video disappeared. Now the user cannot longer understand that's a video to play. It looks just like any other pictures to admire statically.
Is any way to get the previous first look of the video? The one clear, with the current frame and the arrow-in-a-circle look?
I have a web extension that I want to send data to, and receive a response containing modified data.
My understanding is that the native app is only contactable by a background script. How does a webpage contact the background script?
One answer is by adding a content script, which is able to communicate with the background script using browser.native.sendMessage(). Unfortunately this triggers a warning that "this extension can read and alter web pages".
I do not want to read and alter web pages, nor do I want users to be concerned about a permission the app doesn't need. I just want to receive data, and then return a response.
What API should I be using to achieve this?
Hi, I have tried to research how safari clean up the cookie when it reaches maximum limit (4kb) on internet but cannot find a good answer. Anyone can help me to give an answer for this question? Thanks in advance
Topic:
Safari & Web
SubTopic:
General
Good morning fellow developers,
For a while i am struggeling with providing sound to my users on IOS (Safari on Mac is no problem and every other device is not a problem) (we have an existing phone system and made a chat as well), the case is very simple: the notification sound is only for users who are logged in and online for chat.
i have tried multiple things:
Audio play with javascript (start with mute, play when user clicks a button so the sound is familiar, play when user clicks a button and directly pause it and continue when needed)
PWA: the dashboard has been made available as pwa and notifications using google firebase. The popup does show for notifcations to be allowed (and receiving the notifications does work on any other device) But any IOS device cannot register.
The information i find is that notifications were supported with 16.4 or higher but also have been deprecated around IOS 17, auto play is not allowed.
We have an app in development for our product as well were we will have a notification which will handle this, but that is not the solution we can use now.
Long story, short question: is it still somehow possible to push a notification to the user when using the PWA or play a sound in the browser (based on an ajax function). The app/website wont be in the background, so it will always be on the screen.
Languages we use: html/javascript (mostly vanilla)/php
Our app is an enterprise app via MDM.
We are experiencing an issue in iPadOS 18.4 when loading an internal HTTPS server via WKWebView in a hybrid iOS app.
Our server uses a self-signed certificate but lacks the digitalSignature usage in its Key Usage extension. (Currently we have no chance to change the server's certificate)
We override webView:didReceiveAuthenticationChallenge:completionHandler: to trust the certificate:
completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
This "completionHandler" works in previous 18.3.2 , but not work in 18.4. May I know is there any changes in 18.4 for the https certification? Why this delegate not work? What we can do to ignore this ssl error and get connection?
Thanks in advance, look forward for your reply.
I have multiple web views of the same domain that share the same local storage, as expected.
One of them though, is loading a .webarchive file.
The web archive is of the same domain, and is loaded using the same base URL.
For some reason, in most cases, the local storage is not shared with this web view when loading the web archive, although if I make that same web view load the actual live web page it does share local storage.
I say in most cases, because for some users it works as expected, but for a significant portion of users it isn't sharing local storage.
I think that the main difference between working and not is iOS version. iOS 17 seems to be able to share the local storage but iOS 18 does not. I can't find anything related in the release notes of iOS 18 versions.
There is nothing in the documentation for load(_:mimeType:characterEncodingName:baseURL:), or the header file, that explains anything specific about local storage and webarchive loading.
Does anyone know for sure how local storage is handled when a webarchive is loaded into a web view, and did something change with iOS 18 in regards to this?