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

iOS
Hi i Need help, my phone keeps getting all these updates and rapid security features on it at first I thought it was just the normal updates but i started to pay more attention and it's not. i have the beta updates on my phone iPad and Apple Watch but when I go in to see if it in my updates like apple said to do it wasn't in there. Also all my apps are developer apps I'm not able to get normal ones and if I can the next time I go on it it's not how it was. I really don't know what to do, I've gotten 2 new phones because I thought it was just bad software but I researched a lot and I think someone it hacking me. everytime I look something up on safari it takes me to a whole other website or its completly altered and doesnt look like it usually does. Someone please help me lmao I actually think I'm going to lose my mind.
Topic: Safari & Web SubTopic: General
1
0
308
Mar ’25
Safari Web Extension - storage.session not available on iPad v16.3
I'm creating a Safari Web Extension, which successfully uses storage.local and storage.session on MacOS (14.x/15.x) and iOS (15.x,18.x). However, when testing on an iPad running iPadOS 16.3, it fails with an undefined error: TypeError: undefined is not an object (evaluating 'api.storage.session.get') Dropping to the console, I can access 'api.storage.local', but no luck for 'api.storage.session'. First question, why would storage.session not be available? Is there something different on this iPadOS version to enable it? I could just use local storage, but don't need the data to persist. I'll probably just fall back to this solution. Second question, should I instead be using localStorage and sessionStorage? I can't find any helpful direction on if using localStorage vs storage.local is best practice?
1
0
354
Mar ’25
Strange reload behavior, WKWebView reloads with returnCacheDataElseLoad after background
Hi, in our app we have a WKWebView with complex web content that is loaded with cachePolicy: .reloadIgnoringLocalCacheData. If the app is in the background for several hours and returns in the foreground we noticed that the system reloads the webpage, but it does so with a cachePoliy returnCacheDataElseLoad. This could break the app if older cache content is present. To reproduce start an app in the simulator (tested with iOS 17.2), put it in the background and via activity monitor stop the processes com.apple.Webkit.WebContent com.apple.Webkit.networking After foreground the reload will happen. Two questions: why is this reload happening after some hours in the background? We haven't seen any crash reports related to this. It mostly happens on one of our test devices (iphone13 with iOS17.2.1). why is the webview reloading with a modified cachePolicy (returnCacheDataElseLoad)? Our temporary fix is to detect this case in "webView:decidePolicyFor navigationAction decisionHandler", cancel the request and reload with modified cachePolicy. Any ideas? Thanks, Heiko Sample code: class ViewController: UIViewController, WKNavigationDelegate, WKUIDelegate { var webView: WKWebView! override func viewDidLoad() { super.viewDidLoad() let config = WKWebViewConfiguration() webView = WKWebView(frame: .zero, configuration: config) webView.uiDelegate = self webView.navigationDelegate = self view.addSubview(webView) let myRequest = URLRequest(url: URL(string: "https://www.apple.com")!, cachePolicy: .reloadIgnoringLocalCacheData) print("request \(myRequest)") webView.load(myRequest) } func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { print("start loading \(String(describing: navigationAction.request.url)), cache:\(navigationAction.request.cachePolicy)") decisionHandler(.allow) } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() let fullscreen = CGRect.init(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height) webView.frame = fullscreen } }
Topic: Safari & Web SubTopic: General Tags:
3
1
1.7k
Mar ’25
Opening native app from a web extension
Is it possible to open the native app from a web extension? I have tried creating a new tab that uses the app's URL scheme but the UI asking the user to open the app is not shown until the new page UI is dismissed. Creating a tab with an HTTPS URL that the app is setup to handle does not work and always the link in a new tab. I tried sending a message to the app extension and using NSExtensionContext.open(_:completionHandler:) but the URL is not opened and the closure received false, indicating it was not handled. Having the option to link back to the native app would be very useful.
3
0
1.8k
Mar ’25
Redirecting to an app's universal link from and app extension popup
I have a simple Safari extension for iOS. In its popup, I want a button that will open the app via a universal link. I have this kind-of working, except that Safari opens the actual online destination of the link with a banner at the top saying "Open in the XXXX app" and an OPEN button. What do I have to do to go directly to the app? More generally, I know that if I copy-and-paste a universal link into the Safari address bar, Safari does the same thing - but it does go directly to the app from an <a href="...."> link. In my app extension JavaScript, I set window.location. Presumably this is too similar to pasting into the address bar. Is there some alternative to setting window.location that is more like clicking on a link and will go directly to the universal link's app? Thanks.
5
0
1.2k
Mar ’25
Add Authorization header to WKWebView
How can i add Authorization header to a wkwebview. I checked https://developer.apple.com/documentation/foundation/nsurlrequest#1776617 which says Authorization header is a reserved http header and shouldn’t be set. I want to set it when requesting a url in wkwebview for authentication purpose?
Topic: Safari & Web SubTopic: General Tags:
2
0
370
Mar ’25
WKWebView occasionally shows white screen and persists until app restart
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.
4
0
1.7k
Mar ’25
PointerEvents on Safari on iPad with Apple Pencil Pro
Hi, I would like to share a finding and ask for a solution, if possible. This may be a potential bug with PointerMoveEvent on Safari on an iPad with Pencil Pro. I tested onPointerMove and onTouchMove in a <canvas> element in a React web app for freehand drawing using Mouse on a PC. Finger touch on iPad Apple pencil pro on iPad Finger touch on iPhone I was able to draw smooth curves in all cases except when using onPointerMove with Apple pencil pro on iPad. The curve drawn in this case looked like it was created using several straight-line segments. It seems like the sampling rate for PointerMoveEvent is lower than that of TouchMoveEvent on Safari I am not sure how to solve this problem or if it is an issue with Safari's interpretation of PointerEvents. Any input is greatly appreciated. Edit: It seems like https://developer.apple.com/forums/thread/689375 is related.
0
0
269
Mar ’25
PRF Extension Not Supported in Safari's Cross-Device WebAuthn Flow
Safari 18.0.1 on macOS 15.01 doesn't support the Passkey PRF extension during cross-device WebAuthn authentication when using QR code scanning, while it works correctly with iCloud passkeys. Steps to Reproduce: Clone and setup: git clone https://github.com/quocle108/passkey-prf-test yarn yarn start Test iCloud Passkey Flow: Open http://localhost:3000 in Safari Open DevTools (Cmd+Option+I) Click "Register" Choose "Passkey on iCloud" Expected console output: PRF supported: true Test Cross-Device Flow: Click "Register" Choose "Phone/Tablet" Scan QR with mobile device Expected: PRF supported: true PRF extension should be supported in cross-device flow, matching iCloud passkey behavior. Actual: PRF supported: false Cross-device flow returns empty extension results. Verify in Chrome Repeat steps 2-3 in Chrome Both flows return proper PRF extension results: PRF supported: true Test Environment: Browser: Safari 18.1.1 , Chrome 131.0.6778.70 OS: macOS 15.01 Mobile: iOS 18.x / Galaxy Note9 Android 10 Test repo: https://github.com/quocle108/passkey-prf-test
4
1
528
Mar ’25
fetch() in safari extension does not include credentials (cookie) when using from non-default profile
It seems fetch() does not include credentials (cookie) even when credentials: include is used and Safari extension has host_permissions for that domain when using from a non-default Safari profile. It includes credentials (cookie) when using from the default profile (which has the default name Personal). Is there anyone who 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 credentials (cookie) from host_permissions. I already posted https://developer.apple.com/forums/thread/764279, and opened feedback assistant (FB15307169). But it is still not fixed yet. (macOS 15.4 beta 3) I hope this is fixed soon.
0
1
329
Mar ’25
WKWebView based Browser Yubikey&WebAuthn Support
TLDR: I’m searching for a possibility to allow the usage of passkeys and hardware keys for any website in a wkwebview INFO: The browser is macOS ONLY Hi, I couldn’t really find documentation or forums posts on how to implement Webauthn for signin or hardware security keys for a second factor. Or rather where those events are triggered to be handled. In Safari you have that popover, that lets you either authenticate through Passwords or with a security key. When I visit webauthn.io for testing and click either register or authenticate I get Told not to present authorization sheet: Error Domain=com.apple.AuthenticationServicesCore.AuthorizationError Code=1 "(null)" ASAuthorizationController credential request failed with error: Error Domain=com.apple.AuthenticationServices.AuthorizationError Code=1004 "(null)" If I add func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping @MainActor (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) and func webView(_ webView: WKWebView, authenticationChallenge challenge: URLAuthenticationChallenge, shouldAllowDeprecatedTLS decisionHandler: @escaping @MainActor (Bool) -> Void) it doesn’t seem to change anything. I found something about the ASWebAuthenticationSessionWebBrowserSupported entitlement, but by my understanding this is used so a browser can get opened upon some other app calling a ASWebAuthenticationSession. Has anyone some guidance for me? I feel like webauthn and yubikey support are important security measures for our users. https://codeberg.org/miakoring/Amethyst/src/branch/main/Amethyst/Shared/ViewComponents/WebKit/WebViewModel.swift is the code for my webviewmodel. Delegates are in the Delecate folder https://codeberg.org/miakoring/Amethyst/src/branch/main/Amethyst/Shared/ViewComponents/WebKit
Topic: Safari & Web SubTopic: General Tags:
2
0
550
Mar ’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
358
Mar ’25
iOS Mobile Video Audio Playback Issues in React
I'm experiencing issues with audio playback in my React video player component specifically on iOS mobile devices (iPhone/iPad). Even after implementing several recommended solutions, including Apple's own guidelines, the audio still isn't working properly on iOS Safari. It works completely fine on Android. On iOS, I ensured the video doesn't autoplay (it requires user interaction). Here are all the details: Environment iOS Safari (latest version) React 18 TypeScript Video files: MP4 with AAC audio codec Current Implementation const VideoPlayer: React.FC<VideoPlayerProps> = ({ src, autoplay = true, }) => { const videoRef = useRef<HTMLVideoElement>(null); const isIOSDevice = isIOS(); // Custom iOS detection const [touchStartY, setTouchStartY] = useState<number | null>(null); const [touchStartTime, setTouchStartTime] = useState<number | null>(null); // Handle touch start event for gesture detection const handleTouchStart = (e: React.TouchEvent) => { setTouchStartY(e.touches[0].clientY); setTouchStartTime(Date.now()); }; // Handle touch end event with gesture validation const handleTouchEnd = (e: React.TouchEvent) => { if (touchStartY === null || touchStartTime === null) return; const touchEndY = e.changedTouches[0].clientY; const touchEndTime = Date.now(); // Validate if it's a legitimate tap (not a scroll) const verticalDistance = Math.abs(touchEndY - touchStartY); const touchDuration = touchEndTime - touchStartTime; // Only trigger for quick taps (< 200ms) with minimal vertical movement if (touchDuration < 200 && verticalDistance < 10) { handleVideoInteraction(e); } setTouchStartY(null); setTouchStartTime(null); }; // Simplified video interaction handler following Apple's guidelines const handleVideoInteraction = (e: React.MouseEvent | React.TouchEvent) => { console.log('Video interaction detected:', { type: e.type, timestamp: new Date().toISOString() }); // Ensure keyboard is dismissed (iOS requirement) if (document.activeElement instanceof HTMLElement) { document.activeElement.blur(); } e.stopPropagation(); const video = videoRef.current; if (!video || !video.paused) return; // Attempt playback in response to user gesture video.play().catch(err => console.error('Error playing video:', err)); }; // Effect to handle video source and initial state useEffect(() => { console.log('VideoPlayer props:', { src, loadingState }); setError(null); setLoadingState('initial'); setShowPlayButton(false); // Never show custom play button on iOS if (videoRef.current) { // Set crossOrigin attribute for CORS videoRef.current.crossOrigin = "anonymous"; if (autoplay && !hasPlayed && !isIOSDevice) { // Only autoplay on non-iOS devices dismissKeyboard(); setHasPlayed(true); } } }, [src, autoplay, hasPlayed, isIOSDevice]); return ( <Paper shadow="sm" radius="md" withBorder onClick={handleVideoInteraction} onTouchStart={handleTouchStart} onTouchEnd={handleTouchEnd} > <video ref={videoRef} autoPlay={!isIOSDevice && autoplay} playsInline controls crossOrigin="anonymous" preload="auto" onLoadedData={handleLoadedData} onLoadedMetadata={handleMetadataLoaded} onEnded={handleVideoEnd} onError={handleError} onPlay={dismissKeyboard} onClick={handleVideoInteraction} onTouchStart={handleTouchStart} onTouchEnd={handleTouchEnd} {...(!isFirefoxBrowser && { "x-webkit-airplay": "allow", "x-webkit-playsinline": true, "webkit-playsinline": true })} > <source src={videoSrc} type="video/mp4" /> </video> </Paper> ); }; Apple's Guidelines Implementation Removed custom play controls on iOS Using native video controls for user interaction Ensuring audio playback is triggered by user gesture Following Apple's audio session guidelines Properly handling the canplaythrough event Current Behavior Video plays but without sound on iOS mobile Mute/unmute button in native video controls doesn't work Audio works fine on desktop browsers and Android devices Videos are confirmed to have AAC audio codec No console errors related to audio playback User interaction doesn't trigger audio as expected Questions Are there any additional iOS-specific requirements I'm missing? Could this be related to iOS audio session handling? Are there known issues with React's handling of video elements on iOS? Should I be implementing additional audio context initialization? Any insights or suggestions would be greatly appreciated!
0
0
390
Mar ’25
Safari extension without native code
I have a simple Safari extension which contains only Javascript and no native code. Currently I have the placeholder SafariWebExtensionHandler.swift that Xcode created when I added the extension. It's not doing anything useful, but simply deleting it doesn't seem to work. Can I have an extension that includes no native code?
2
0
304
Mar ’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
725
Mar ’25
com.apple.developer.web-browser
When I open com. apple. developer. web browser, I am unable to inject JavaScript into the webview through methods such as addUserScript. The console will prompt 'ignoring user script injection for non app bound domain'
Topic: Safari & Web SubTopic: General Tags:
0
1
183
Mar ’25
Mailto href is not working in iOS 18.3.2
Hi Team, I'm using the simple mailto functionality in the demo page and when I tested the same via Safari mailto functionality is not working. However, the same feature is working as expected via Chrome. Demo: https://jsfiddle.net/xut0ed4y/ Kindly help.me to resolve this issue.
Topic: Safari & Web SubTopic: General Tags:
0
0
269
Mar ’25
Declarative Web Push
Anybody succeeded sending a Web Push Message using the new Declarative approach introduced with Safari Version 18.4 (20621.1.14.11.3)? I will help as well if someone can point me to a solution debugging the entire system using Xcode and Minibrowser? Currently I can't get the MiniBrowser connected to the WebPush Daemon.
0
0
219
Mar ’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
200
Mar ’25