Explore the integration of web technologies within your app. Discuss building web-based apps, leveraging Safari functionalities, and integrating with web services.

General Documentation

Posts under General subtopic

Post

Replies

Boosts

Views

Activity

WebKit crash on iOS 18.3
After the official release of iOS 18.3, our app has collected numerous identical crash logs. These crashes occurred on different devices, but the common denominator is that they all, and only, happened on iOS 18.3. Based on the stack trace, the crash is happening internally within WebKit. The details are as follows: Crashed: com.apple.main-thread 0 WebCore 0x721f9c + 28 1 WebCore 0x15b6924 + 11356 2 WebCore 0x15b174c + 1008 3 WebCore 0x1776e4 + 292 4 WebCore 0x17753c WebCore::SerializedScriptValue::deserialize(OpaqueJSContext const*, OpaqueJSValue const**) + 100 5 WebKit 0x530b28 + 92 6 WebKit 0x5a0d2c + 176 7 WebKit 0x9e74b0 + 956 8 WebKit 0xe43d58 + 392 9 WebKit 0x886ac + 272 10 WebKit 0x88940 + 44 11 WebKit 0x87a74 + 252 12 WebKit 0x875ec + 576 13 JavaScriptCore 0x2f8a48 ***::RunLoop::performWork() + 204 14 JavaScriptCore 0x2f895c ***::RunLoop::performWork(void*) + 36 15 CoreFoundation 0x73f4c CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 28 16 CoreFoundation 0x73ee0 __CFRunLoopDoSource0 + 176 17 CoreFoundation 0x76b40 __CFRunLoopDoSources0 + 244 18 CoreFoundation 0x75d3c __CFRunLoopRun + 840 19 CoreFoundation 0xc8284 CFRunLoopRunSpecific + 588 20 GraphicsServices 0x14c0 GSEventRunModal + 164 21 UIKitCore 0x3ee674 -[UIApplication _run] + 816 22 UIKitCore 0x14e88 UIApplicationMain + 340 23 18Birdies 0x1b2d3c main + 14 (main.m:14) 24 ??? 0x1ac161de8 (Missing)
Topic: Safari & Web SubTopic: General Tags:
1
0
597
Feb ’25
Websockets (WS/WSS) in iOS26
We're having trouble connecting to local area network websockets in Safari in the latest iOS26 Beta 3 (iPhone 14), both secure and unsecure. Code works < iOS26 & macOS, etc. -- Unsecure behaviour: need to call connectWebSocket() twice, establishes connection reliably. Calling connectWebSocket() once, will sometimes work, sometimes not. -- Secure behaviour: Error in debug console, even though the certificate has been accepted and the page is loaded as https. Error: WebSocket connection to 'wss://192.168.1.81/api/webSocket' failed: The certificate for this server is invalid. You might be connecting to a server that is pretending to be “192.168.1.81”, which could put your confidential information at risk. -- let apiEndpoint = window.location.hostname; if (apiEndpoint == null || apiEndpoint == '') { apiEndpoint = "192.168.1.81"; } function connectWebSocket() { if (webSocket && webSocket.readyState == 1) { return; } if (webSocket) { webSocket.close(); } webSocket = new WebSocket( (window.location.protocol === 'https:' ? "wss://" : "ws://") + apiEndpoint + "/api/webSocket", ); webSocket.onerror = (error) => { console.log("WebSocket error", error); }; webSocket.onopen = () => { console.log("WebSocket connected"); webSocket.send("volume"); webSocket.send("isPlaying"); }; webSocket.onmessage = (event) => { const msg = event.data; if (!msg) return; if (msg.startsWith("volume")) { const volume = parseInt(msg.replace('volume:','')); const slider = document.getElementById("volumeSlider"); slider.value = volume; slider.style.background = `linear-gradient(to right, #007bff ${volume}%, white ${volume}%)`; } else if (msg.startsWith("isPlaying")) { const url = msg.replace('isPlaying:', ''); let matchedEntry = null; let coverToSelect = null; categories.forEach((category, catIdx) => { category.entries.forEach((entry, entryIdx) => { if (entry.url === url) { matchedEntry = entry; coverToSelect = document.querySelector(`.cover[category-idx="${catIdx}"][entry-idx="${entryIdx}"]`); } }); }); if (matchedEntry && coverToSelect) { selectCover(coverToSelect, true); showNowPlayingBar(matchedEntry); const top = coverToSelect.getBoundingClientRect().top + window.scrollY - 150; window.scrollTo({ top, behavior: 'smooth' }); } } }; webSocket.onclose = () => { console.log("WebSocket closed, retrying..."); setTimeout(connectWebSocket, 1000); }; } document.addEventListener("visibilitychange", () => { if (document.visibilityState === "visible") { connectWebSocket(); } }); connectWebSocket();
1
3
807
Jul ’25
iOS26 Safari rendering bug even on latest beta 3
I am testing stuff on a website, and it worked well on any mobile browser till iOS18. Now that I am testing iOS26, even with the latest BETA (3) everything works smoothly on any other mobile browser but Safari. Previously I had the bug, which now has been patched, for status-bar, which was flickering too, but popover and page issue seems still there. I have persistent popover and ajax navigation, and both are rendering with bugs and fouc while view/page changes. Example: If I have an element which must stay on its place and its width is 100vw: while page changes it blinks, shrinks, flicker and jumps on rendering, while it simply must stay as is.. Animations and page transitions work smoothly on Chrome mobile (latest iOS 26 beta 3) , while breaking on Safari. I did open a feedback FB18328720, but seems no one caring. Any idea guys? ** Video of the bug (which is huge!) : ** https://youtube.com/shorts/rY3oxUwDd7w?feature=share Cheers
1
0
370
Aug ’25
Is it possible to programmatically set macOS notification preferences for an app in Swift?
Hi, I’m working on a Safari extension for macOS, and I’d like the app to use specific system notification settings right after installation. I’m wondering if there’s a way in Swift to programmatically configure the default notification preferences (as seen in System Settings > Notifications > [my app]). Here are the desired settings: Only Desktop – without “Notification Center” or “Lock Screen” Alert Style: Temporary Badge App Icon: Enabled Play Sound for Notifications: Disabled Show Previews: When Unlocked Notification Grouping: Off (I don’t want them to accumulate in Notification Center) Here is the code I’m currently using to display a basic notification: private func handleNotificationRequest(_ message: [String: Any]) { guard let title = message["title"] as? String, let body = message["body"] as? String else { return } UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, error in if granted { self.showNotification(title: title, body: body) } } } private func showNotification(title: String, body: String) { let content = UNMutableNotificationContent() content.title = title content.body = body content.sound = nil // No sound for subtle notification // Create notification that doesn't persist in notification center let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 0.1, repeats: false) let request = UNNotificationRequest(identifier: "fast-url-copy-notification", content: content, trigger: trigger) UNUserNotificationCenter.current().add(request) { error in if let error = error { os_log(.error, "Failed to show notification: %@", error.localizedDescription) } } } OS: macOS 26.0 Thanks in advance, Mateusz
1
0
443
Jul ’25
Bug {year}} in New Apple Pay SDK Third-browsers (iOS 18)
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!
1
0
208
Mar ’25
Unable to load CSS fonts from WKURLSchemeHandler in a https website
I am trying to cache fonts natively in a hybrid app, so that CSS hosted in an https website loaded in WKWebView through loadRequest can reference them like this for a performance boost: @font-face { font-family: 'MyFont'; src: url('my-assets://Gordita-bold-subset.woff') format('woff'); font-weight: normal; font-style: normal; } The problem happens when I register a WKURLSchemeHandler for my-assets. The handler never gets called and the Safari Web Insepctor shows this: [blocked] The page at https://www.x.com/ requested insecure content from my-assets://Gordita-bold-subset.woff. This content was blocked and must be served over HTTPS. Interestingly enough, if we try to serve content with <img src="my-assets://test.png" this restriction does not apply. Are there any workarounds other than using the private API WKProcessPool._registerURLSchemeAsSecure?
Topic: Safari & Web SubTopic: General
1
0
64
Jun ’25
Safari nativeMessaging with non-persistent background page
I'm working on a Safari web extension that uses the nativeMessaging facility to communication with native code. When I want to notify the javascript extension from the embedding application, I use SFSafariApplication::dispatchMessage. As per the documentation, this call ... ensures that Safari is launched and that your extension is running before delivering the message. Everything works fine when the background script is running. However, after the background script gets unloaded at some point in time (non persistent background page, default behavior for a manifest V3 extension), the background script is not reloaded by the message from the native app (background script still appears unloaded in the developer menu of Safari, double-checked using a counter stored in browser.storage.local incremented on message reception). In this case, the completion handler of the application gets no error (error == nil) as if the message was correctly delivered. I was able to reproduce this behavior with the sample app delivered for WWDC20 (after upgrading the manifest from v2 to v3 to make it non-persistent). Is it supposed to work ? What I'm doing wrong ?
1
1
184
Jul ’25
Safari Extension Stops on iOS 17.5.1 - 18
We are encountering an issue where the Safari extension we are developing stops working while in use on relatively new iOS versions (confirmed on 17.5.1, 17.6.1, and 18). Upon checking the Safari console, the content script is displayed in the extension script, so the background script or Service Worker must be stopping. The time until it stops is about 1 minute on 17.5.1 and about one day on 17.6.1 or 18. When it stops, we would like to find a way to restart the Service Worker from the extension side, but we have not found a method to do so yet. To restart the extension, the user needs to turn off the corresponding extension in the iPhone settings and then turn it back on. As mentioned in the following thread, it is written that the above bug was fixed in 17.6, but we recognize that it has not been fixed. https://forums.developer.apple.com/forums/thread/758346 On 17.5.1, adding the following process to the background script prevents it from stopping for about the same time as on 17.6 and above. // Will be passed into runtime.onConnect for processes that are listening for the connection event const INTERNAL_STAYALIVE_PORT = "port.connect"; // Try wake up every 9S const INTERVAL_WAKE_UP = 9000; // Alive port var alivePort = null; // Call the function at SW(service worker) start StayAlive(); async function StayAlive() { var wakeup = setInterval(() => { if (alivePort == null) { alivePort = browser.runtime.connect({ name: INTERNAL_STAYALIVE_PORT }); alivePort.onDisconnect.addListener((p) => { alivePort = null; }); } if (alivePort) { alivePort.postMessage({ content: "ping" }); } }, INTERVAL_WAKE_UP); } Additionally, we considered methods to revive the Service Worker when it stops, which are listed below. None of the methods listed below resolved the issue. ① Implemented a process to create a connection again if the return value of sendMessage is null. The determination of whether the Service Worker has stopped is made by sending a message from the content script to the background script and checking whether the message return value is null as follows. sendMessageToBackground.js let infoFromBackground = await browser.runtime.sendMessage(sendParam); if (!infoFromBackground) { // If infoFromBackground is null, Service Worker should have stopped. browser.runtime.connect({name: 'reconnect'}); // ← reconnection process // Sending message again infoFromBackground = await browser.runtime.sendMessage(sendParam); } return infoFromBackground.message; Background script browser.runtime.onConnect.addListener((port) => { if (port.name !== 'reconnect') return; port.onMessage.addListener(async (request, sender, sendResponse) => { sendResponse({ response: "response form background", message: "reconnect.", }); }); ② Verified whether the service worker could be restarted by regenerating Background.js and content.js. sendMessageToBackground.js export async function sendMessageToBackground(sendParam) { let infoFromBackground = await browser.runtime.sendMessage(sendParam); if (!infoFromBackground) { executeContentScript(); // ← executeScript infoFromBackground = await browser.runtime.sendMessage(sendParam); } return infoFromBackground.message; } async function executeContentScript() { browser.webNavigation.onDOMContentLoaded.addListener((details) => { browser.scripting.executeScript({ target: { tabId: details.tabId }, files: ["./content.js"] }); }); } However, browser.webNavigation.onDOMContentLoaded.addListener was not executed due to the following error. @webkit-masked-url://hidden/:2:58295 @webkit-masked-url://hidden/:2:58539 @webkit-masked-url://hidden/:2:58539 ③ Verify that ServiceWorker restarts by updating ContentScripts async function updateContentScripts() { try { const scripts = await browser.scripting.getRegisteredContentScripts(); const scriptIds = scripts.map(script => script.id); await browser.scripting.updateContentScripts(scriptIds);//update content } catch (e) { await errorLogger(e.stack); } } However, scripting.getRegisteredContentScripts was not executed due to the same error as in 2. @webkit-masked-url://hidden/:2:58359 @webkit-masked-url://hidden/:2:58456 @webkit-masked-url://hidden/:2:58456 @webkit-masked-url://hidden/:2:58549 @webkit-masked-url://hidden/:2:58549 These are the methods we have considered. If anyone knows a solution, please let us know.
1
1
1k
Aug ’25
Unable to register or use passkeys via Safari Web Extension
There does not appear to be any way to use or create iCloud passkeys with a Safari Web Extension, either using the navigator.credentials API in an extension origin webpage such as the popover, or using the AuthenticationServices framework in the SafariWebExtensionHandler. I've setup an associated domain for my plugin, and I know it works for the host application. But I get errors trying to do so in the web extension target. createCredentialRegistrationRequests results in the following error: Domain=com.apple.AuthenticationServices.AuthorizationError Code=1004 "Application with identifier <ID> is not associated with domain <RPID> The other problem, assuming the entitlement works correctly for the web extension, is that there is no NSWindow to use as the presentation target from the SafariWebExtensionHandler. Trying to use the navigator.credentials.create JS API (which is the preferred method, frankly, in a web extension) results in the following error: NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission. Chrome has a great solution for this that I believe should be adopted by Safari. If an extension has host permissions for a relying party it wants to claim, or if it has an associated domain entitlement for it, webauthn operations should be allowed.
1
1
464
May ’25
Unable to Open HTTP Site B from HTTP Site A in WKWebView – Stuck on Spinning Wheel (Xcode 15.2 and above, VPN Enabled, Cross-Domain)
After upgrading to Xcode 15.2 or above(Till Xcode 16.2), users are unable to open Site B (HTTP URL) from Site A (HTTP URL) within our Browser app when loaded in WKWebView. Clicking the link to Site B results in a spinning wheel, but the site does not load. This issue is not present when the app is built with Xcode 15.0.1. Additionally: Users are connected to a VPN, which is required to access the sites. Site A and Site B are on different domains (cross-domain request). Expected Behavior: Clicking the link to Site B should successfully load the site with user information passed from Site A. Current Behavior: Clicking the link results in a spinning wheel, but Site B does not load inside WKWebView. Technical Details: Both Site A and Site B use HTTP (not HTTPS). Site A and Site B have different domains (cross-domain request). Do not use location.href for transitions. Instead, we temporarily set about:blank in an iframe and then submit data via a form to the target system’s URL within the iframe. This approach worked in Xcode 15.0.1 but fails in Xcode 15.2 or above. Users are connected to a VPN, which is required to access the sites. WKWebview is not receiving navigation delegate callback for Site B Steps to Reproduce: Ensure the device is connected to a VPN. Open the app (using WKWebView) built with Xcode 15.2 or above. Load Site A (HTTP) within the app in WKWebView. Click the link to Site B (HTTP), which should open in an iframe. Observe that a spinning wheel appears, but Site B does not load. Environment: Xcode Versions Affected: 15.2 or above (issue present), 15.0.1 (no issue) iOS Version: All iOS versions Devices: iPad Questions: Has there been any change in WKWebView’s handling of HTTP URLs or VPN-related network traffic in Xcode 15.2? Are there any new security policies, iframe restrictions, or VPN-related changes in this version that might be affecting this behavior? Request for Assistance: Can you confirm if this is a known issue or an intended change? Are there any workarounds available?
Topic: Safari & Web SubTopic: General Tags:
1
0
117
Mar ’25
Level index
Apple must comply with the requirements of the Level Index, the global digital credit gateway, and suspend gift cards and similar services until formal arrangements are made with service providers.
1
0
79
Jun ’25
Safari Web Extension - ES6 Module Imports Not Working After Enabling "type": "module"
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?
1
0
149
Mar ’25
invalid_client when using sign in with apple in browser
Hi guys, I'm trying to use sign in with apple in javascript, I followed the guider in the website, and almost find everything I can find in Google, but nothing help, here is my situation: I create a new App: com.yuhan.test.app I create a new service ID: com.yuhan.test.service configure a domain and return url domain: tts.perterpon.com returnURL: https://tts.perterpon.com/login create a new key for Sign In with Apple. my html code is here, it's easy, but it always told me invalid_client, I think I have done anything I need to do, can somebody help me? Thank you so much. you can test my online web site: https://tts.perterpon.com/login.html ` const buttonElementNew = document.getElementById('appleid-signin'); buttonElementNew.addEventListener('click', async () => { try { const data = await AppleID.auth.signIn() console.log('Try/Catch Data', data.authorization.id_token); const formData = new FormData(); formData.append("token", data.authorization.id_token); await fetch("", { method: "POST", body: formData, }); // Handle successful response. } catch (error) { // Handle error. } }); </script>
1
1
100
Jun ’25
Have control over show/hide the Smart Banner
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
1
0
780
Mar ’25
iOS 26 WebKit Crash
Thread 0 Crashed: 0 WebKit 0x00000001a1b6bf1c WKMouseDeviceObserver.connectedDeviceCount.setter + 68 (WKMouseDeviceObserver.swift:0) 1 WebKit 0x00000001a1b6bea4 @objc WKMouseDeviceObserver.connectedDeviceCount.setter + 152 2 WebKit 0x00000001a1b6d95c closure #2 in WKMouseDeviceObserver.start() + 80 (WKMouseDeviceObserver.swift:0) 3 WebKit 0x00000001a1b4e3e9 &lt;deduplicated_symbol&gt; + 1 4 WebKit 0x00000001a1b4e139 &lt;deduplicated_symbol&gt; + 1 5 WebKit 0x00000001a1b4e769 &lt;deduplicated_symbol&gt; + 1 6 libswift_Concurrency.dylib 0x0000000196037cdd completeTaskWithClosure(swift::AsyncContext*, swift::SwiftError*) + 1 (Task.cpp:546)
1
0
755
Jul ’25
Epic games website sign in page
Hello i would like to report a bug on iOS 26 beta. The problem is on the epic games website you see when I hit sign in it is just blank but the epic games store is just fine i would like this to be fixed on iOS 26 beta 3 thank you.
Topic: Safari & Web SubTopic: General
1
0
280
Jun ’25
iOS 18 upgrade: website map point text now missing after
My website ccflood.us is a simple map that uses a CSV file for the data that is displayed on the map. It uses the ESRI JS API. Recently the points on the map began missing the text in the boxes only on Apple devices that have been upgraded to iOS 18. Has anyone also had this happen to their site? If you have upgraded to iOS 18, try this site on your iPhone then look at it on an Android phone or your desktop browser. You should seet the values in the boxes and a "+" at points that have no value. If you've had this happen with your site or have heard of a fix, please reply to this post.
Topic: Safari & Web SubTopic: General
1
0
373
Mar ’25
When using ProxyConfiguration, use different proxy for HTTP and HTTPS with WKWebView
I am currently developing an app using WKWebView. In iOS 17, Apple introduced ProxyConfiguration, and I have two questions regarding its usage: Is there a way to use ProxyConfiguration to distinguish between HTTP and HTTPS traffic? I have reviewed the documentation but couldn’t find a clear method for this. As an alternative approach, I am attempting to determine the request scheme within WKWebView and switch proxyConfigurations just before loading the request. My current implementation sends requests to hoge_a by default and switches to hoge_b only for HTTP traffic.   if #available(iOS 17.0, *) { if URLString.contains("http:") { webView.configuration.websiteDataStore.proxyConfigurations = [hoge_b] } } webView.load(request) if #available(iOS 17.0, *) { if URLString.contains("http:") { webView.configuration.websiteDataStore.proxyConfigurations = [hoge_a] } }   2. Since I modify proxyConfigurations every time webView.load(request) is called, are there any potential issues or concerns with this approach? I would appreciate any insights you may have on either of these questions.
1
0
368
Feb ’25