I'm using a CSS filter to achieve dark mode for my HTML page. I know it's imperfect, but I have no choice for many reasons.
However, I found that the CSS filter produces incorrect colors in iOS 26.2 WebView, while it works fine in iOS 18.6.2 WebView.
Here is my HTML and CSS filter:
<html>
<head>
<style>
.filter_container {
/* invert colors for the entire page */
filter: invert(1) hue-rotate(180deg);
}
.filter {
/* restore colors for specific elements, such as img */
filter: hue-rotate(180deg) invert(1);
}
</style>
</head>
<body>
<div>original & bgcolor+filter & img+filter</div>
<table>
<tr>
<td>
<div style="display:flex; gap:1px; align-items:center; justify-content:center;">
<div class="origin_container"><div class="origin" style="background-color:#FFFFFF; height:60px; width:60px; border-style: solid; border-color: #000000; border-width: 1px;"></div></div>
<div class="filter_container"><div class="filter" style="background-color:#FFFFFF; height:60px; width:60px; border-style: solid; border-color: #000000; border-width: 1px"></div></div>
<div class="filter_container"><img class="filter" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAAAdklEQVR4nOXOQQEAIACEMKR/57OFPliCnW0jRGIkRmIkRmIkRmIkRmIkRmIkRmIkRmIkRmIkRmIkRmIkRmIkRmIkRmIkRmIkRmIkRmIkRmIkRmIkRmIkRmIkRmIkRmIkRmIkRmIkRmIkRmIkRmIkRmIkxt+B1y6HmAR0uIzOQQAAAABJRU5ErkJggg==" style="height:60px; width:60px; border-style: solid; border-color: #000000; border-width: 1px"></img></div>
</div>
<div style="text-align:center;">#FFFFFF</div>
</td>
...many other colors
</table>
</body>
</html>
It works fine in iOS 18.6.2 WebView:
But renders incorrectly in iOS 26.2 WebView:
General
RSS for tagExplore 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
Is iOS WebRTC communication via WebView stable when the app is in the background?
I'm implementing SIP communication using JsSIP within a WebView. On iOS, I'm using WKWebView, but I'm concerned that its resources may be limited by the system when the app is backgrounded. Even with the VoIP background mode declared in the Info.plist file, will the system preserve sufficient resources to keep the SIP communication active?
If the extension uses manifest v3 and a background script in the form of a service worker, then in Safari it is not possible to open the background script debugging window. If I expand the Developer menu in Safari, there is nothing under Web Extension Background Data (or disappear after click), which is an error. In other browsers (Edge, Chrome, Opera, Firefox) this works correctly.
If I switch the background script back to non-persistent script mode, everything works fine and from the Developer menu and the Web Extension Background Data submenu I am able to open the background script debugging window for the extension. Am I doing something wrong?
I am maintaining a PWA that utilizes WebSockets. In this app, after the web page is loaded from the server, JavaScript establishes a WebSocket connection.
Because the app connects to a completely local server on a managed local network, we use http:// and ws:// (non-secure).
The Issue: The app worked perfectly from older iOS versions up to iPadOS 18. However, during testing on iPadOS 26, we encountered an issue where the WebSocket connects successfully but is disconnected by the iPad approximately one second later.
According to our packet captures, the iPad is sending a FIN packet to initiate the teardown.
Additional Context: What makes this particularly confusing is that we have another server hosting the exact same PWA where the WebSocket connection stays stable even on iPadOS 26. This suggests it might not be a universal OS bug, but perhaps related to specific network conditions or a new security policy.
Has anyone experienced similar behavior on iPadOS 26?
Could this be a bug, or is there a new security restriction regarding non-secure WebSocket (ws://) connections in local networks?
Are there any known changes in WebKit/Safari for iPadOS 26 that might cause the OS to send a FIN packet immediately after a handshake?
I would appreciate any insights or suggestions on what might be causing this.
Topic:
Safari & Web
SubTopic:
General
I want to print the content of a WKWebView. I've done some searching, and many people have struggled with this over the years. Some claimed success, but their solutions don't work for me. One person created images for each pages and printed that, but then if you were to print to PDF, you'd get a PDF containing images rather than text.
If I just call the printView(_:)) method of the view, I get blank pages.
With the following more elaborate code, I get a partial printout, 11 out of what should be about 13 pages.
let info = NSPrintInfo.shared
info.topMargin = 72.0;
info.bottomMargin = 72.0;
info.leftMargin = 72.0;
info.rightMargin = 72.0;
info.isVerticallyCentered = false;
info.isHorizontallyCentered = false;
info.horizontalPagination = .fit;
info.verticalPagination = .automatic;
let printOp = webView!.printOperation( with: info )
printOp.canSpawnSeparateThread = true
printOp.view?.frame = NSMakeRect( 0, 0,
info.paperSize.width, info.paperSize.height )
printOp.runModal(for: webView.window!, delegate: self,
didRun: nil, contextInfo: nil )
When I run the above under the debugger, I see console messages saying
CGContextClipToRect: invalid context 0x0.
Once the print dialog appears, if I touch (but not change) the selected printer, then the page count changes to the correct value.
I develop a tab manager extension: https://apps.apple.com/ua/app/tab-finder-for-safari/id6741719894
It's written purely in Swift. All Safari interactions are done solely inside a SFSafariExtensionHandler .
But now i'm considering adding some features from Google Chrome's Extension API like window switching.
Is it possible to add a background.js worker to my existing Safari App Extension to have access to the beginRequest method override inside SFSafariExtensionHandler?
Without converting my extension from Safari App Extension to Safari Web Extenion?
I want to migrate from a Safari App Extension to a Safari Web Extension, but don't know how to get rid of the message, telling users that my extension can access their passwords. Here is a message which I see:
I was thinking that this might be because all Safari Web Extension get this type of access, but I have a Safari Web Extension which does not require such level of access:
Here is the manifest:
{
"manifest_version": 2,
"default_locale": "en",
"name": "__MSG_extension_name__",
"description": "__MSG_extension_description__",
"version": "1.1",
"icons": {
"48": "images/icon-48.png"
},
"background": {
"scripts": [
"background.js"
],
"persistent": true
},
"browser_action": {
"default_popup": "popup.html",
"default_icon": {
"16": "images/toolbar-icon-16.png"
}
},
"permissions": [
"nativeMessaging", "tabs"
]
}
and here is the Info.plist file:
Here is the entire code of the extension:
https://github.com/kopyl/web-extension-simplified
After App uses Network.framework PrivacyContext Api, dns has been encrypted, that is good.
But when using wkwebview to load web page, wireshark captures normal dns request sent by wkwebview.
Does wkwebview use DoH to resolve domain? if can, how to config params?
If can not, is there anyway to stop wkwebview sending normal dns, such as local proxy.
On iOS Devices with ProMotion (120HZ) if you animate Elements on your Page with animation-timeline you get Ghosting Effects.
You can not see the Ghosting with a Simulator or on Screenshots, only on real Devices.
To Reproduce I made a Minimal Example:
https://codesandbox.io/p/sandbox/120hztest-xrwgtc
When you scroll quickly on the Page with an iOS 120HZ Device (https://en.wikipedia.org/wiki/List_of_smartphones_with_a_high_refresh_rate_display)
you will see ghosting on the Top of the right Element (animation-timeline) and no ghosting on the other animated Element.
(I edited the Screenshot, to Illustrate how the Effect looks like, since it is only visible on the real Display)
It’s the small things that make a difference, and the three dots at the top of the screen in Safari and Chrome are such examples. I’ve already accidentally deleted several tab groups by accident and try to relearn browsing is harder than it should be.
Topic:
Safari & Web
SubTopic:
General
Scenario Overview:
In our app, we open an in-app browser to complete a third-party consent flow. The sequence is:
App → Website A (set cookie and redirect) → Google → Website A (check cookie) → App
After upgrading the app, the first consent attempt fails because the cookie cannot be written, causing the check cookie step to fail. However, if we use the native Safari browser, this issue does not occur.
Observed Behavior:
Scenario
Result
Upgrade app → Consent
❌ Fail
Upgrade app → Consent fail → Consent again immediately
✅ Pass
Upgrade app → Consent fail → Upgrade again after 1–2h → Consent
✅ Pass
Upgrade app → Consent fail → Upgrade again after 1d → Consent
❌ Fail
Install a new app → Consent
✅ Pass
Upgrade app → Consent, cancel flow → Consent again
✅ Pass
Install new app → Wait for upgrade → Upgrade app → Consent
✅ Pass
Install new app → Wait 1–2h → Upgrade app → Consent
✅ Pass
Investigation:
From Safari documentation, this seems related to Intelligent Tracking Prevention (ITP), which restricts cross-site cookie behavior during first-party interactions. However, I haven’t found a clear mitigation strategy yet.
Question:
Has anyone encountered similar issues with Safari ITP after app upgrades? Are there recommended approaches to ensure cookies persist across this redirect flow?
Topic:
Safari & Web
SubTopic:
General
It seems Safari 18's fetch() does not include credentials even credentials: include and safari extension has host_permissions for that domain.
Is there anyone has this problem?
I try to request in popup.js like this:
const response = await fetch(
url,
{
method: 'GET',
mode: 'cors',
credentials: 'include',
referrerPolicy: 'no-referrer',
}
);
and it does not include the cookie from host_permissions.
Those code worked in Safari 17 (macOS Sonoma).
Hi, after upgrading MacOS (MB Air M1 Version 26.2 (25C56)) & Safari (Version 26.2 (21623.1.14.11.9)) to latest versions, we are experiencing a new bug occurring with our web extension (Click & Read) on local storage writing and getting this error :
Invalid call to browser.storage.local.set(). Disk I/O error.
This doesn't happen on other browsers (chromium, Firefox).
export const setLocalStorage = async (value: object) => {
try {
await browser.storage.local.set(value);
} catch (error) {
console.error("[Click & Read] Error setting local storage", error);
}
};
I have a simple website, that I would like to make available as a progressive webapp, so I can somewhat customize what happens when people add the website to their homescreen (using the Share button) and maybe, in the future, use PWABuilder or something similar to publish it in some stores.
My website needs authentication using OIDC, which after some redirects within the PWA opens an authenticator app on the phone.
When the app returns from authenticating however, it opens a new browser tab instead of my PWA, so there is no context and the login fails.
I am under the impression that this used to work, but I'm not sure. I'm also not sure what the problem is, I have no idea how, when the Authenticator app opens a URL (which is what I assume is happening under the hood), iOS or Safari or whatever would know which app to open (as the redirect URL is to the OIDC Idp, not the URL of my Web app).
Any hints where I could look for a solution? Thanks!
Topic:
Safari & Web
SubTopic:
General
Subject: Unexpected system confirmation dialog when opening a Universal Link
Description of the issue:
We’re implementing a login flow using Native iOS apps, Universal Links, and OpenID Connect authentication. Our domain is correctly configured with the apple-app-site-association file, and Universal Links work as expected.
However, under certain circumstances, the behavior differs on the same login page:
The user connects to the OIDC provider in their mobile browser.
Instead of automatically switching to the Native application, a popup asks the user to open the app.
The behavior depends on how the login page is opened:
When opened in a new browser tab, the Universal Link opens the app immediately without showing any system confirmation dialog.
When the same tab is reused without a page refresh, iOS displays a system confirmation dialog asking the user to open the link in the app. This confirmation dialog doesn’t appear in the first scenario.
This additional system dialog impacts the user experience, as we aim for a frictionless and seamless login flow with minimal confirmation steps.
Question: Why does the app switch work automatically only the first time?
Is this intentional iOS behavior? If so, what security requirement or system rule causes a confirmation dialog when reusing the same tab, but not when redirecting in a new tab or pressing a button on the reused tab? Is this expected design, or should we adjust our side to avoid this dialog?
Environment details:
Verified on two devices
iOS versions: 18.7.2, 26.1
Thanks for your help.
Hi everyone,
I’m building a React Native iOS app where I’m integrating Wazo (native WebRTC) and Jitsi (WebView / WebRTC).
Use case:
Wazo is used to maintain a background call session (mainly signaling + audio keep-alive).
Jitsi is used in the foreground for video calls.
Problem:
When Jitsi starts, it takes control of the microphone and camera.
The Wazo call disconnects after ~5 minutes (likely due to media / audio session conflict).
Even if Wazo audio/video is muted or tracks are disabled, the session still drops.
My questions:
Is it officially supported or recommended to run two WebRTC stacks (Wazo + Jitsi) simultaneously on iOS?
Can Wazo stay connected without active audio/video tracks while Jitsi uses mic/camera?
Is there a way to release Wazo media streams temporarily (but keep signaling alive) while Jitsi is loading or active?
Are there any AVAudioSession / background mode limitations on iOS that make this impossible by design?
If this is not supported, what is the recommended architecture (single WebRTC pipeline, switching media ownership, etc.)?
Environment:
iOS (React Native)
Wazo SDK (native WebRTC)
Jitsi Meet (WebView)
CallKit + PushKit enabled
Any guidance, documentation, or real-world experience would be greatly appreciated.
Thanks in advance 🙏
I'm working on a web browser App that's distributed via the App Store. This app renders web pages using WKWebView.
Our users are requesting a way for us to allow them to play videos in Picture in Picture. After some investigation, we noticed that in order to allow PiP videos in our browser in the sandboxed environment, we need to add the com.apple.PIPAgent entitlement under the com.apple.security.temporary-exception.mach-lookup.global-name option.
We tried to submit our app with this entitlement, but unfortunately, we were rejected:
Guideline 2.4.50) - Performance
We've determined that one or more temporary entitlement exceptions requested for this app are not appropriate and will not be granted:
com.apple.security.temporary-exception.mach-lookup.global-name
com.apple.P|PAgent
We would like to have access to this entitlement so we can offer PiP to our users.
We already created a radar about this as well: FB13814428
Additionally, we have another radar (FB13557716) regarding allowing the usage of a private flag _allowsPictureInPictureMediaPlayback, which would also be required to enable us to use PiP.
Is there any way in which we can currently enable PiP? Would opening a TSI help here?
Hello,
I am implementing video calling on iOS and need to support Picture in Picture (PiP) behavior similar to FaceTime or WhatsApp.
What works
Audio continues correctly in background
CallKit UI works as expected
Video works correctly while the app is in the foreground
What I’m trying to achieve
When the user presses the Home button or switches apps, I want to show a system Picture in Picture window (floating video outside the app).
Current setup
Video is rendered via WebRTC
The video is displayed inside a WKWebView (HTML / JavaScript)
PiP works only while the app is foregrounded
When the app backgrounds, the video disappears (only audio remains)
Questions
Does iOS support system Picture in Picture for:
WebRTC video
WKWebView / HTML video
2 Is AVPictureInPictureController limited only to:
AVPlayerLayer
AVSampleBufferDisplayLayer
3 If PiP requires native rendering:
Is it mandatory to render WebRTC frames natively using AVSampleBufferDisplayLayer?
Is PiP explicitly unsupported for WebView / HTML video?
📌 Clarification
Apps like FaceTime and WhatsApp are able to show PiP outside the app.
I want to understand whether this behavior is achievable only with native video pipelines, or if WebView-based video is fundamentally restricted by iOS.
Any official clarification or documentation reference would be appreciated.
Thank you.
Touch not working to close in-app close-ups since latest iOS 26 update
Topic:
Safari & Web
SubTopic:
General
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!