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

Notify web extension native process of user default changes
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?
0
0
68
Apr ’25
The tag displayed in native webview does not work in iPadOS 26 Beta
I'm creating an iPad app using Xcode 26 Beta 6. I have the following simple code and web page, but when I tap the file selection button, nothing appears. Do I need to add any additional code? code struct SwiftUIWebView: View { @State private var webPage = WebPage() private let url = URL(string: "https://www.xxxx.com/")! var body: some View { WebView(webPage) .onAppear { webPage.load(URLRequest(url: url)) } } } web page <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Test</title> </style> </head> <body> <div id="container"> <input type="file" /> </div> </body> </html>
Topic: Safari & Web SubTopic: General Tags:
0
0
335
Aug ’25
Safari Does Not Include topOrigin in WebAuthn clientDataJSON Despite crossOrigin: true
Hello, I’m working on a cross-origin WebAuthn implementation where a parent page embeds an iframe from a different origin to perform authentication. According to the WebAuthn Level 3 spec (Section 7.1.1), when crossOrigin is true, the clientDataJSON may include topOrigin—but Safari does not seem to populate this field. Observed Behavior: Chrome/Firefox: Include topOrigin in clientDataJSON when crossOrigin: true. Safari (macOS/iOS): Omits topOrigin even though crossOrigin is correctly set to true. Example clientDataJSON from Safari: { "type": "webauthn.get", "challenge": "...", "origin": "https://iframe-origin.example.com", "crossOrigin": true // Missing `topOrigin` (expected: parent origin) } Questions: Is this an intentional omission in Safari for privacy/security reasons? Are there specific requirements (e.g., HTTP headers, permissions policies) needed for Safari to expose topOrigin? Is there a known workaround to reliably obtain the top-level origin in cross-origin WebAuthn flows? System Info: Version 18.4 (20621.1.15.11.10) OS: Sequoia Version 18.4 (20621.1.15.11.10) Reproduction Steps: Parent page (https://parent.example.com) embeds an iframe (https://webauthn-rp.example.com). The iframe calls navigator.credentials.get() with a WebAuthn challenge. Safari returns clientDataJSON with crossOrigin: true but no topOrigin. Code Snippet (iframe): const credential = await navigator.credentials.get({ publicKey: { challenge: new Uint8Array(/* ... */), rpId: 'webauthn-rp.example.com', allowCredentials: [], hints: [], userVerification: "preferred", } }); console.log(JSON.parse(atob(credential.response.clientDataJSON))); Has anyone encountered this? Any insights would be greatly appreciated!
Topic: Safari & Web SubTopic: General
0
0
102
May ’25
Suggestions for OAuth2 in Swift
Hello! I have a few questions about integrating an OAuth2 API into my Swift application. I am using this API to access user data from the website (users will authenticate themselves within the app). I have seen other apps use this API in the way that I am describing it so I know that it is possible. However, I am not sure how to implement it. Are there any recommended ways to use an OAuth2 API in my application? The API that I am using does not specifically say that it supports PKCE. However, I have heard from some sources that it does. If it does not support PKCE, how do I still create a secure app infrastructure that will pass App Store Review? At a more basic level, what is the difference between OAuth2 and PKCE? What should I use in my app? Are there any resources to learn a little bit more about these protocols so that I understand them better? Thanks!
0
0
76
Jun ’25
DNR Redirect Rule Won’t Redirect to Extension Path
DNR rules redirecting to an extension path lead to an error page: “Safari can’t open the page. The error is: “The operation couldn’t be completed. (NSURLErrorDomain error -1008.)” (NSURLErrorDomain:-1,008).” Here is a demo extension that replicates the bug: https://github.com/lenacohen/Safari-Test-Extensions/tree/main/dnr-extension-path-redirect This is an example of a redirect rule that leads to an error page instead of the extension path page: chrome.declarativeNetRequest.updateDynamicRules({addRules: [ { id: 2, priority: 1, action: { type: "redirect", redirect: { extensionPath: "/web_accessible_resources/test_redirect.html" } }, condition: { urlFilter: "||washingtonpost.com^", resourceTypes: [ "main_frame" ] } } ]}); The extension path is included in web_accessible_resources in the extension manifest: "web_accessible_resources": [{ "resources": [ "web_accessible_resources/test_redirect.html" ], I also submitted a bug report on Apple's Feedback Assistant: FB16607632
0
1
531
Feb ’25
CSS not displaying when using WKURLSchemeHandler on iOS 17+ with Xcode 15.3+
I’m encountering an issue with CSS not displaying when using WKURLSchemeHandler to load local HTML files. When I package the app using Xcode 15.3 or above, the CSS styles do not display on iOS 17 or higher. However, on iOS 16.7.1, the CSS displays correctly. • If I use Xcode 15.2 to package the app, the CSS loads and displays correctly on all iOS versions. I am using WKURLSchemeHandler to intercept and load the local HTML files. Is there any known issue or workaround for this? You can now post this in the “Safari & Web” section of the Apple Developer forums for further assistance! // // CustomURLSchemeHandler.m // HTMLTest // // Created by lvxue on 2024/9/23. // // CustomURLSchemeHandler.m #import "CustomURLSchemeHandler.h" @implementation CustomURLSchemeHandler - (void)webView:(WKWebView *)webView startURLSchemeTask:(id<WKURLSchemeTask>)urlSchemeTask { NSURL *url = urlSchemeTask.request.URL; //NSString *filePath; NSString *filePath = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html" inDirectory:@"LoaclHtml.bundle/A4"]; if ([url.lastPathComponent hasSuffix:@".css"]) { filePath = [[NSBundle mainBundle] pathForResource:@"style" ofType:@"css" inDirectory:@"LoaclHtml.bundle/A4/css"]; } else if ([url.lastPathComponent hasSuffix:@".js"]) { filePath = [[NSBundle mainBundle] pathForResource:@"yourJSFileName" ofType:@"js" inDirectory:@"LoaclHtml.bundle/A4/js"]; } NSData *htmlData = [NSData dataWithContentsOfFile:filePath]; NSString *mimeType = [self mimeTypeForPath:filePath]; NSURLResponse *response = [[NSURLResponse alloc] initWithURL:url MIMEType:mimeType expectedContentLength:htmlData.length textEncodingName:@"utf-8"]; [urlSchemeTask didReceiveResponse:response]; [urlSchemeTask didReceiveData:htmlData]; [urlSchemeTask didFinish]; } - (void)webView:(WKWebView *)webView stopURLSchemeTask:(id<WKURLSchemeTask>)urlSchemeTask { } - (NSString *)mimeTypeForPath:(NSString *)path { NSString *fileExtension = [path pathExtension]; if ([fileExtension isEqualToString:@"html"]) { return @"text/html"; } else if ([fileExtension isEqualToString:@"css"]) { return @"text/css"; } else if ([fileExtension isEqualToString:@"js"]) { return @"application/javascript"; } else if ([fileExtension isEqualToString:@"png"]) { return @"image/png"; } else if ([fileExtension isEqualToString:@"jpg"] || [fileExtension isEqualToString:@"jpeg"]) { return @"image/jpeg"; } else if ([fileExtension isEqualToString:@"gif"]) { return @"image/gif"; } return @"application/octet-stream"; } @end code-block
Topic: Safari & Web SubTopic: General
0
1
189
Feb ’25
(iOS 26 / WebKit): Fixed-position header misaligned after keyboard interaction and interactive swipe-back in WKWebView
Steps to Reproduce 1. Create a native UIViewController with a WKWebView, loading test-1.html (contains position:fixed header that displays correctly). 2. Push another UIViewController also with a WKWebView, this time loading test-2.html. 3. In test-2.html, tap into the to summon the on-screen keyboard. 4. Without calling blur(), perform an interactive swipe-back gesture to go back to the first view controller. 5. Observe that the fixed header in test-1.html is now offset downward by approximately the height of the keyboard and does not return to its original position. demo-link : https://bugs.webkit.org/attachment.cgi?id=476324
Topic: Safari & Web SubTopic: General Tags:
0
3
470
Aug ’25
Detecting tabs change in Safari App Extension when switching windows inside validateToolbarItem.
Hi. I'm a developer of Tab Finder (https://apps.apple.com/us/app/tab-finder/id6741719894) My problem is that every time i switch from my first window to a second window, the tabs in the validateToolbarItem() are INcorrect on a first call, but when I switch back from the second window to my main window, the tabs are CORRECT even on a first call. To demonstrate it, i recorded a video: https://youtu.be/RwskzrSJ8u0 To run the same sample extension from the video, you can get the code from this GitHub repo: https://github.com/kopyl/test-tabs-change Its only purpose is to log URLs of an active page of all tabs. The SafariExtensionHandler's code of the sample app is very simple: import SafariServices func printOpenTabsHost(in window: SFSafariWindow) async { let tabs = await window.allTabs() log("Logging tabs for a new window: \(window.hashValue)") for tab in tabs { let page = await tab.activePage() let properties = await page?.properties() let url = properties?.url log(url?.absoluteString ?? "No URL") } } class SafariExtensionViewController: SFSafariExtensionViewController { static let shared = SafariExtensionViewController() } class SafariExtensionHandler: SFSafariExtensionHandler { override func validateToolbarItem(in window: SFSafariWindow, validationHandler: @escaping ((Bool, String) -> Void)) { Task { await printOpenTabsHost(in: window) } validationHandler(true, "") } override func popoverViewController() -> SFSafariExtensionViewController { return SafariExtensionViewController.shared } } Could you please tell if i'm missing something and how to see the actual tabs inside the overridden validateToolbarItem call of the SafariExtensionHandler (or in any other way, I'm okay with any implementation as long as it works).
0
0
403
Mar ’25
Inquiry Regarding Unsubscribe Flow for Recurring Payment Processing
We would like to confirm the unsubscribe flow related to recurring payment processing. When a user unsubscribes, does your system send any notification to us? If no notification is provided, we will not be able to detect the unsubscribe event and will continue to send recurring payment requests to the gateway periodically. Would this cause any issues? We would appreciate it if you could share the specific unsubscribe flow with us. Thank you in advance for your support.
0
0
59
Aug ’25
Redirect link open 2 links not only 1 link in IOS 18
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.
0
0
389
Mar ’25
Frontend Does Not Display Password Validation Error (e.g., “Password Cannot Contain Your Name”)
Description When creating an Apple ID via the web form, if the user’s chosen password contains their own name, the server correctly returns an error (e.g., "Password cannot contain your name") in the PUT request's JSON response. However, this error is not shown on the frontend, leaving users unaware of why the form silently fails or stalls. Steps to Reproduce Go to the Apple ID account creation page (https://appleid.apple.com/account). Enter valid account details where the password includes the user's first or last name (e.g., Johnacb2331!l for a user named John Doe). Complete all fields, including phone number verification and captcha. Submit the form and monitor the Network tab in your browser’s DevTools. Observe that the form appears to hang, loop, or silently fail. Open the PUT request to /account — the response JSON will contain the relevant validation error (e.g., “Password cannot contain your name”), but the user is not shown this. Expected Behavior The password validation error (e.g., containing the user’s name) should be immediately displayed in the UI next to the password field to inform the user and allow for correction. Actual Behavior No error is shown in the UI. The form appears to fail silently, leaving the user confused. The actual reason for failure is only visible through browser developer tools in the PUT response payload. Impact This can lead to: User frustration and confusion Increased support overhead Poor UX in a critical flow (account creation) Environment Browser: chrome 136.0.7103.114 Platform: Web (https://appleid.apple.com) Date observed: 31/5/25 Suggested Fix Ensure that password validation messages from backend responses surface in the frontend, especially for common user input issues like including names in passwords. No screenshots as I can not create a new account
Topic: Safari & Web SubTopic: General
0
0
139
Jun ’25
Is the branded email feature available in France? What is the timeline?
Hello, I followed the instructions to set up a custom logo for our domain name Allogarage.fr, both for the brand and the domain. Everything appears to be correctly configured in Apple Business backend for several weeks now, but the logo still doesn’t show up in Mail. Is the branded email feature available in France? Are there any additional steps required?
0
0
117
Jun ’25
WebKit https post return html use javascript send WebSocket Request
In my application, I use HTML pages to display the interface. Since it’s a cross-platform app, the pages and interactions work properly on other platforms. However, in WebKit, because HTTPS protocol is used, JS requests from the page cannot use the ws protocol but must use the wss protocol under HTTPS. Is there any way to allow a webpage under HTTPS to use ws requests normally? Google Chrome can do this.
Topic: Safari & Web SubTopic: General
0
0
97
Jun ’25
WebKit's `decidePolicy` breaking change in iOS 18.5 + Xcode 16.4
It seems that in iOS 18.5+ built with Xcode 16.4+, there has been a breaking change since 18.4 with 16.3 within WebKit and how the navigationAction.sourceFrame property is initialized when implementing the decidePolicy delegate method. The flow goes: Implement a WKNavigationActionDelegate with decidePolicy Call WKWebView.loadHTMLString("some-string", baseURL: nil) Upon loading the HTML content, read the value of navigationAction.sourceFrame within the decidePolicy method of the WKNavigationActionDelegate On iOS 18.4 (and below) with Xcode 16.3 (and below); navigationAction.sourceFrame is <uninitialized> On iOS 18.5+ with Xcode 16.4+: navigationAction.sourceFrame is already initialized and is equal to navigationAction.targetFrame It appears that this change was made between minor versions of Xcode and is unexpected behavior of a minor version. Not only was this not called out in the release notes for Xcode 16.4 and iOS 18.5, but it's technically also a breaking change to the WebKit API. Can we get insight on why this change was made and what Apple's policy is on breaking changes between minor versions of Xcode/iOS?
Topic: Safari & Web SubTopic: General Tags:
0
1
309
Jul ’25
Cookie Missing After App Upgrade During OAuth Consent Flow on iOS (Safari ITP?)
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
0
0
62
3w
Follow-up: Programmatically detecting "Allow in Private Browsing" for Safari App Extensions
I am following up on Thread (https://developer.apple.com/forums/thread/733233). Currently, SFSafariExtensionManager.getStateOfSafariExtension only returns if an extension is enabled, but not if "Allow in Private Browsing" is toggled on. Is there an API in macOS 26 and Safari 19 that allows a native Safari App Extension to detect this specific permission?
0
0
621
Jan ’26