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

Memory leak in WebKit caused by KVO and @StateObject
Hi! My SwiftUI app is a rather complex browser app. Starting with iOS 18, the app crashes due to repeted reloads of the WkWebView. I’ve tracked the issue as far as I can, but I still haven’t found the root cause. My app is structured like this: MainView holds a cuple of subviews. It also holds a @StateObject called viewModel that holds a lot of @Published vars. The viewModel is passed as a enivormentObject. Example from ViewModel: @MainActor class ViewModel: NSObject, ObservableObject { @Published public var isLoading: Bool = false @Published public var loadProgress: Double? = 0 public func setIsLoading(_ value: Bool) async { self.isLoading = value } public func setLoadProgress(_ value: Double?) async { self.loadProgress = value } } WebView is a subview of MainView, which holds a navigation bar, and a UIViewRepresentable, which is a WkWebView. The WkWebView pushes some states to the ViewModel as the underlying values of the WkWebView changes, i.e. estimaedProgress, and isLoading. This is done via KVO and works like this: estimatedProgressObservation = self.parent.webView.observe(\.estimatedProgress) { webView, progress in Task { await parent.viewModel.setLoadProgress(webView.estimatedProgress) } } isLoadingObservation = self.parent.webView.observe(\.isLoading) { webView, value in Task { await parent.viewModel.setIsLoading(webView.isLoading) } } By using a timer in WkWebViews Coordinator, i trigger a load after a configurable amount of time :
 func loadUrl(url: URL) { DispatchQueue.main.async { console.info("Load URL: ...", sensitive: "Load URL: \(url.absoluteString)") let policy: NSURLRequest.CachePolicy if self.parent.settings.noCache { policy = .reloadIgnoringLocalAndRemoteCacheData } else { policy = .useProtocolCachePolicy } let request = URLRequest(url: url, cachePolicy: policy) self.parent.webView.load(request) } } Running the app with the automatic reload enabled freezes the app after a couple of hours. It also seems to freeze Safari on the device. The device needs to be rebooted. If I inspect the device's running processes, hundreds of ”com.apple.webkit. web content " processes are running. Removing await parent.viewModel.setLoadProgress(webView.estimatedProgress) and await parent.viewModel.setIsLoading(webView.isLoading) fixes the issue, but it is necessary for other app functions. Therefore, is suspect that the viewModel somehow causes the bug. The issue arises after a couple of loads 5-10. The debugger shows a message when the processes start to pile up. I suspect its related. Failed to terminate process: Error Domain=com.apple.extensionKit.errorDomain Code=18 "(null)" UserInfo={NSUnderlyingError=0x12d0e7f60 {Error Domain=RBSServiceErrorDomain Code=1 "Client not entitled" UserInfo={RBSEntitlement=com.apple.runningboard.terminateprocess, NSLocalizedFailureReason=Client not entitled, RBSPermanent=true}}} How can I find out what causes the suspected memory leak? Instruments gives me nothing of value. The memory leak wasn't present in iOS 17. Is this a bug in iOS 18, or was something intentionally changed?
0
0
477
Mar ’25
macOS customized shortcut for Safari with menu title "ReTab" doesn't trigger the extension
Hello! I've made a Safari extension that supports command "ReTab", and a couple of month ago, adding a customized macOS shortcut for Safari with menu title "ReTab" did trigger the extension. However, it's not working anymore and I'm not sure if it's from macOS/Safari update or because I changed manifest from v2 to v3 - could you help check if there's anything wrong with either the manifest.json or background.js? (the default Cmd+E still works) Thank you in advance! Xun manifest.json: { "manifest_version": 3, "default_locale": "en", "name": "ReTab", "description": "Go to the last active tab with Cmd+E!", "version": "1.4", "homepage_url": "https://LycheeIsle.com", "background": { "service_worker": "background.js" }, "action": { "default_icon": "images/toolbar-icon.svg" }, "permissions": [ "commands", "tabs", "storage" ], "commands": { "ReTab": { "suggested_key": { "default": "Command+E" }, "description": "Go to the last active tab" } }, "options_page": "options.html" } in background.js, I have this line which should listen to the command, and Cmd+E works but any customized shortcut for "ReTab" in Safari doesn't: browser.commands.onCommand.addListener(async (command) => { if (command === "ReTab" || command === "retab") { await retab() } });
1
0
364
Feb ’25
iOS 18.3.x no longer accepts self singed certificates
We have an app store app that hosts an internal webserver we use as a proxy and it works for a period until iOS 18.3.x decides our cert is no longer valid at which point our customer have reinstall the app. This has only become a problem on iOS18.3. We publish the self-signed with out app, and it is valid and accepted until it's not. We know the cert is valid and our implementation of the local proxy has not changed. If we install a cert on the device and trust it, then the app will start behaving normally again without reinstall. We have replicated this locally and the error we are seeing is: Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _WKRecoveryAttempterErrorKey=<WKReloadFrameErrorRecoveryAttempter: 0x301111e40>, networkTaskDescription=LocalDataTask <541390E2-65FA-47AB-80B1-10209D6C761A>.<3>, _kCFStreamErrorDomainKey=3, NSErrorPeerCertificateChainKey=( "<cert(0x108e3b700) s: 127.0.0.1 i: 127.0.0.1>", "<cert(0x108e3b980) s: 127.0.0.1 i: 127.0.0.1>" ), NSErrorClientCertificateStateKey=0, NSErrorFailingURLKey=https://localhost:8082/Blablal/?device=ios&sftouch=1&pgport=8081&secure=1, NSErrorFailingURLStringKey=https://localhost:8082/blahblah/?device=ios&sftouch=1&pgport=8081&secure=1, NSUnderlyingError=0x301e1d680 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802}}, _NSURLErrorRelatedURLSessionTaskErrorKey=( "LocalDataTask <541390E2-65FA-47AB-80B1-10209D6C761A>.<3>" ), _kCFStreamErrorCodeKey=-9802, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <541390E2-65FA-47AB-80B1-10209D6C761A>.<3>, networkTaskMetricsPrivacyStance=NotEligible, NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x302670a50>, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made.}
Topic: Safari & Web SubTopic: General Tags:
0
0
622
Feb ’25
File Downloading Problems
Hi, I'm here to Report a Problem with the IOS 18.3 UPDATE. So, when i Download a file, any file. The Download Progress has no problems, but when the download complete, Nothing happens it just keeps the blue line of the download, and then I can’t open that file…this only happened to me when i downloaded the IOS 18.3… hope it'll be fixed ASAP. Bye!
Topic: Safari & Web SubTopic: General Tags:
1
0
465
Mar ’25
Custom WkWebsiteDatastore
Hey team, I've integrated custom WkWebsiteDatastore to manage profiling for different sessions. upon testing the WkWebsiteDataStore as its mentioned to be persistent But The storage can be accessed via identifier, But the session data in storage is absent, such as cookies caches all are cleared when app is relaunched is it the default behavior to be expected or there is some property missing causing the session data to be removed from storage.
Topic: Safari & Web SubTopic: General Tags:
0
0
61
Mar ’25
Your browser preventing this app to open “URL”
Hi Apple developers, I am very new to XCode and Swift, I am planning to build an app for iOS from a web. I tried to use WKWebView to handle the web , I managed to redirect some of the links to Safari, however some button/links didn't trigger .linkActivated function and encounter the error as "Your browser preventing this app to open “URL”. If I copy the URL to Safari is able to open, I trying to research on web but can't find any related solution for my case. Here is the code in my app: import UIKit import WebKit import SafariServices class ViewController: UIViewController, WKNavigationDelegate { var webView: WKWebView! override func viewDidLoad() { super.viewDidLoad() // Initialize WKWebView let webConfiguration = WKWebViewConfiguration() //enable javascript webConfiguration.preferences.javaScriptEnabled = true webView = WKWebView(frame: self.view.frame, configuration: webConfiguration) webView.navigationDelegate = self self.view.addSubview(webView) // Load a web page as webview if let url = URL(string: "https://myurl") { let request = URLRequest(url: url) webView.load(request) } //console log webView.evaluateJavaScript("console.log('Button clicked!')") { result, error in if let error = error { print("Error executing JavaScript: \(error.localizedDescription)") } else { print("JavaScript result: \(String(describing: result))") } } } func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { if let url = navigationAction.request.url, navigationAction.navigationType == .linkActivated { // Check if URL is external and open it in Safari if UIApplication.shared.canOpenURL(url) { UIApplication.shared.open(url, options: [:], completionHandler: nil) decisionHandler(.cancel) // Prevent loading the link in the WebView } else { decisionHandler(.allow) // Allow loading if URL cannot be opened in Safari } } else { decisionHandler(.allow) // Allow the WebView to load the URL normally } } }
1
0
760
Jan ’25
Safari doesn't seem to respect cache-control on fetch redirects
I am calling fetch with a POST on page1 in Safari. No special cache parameters on the fetch call. The response from the server is a 303 redirect to page2 The second page -- page2 -- is in my browser's cache with cache-control "public, max-age=31536000, immutable". For some reason, the page2 redirect is causing a server hit to re-GET the second page every time instead of pulling from cache. If I instead directly get the second page by doing a fetch on page2, there is no server hit. If I do this on Chrome or Firefox, it behaves as I would expect, pulling page2 from the cache with no server hit. In case it matters, the fetch is coming from within an iFrame. Also, if I change the original POST to a GET, the problem still happens. I am using a pretty old version of Safari on my Mac, so I could chalk it up to that, but I am getting the same behavior with Safari on my iPhone with iOS 18.3.2 Any ideas? Thanks.
Topic: Safari & Web SubTopic: General Tags:
0
0
57
Mar ’25
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
583
Feb ’25
Safari Web Extension service_worker failed to load
I built and extension for chrome, edge, and firefox. I'm porting the chrome extension to safari using the safari-web-extension-converter tool. This has worked successfully and I was able to publish my extension to the app store. I made some updates to the service worker code recently and I'm now being hit with an error when trying to load my unsigned extension into safari: The service_worker script failed to load due to an error. I've looked online at some other forums and haven't found anything helpful around how to debug this kind of error. Because the service worker is non-persistent in safari, I don't have access to the console logs of the service worker through the Develop > Web Extension Background Context menu. Has anyone successfully debugged this kind of error? Are there logs I can pull directly from safari that would help me here? Thanks in advance for the help!
0
0
299
Feb ’25
Safari Web Extension: How do I avoid "this extension can read and alter web pages"?
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?
2
0
737
Mar ’25
Prevent collapsing every tab group when collapsing sidebar
I'm not sure if this is even the right place to ask this, or voice this complaint if there's no fix. If not, please direct me where to go. I'm trying to switch all my development over to Safari, but the tab sidebar is driving me absolutely insane. Let's say I have a bunch of tab groups expanded, and I collapse the sidebar to focus on the webapp I am building. When I toggle to show the sidebar again, every single tab group is collapsed. Why is it 2 clicks to see the tabs in the sidebar? Even with zero tab groups, and just tabs in the workspace, if you collapse the sidebar it'll collapse the list of tabs. Is there some hidden setting for this? Who do we have to complain to?
Topic: Safari & Web SubTopic: General
0
0
201
Feb ’25
Can I use allowFileAccessFromFileURLs to access local html file in my Project and not get appStorereview
We are currently implementing the payment flow, and for handling payment details — including card entry and validation — we are utilizing a WKWebView. The webview securely loads the payment provider’s page, ensuring sensitive information such as card numbers are entered and validated directly within the web context. I’d like to clarify that this change has not yet been released to Production. As part of a feature enhancement to our existing payment flow, we are transitioning to a new payment vendor, SnapPay. While trying to load the SnapPay URL embedded within an iFrame in our iOS app, I observed the following error in the Xcode console. While this error may be generic, I wanted to highlight it: 825a18 - [pageProxyID=7, webPageID=8, PID=67346] WebPageProxy::didFailLoadForFrame: frameID=24, isMainFrame=0, domain=NSURLErrorDomain, code=-999 Upon investigating, we compared the headers from our existing payment URL and SnapPay's URL, and found that SnapPay includes the following Content-Security-Policy (CSP) header: Content-Security-Policy: frame-ancestors ... "Content-Security-Policy" value="default-src 'self'; script-src 'self' https://hcaptcha.com https://.hcaptcha.com https://code.jquery.com https://www.gstatic.com https://code.jquery.com/jquery-3.3.1.min.js https://test.lightbox.cardx.com/v1/lightbox.min.js https://www.ssa.gov/accessibility/andi/ https://c.evidon.com 'unsafe-inline' 'unsafe-eval'; style-src 'self' https://hcaptcha.com https://.hcaptcha.com https://fonts.googleapis.com/css https://stage.snappayglobal.com/Resource/ https://www.ssa.gov/accessibility/andi/andi.css 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' *.googleapis.com *.gstatic.com ; connect-src 'self' https://demo1.cditechnology.com https:; form-action https://hcaptcha.com https: 'self' *.ipg-online.com secure.bluepay.com https://test.api.lightbox.cardx.com https://3ds-acs.test.modirum.com/ https://demo1.cditechnology.com/; frame-ancestors https://snappaydirect-perf.fiserv.com 'self' file: https: http; frame-src .snappayglobal.com 'self' https://hcaptcha.com https://.hcaptcha.com https: https://www.google.com .ipg-online.com secure.bluepay.com https://.cardconnect.com https://test.api.lightbox.cardx.com/ https://test.lightbox.cardx.com https://paywithcardx.com/payment/auth.cgi securepayments.cardpointe.com *.cardpointe.com https://3ds-acs.test.modirum.com/ https://www.yokohamatire.com http://uat1-txt.ad.portal.texas.gov https://uat1-txt.ad.portal.texas.gov " After multiple working sessions with the SnapPay team, we were able to confirm that when they disable CSP or remove the frame-ancestors directive, the iFrame loads successfully within our app. However, SnapPay cannot change on their CSP. To enable the iFrame to load in the iOS app, we added the following line of code: webView.configuration.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs"). This resolved the issue with loading the iFrame. Note: the file being loaded is a local .html file,. Before submitting this update to the App Store, I’d like to confirm whether this usage of allowFileAccessFromFileURLs is acceptable for App Store review. I wanted to confirm that with this change is there a security concern for WKWebview?
0
0
130
Apr ’25
iOS 18.3 beta meet CannotConnectToHost - 1004
Recently, our some customers feedback that their phones can not connect to our site by safari or App, show the error of “Cannot Connect to Host -1004”,all of these problem customers has installed iOS 18.3 beta. Is there anybody meet the same problem?
Topic: Safari & Web SubTopic: General
0
0
294
Jan ’25
How do I add a UI to a Safari Web Extension?
I have a Safari Web Extension that successfully receives a message from a webpage and returns a response. I now want to add a user interface to the Safari Web Extension. How do I do this? I have modified the default template code as follow to add an NSAlert for testing. The modal runs, but no alert ever appears, and the code remains stuck at runModal. What is the correct way to add a UI to a webextension? - (void)beginRequestWithExtensionContext:(NSExtensionContext *)context {     id message = [context.inputItems.firstObject userInfo][SFExtensionMessageKey];     NSLog(@"Received message from browser.runtime.sendNativeMessage: %@", message);     NSAlert* alert = [[NSAlert alloc]init];     [alert setMessageText:message[@"request"]];     [alert setInformativeText:@"Hello"];     [alert runModal];     NSExtensionItem *response = [[NSExtensionItem alloc] init];     response.userInfo = @{ SFExtensionMessageKey: @{ @"id": message[@"id"], @"uuid": message[@"uuid"], @"contentType": message[@"contentType"], @"response": message[@"request"] } };     [context completeRequestReturningItems:@[ response ] completionHandler:nil]; } @end
3
0
1.2k
Mar ’25
Safari Extension: Cookie Header Missing in Background Fetch from Non-Default User Profile (Works in Default Profile)
When our Safari Web Extension makes a api request from its background script (registered via "scripts" in manifest.json, e.g., "background": { "scripts": ["js/background.bundle.js"] }) to our authenticated API endpoint (https://api-domain/user), the Cookie header is not included in the request. This occurs only when the extension is running within a non-default Safari User Profile. This causes our API to treat the user as unauthenticated. The exact same extension code, manifest, and API call work correctly (Cookie header is present and user is authenticated) when the extension is running in the Default Safari User Profile.
0
0
153
May ’25
Push subscribe error User denied push permission
Hi, I am developing the Click & Read web add-on for Chromium, Firefox and Safari. We use xcrun safari-web-extension-converter tool to generate the Safari add-on, with up-to-date MacBook MacOS, Xcode et Safari : Sequoia 15.3.2, Safari Version 18.3.1 (20620.2.4.11.6), XCode Version 16.0 (16A242d). We have updated our addon to Manifest v3, having the Background script as Server Worker "background": { "service_worker": "background.js", "type": "module" } self.addEventListener("activate", (event) => { console.info("Service Worker activated", event); event.waitUntil( self.registration.pushManager .subscribe({ userVisibleOnly: true, applicationServerKey: urlBase64ToUint8Array( process.env.VAPID_PUBLIC_KEY ), }) .then(async (subscription) => { console.info("[Service Worker] Extension is subscribed to push"); const { subscription: savedSubscription } = await getLocalStorageKeyData("subscription"); if (savedSubscription) fetchApi({ url: `${API_SERVER_URL}/subscription/remove/${savedSubscription.keys.auth}`, }); // Remove previous subscription from server on addon activate currentBrowser.storage.local.set({ subscription: subscription.toJSON(), }); // Save subscription in local storage currentBrowser.runtime.setUninstallURL( `${API_SERVER_URL}/subscription/remove/${ subscription.toJSON().keys.auth }` ); // Set uninstall URL to remove notification subscription on addon uninstall fetchApi({ url: `${API_SERVER_URL}/subscription`, reqInit: { body: JSON.stringify(subscription.toJSON()), method: "POST", headers: { "Content-Type": "application/json", }, }, }); }) .catch((error) => { console.error("Push subscribe error: ", error); }) // Subscribe to push notifications ); }); When trying to subscribe the addon instance to our Push server, we get this error : Push subscribe error: NotAllowedError: User denied push permission Our NodeJS backend is using the web-push librabry : https://github.com/web-push-libs/web-push) to save subscriptions and make notifications push. By looking for same errors on forums, the best hint I found is that it could be related to the testing is done on localhost (addon is built from XCode onto Safari, and Push server is running on localhost). Thanks for your help !
1
0
363
Mar ’25