Post

Replies

Boosts

Views

Activity

Detect whether the user is using Safari or Safari Technology Preview?
Hi, I’m trying to detect whether my Safari Web Extension is running in Safari or Safari Technology Preview. Is there a reliable way to do that? I can get the executable path of the parent process using proc_pidpath(). However, unlike Chrome or Firefox, Safari extensions run under /sbin/launchd as the parent process, not the responsible process (browser’s binary). In this scenario, I need the executable path of the actual browser process, but I haven’t found a way to get it. Also, Safari doesn’t implement the Web Extension API’s browser.runtime.getBrowserInfo(), unlike Firefox. I haven’t tested it yet, but I’m considering checking the user agent string, though I’m not sure how reliable that would be. Use Case Some users use my Safari extension as a web development tool and want to enable some features exclusively in Safari Technology Preview, while using other features only in standard Safari. If I could detect which browser is in use, I could provide the appropriate functionality for them.
0
0
396
Jul ’25
Details of SFExtensionProfileKey?
Hi, I’m working with the SFExtensionProfileKey in my Safari Web Extension. As I understand it, this key is to get the UUID of the profile currently in use. However, it seems to be missing (no key in userInfo) when the default profile is active. Also, I haven’t found any API to get a profile’s human-readable name or list all available profiles. Could someone clarify: If the value of SFExtensionProfileKey is absent, can I safely assume the default profile is in use? Is there a supported way to get a profile’s display name? Does Safari expose an API for getting all profiles? Thanks in advance for your insights!
0
0
82
May ’25
App Store Guidelines: auto-renewable subscription offer code as non-consumable alternative?
Hi, My app currently offers a non-consumable in-app purchase to unlock all its features, and I would like to provide this full access for free to an organization with a few thousand Macs. Since Apple limits non-consumable in-app purchase promo codes to 1000 per app, this isn't sufficient for the organization's size. So I'm considering an alternative approach using an auto-renewable annual subscription with offer codes: Create a few thousand offer codes for an annual subscription. Users within the organization would redeem these codes. Instruct users to immediately unsubscribe after redeeming the code. The app would then check the in-app purchase receipt. If the receipt contains a transaction redeemed with an offer code, the app would treat this as a permanent unlock of all features. My concern is that repurposing an auto-renewable subscription in this manner—effectively turning it into a lifetime unlock triggered by redeeming an offer code and immediately cancelling—might violate App Store guidelines. Is using an annual subscription and offer codes this way likely to be compliant with App Store guidelines? Thank you for your guidance!
0
0
50
Apr ’25
Animated scale effect causes NSCursor to reset in SwiftUI macOS app
For my macOS app, I'm trying to change the mouse cursor to a pointing hand while hovering over a specific view. However, when the view is scaled with an animation triggered by hovering (using .scaleEffect() and .animation()), the cursor doesn't change as expected. Is there any workaround to fix this? This is a sample code: struct ContentView: View { @State private var hovering = false var body: some View { VStack { Text("Hover me") .padding() .background(hovering ? Color.blue : Color.gray) .scaleEffect(hovering ? 1.2 : 1.0) .animation(.linear(duration: 0.2), value: hovering) .onHover { hovering in self.hovering = hovering if hovering { NSCursor.pointingHand.push() } else { NSCursor.pop() } } } .frame(width: 200, height: 200) } } This is how it works: As you can see, when the pointer enters the view, the cursor changes momentarily before reverting back to the arrow icon. I also tried using NSTrackingArea with an NSView placed over the view, but it did not solve the issue. It might be that the combination of .scaleEffect() and .animation() is causing a forced cursor reset (possibly related to the use of NSWindow.disableCursorRects() or something similar). However, I'm not entirely sure. Any insights or suggestions would be greatly appreciated. Thanks!
2
0
79
Apr ’25
Can't use Clipboard API after sending a message to the background script?
Hi, I’m encountering an unexpected issue in Safari. Specifically, navigator.clipboard.writeText() fails when called from a content script in my extension immediately after sending a message to background.js while it works fine in Chrome and Firefox. Is this expected? Environment Safari 18.2 (20620.1.16.11.8) Technology Preview 210 macOS Sequoia 15.2 (24C101) Example This is a minimal reproducible example, which adds a button to example.com: https://github.com/mshibanami/ClipboarAPIIssueExample Below is the related code: // content.js copyButton.addEventListener('click', async () => { // 👇️ This call seems to trigger the issue await chrome.runtime.sendMessage({}); try { await navigator.clipboard.writeText(text); alert(`✅ Copied '${text}' to clipboard!`); } catch (err) { alert(err + '\n\n' + `navigator.userActivation.isActive: ${navigator.userActivation.isActive}`); } }); // background.js chrome.runtime.onMessage.addListener(() => { }); When I click the button, I expect the text to be copied successfully. However, I receive an error in Safari.: Interestingly, if I remove chrome.runtime.sendMessage(), the clipboard operation works without any problems. Also, note that navigator.userActivation.isActive is true, which might mean it's not related to the User Activation API. Misc. This might be related to another question I posted here: https://developer.apple.com/forums/thread/772275
0
0
478
Jan ’25
Clipboard API `writeText()` fails in Safari due to User Activation API, but works in Firefox and Chrome
Hi, I'm encountering an issue with the Clipboard API's writeText() method in Safari. It throws a NotAllowedError even when triggered by a user action (selecting an option from a <select> element). Is this expected? This issue seems specific to Safari, as the same code works perfectly in Firefox and Chrome. Perhaps I should send feedback to Apple, but I'd like to post it here first in case I misunderstand something. Problem In Safari, when I try to copy text to the clipboard using navigator.clipboard.writeText() within an input event listener attached to a <select> element, it fails with 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. Environment Safari 18.2 (20620.1.16.11.8) Technology Preview 210 macOS Sequoia 15.2 (24C101) Example I've created a minimal reproducible example on CodePen: https://codepen.io/mshibanami/pen/LEPdxXZ Here's the relevant JavaScript code from the example: selectElement.addEventListener('input', async (event) => { const selectedText = event.target.options[event.target.selectedIndex].text; try { await navigator.clipboard.writeText(selectedText); alert(`Text copied to clipboard: ${selectedText}`); } catch (err) { alert('Failed to copy text to clipboard: ' + err); } }); Firefox and Chrome handle this code without any issues, successfully copying the text to the clipboard, but not Safari. Possible Cause I suspect this issue might be related to WebKit's User Activation API. It seems like Safari is not correctly recognizing the input or change event on a <select> element as a valid user activation for the Clipboard API, even though it is initiated by a user gesture. Questions Is this behavior unexpected? Should Safari allow the Clipboard API to work in this context? (Technically, this might be expected as of now, as such events are not explicitly described in https://webkit.org/blog/13862/the-user-activation-api/.) Any insights or suggestions would be greatly appreciated. Thanks!
1
2
1.2k
Jan ’25
[iOS 18] Is there an SF Symbol of the new icon in Safari's address bar?
The following icon has been introduced in Safari's address bar for iOS 18: I’d like to use it in my app to guide users on how to enable my Safari extension, but I couldn’t find it in SF Symbols beta 6.0 (99). Is this because it’s still in beta and will be available for third-party use later, or is it a private icon that only Apple can use? I hope I just overlooked something.
1
0
802
Sep ’24
Safari DNR Redirect Issue When Using Address Bar for Default Search Engine Queries
I’ve noticed that redirecting from one web page to another using DNR (Declarative Net Request) no longer works if: The source page is a search results page of the default search engine, and The user searches for a keyword from Safari’s address bar. Has this functionality been degraded, or is it an intentional restriction? I'd like a response from Apple. Steps to Reproduce Create a Safari extension that adds the following rule using browser.declarativeNetRequest.updateSessionRules() in background.js: { id: 37457985, priority: 1, action: { type: "redirect", redirect: { regexSubstitution: "https://search.brave.com/search?q=\\1" }, }, condition: { regexFilter: "https://duckduckgo.com/\\?(?:.*&)?q=([^&]*).*", resourceTypes: ["main_frame"] } } Enable the extension in Safari. Set Safari’s default search engine to DuckDuckGo. Type "hello" in the address bar to search for it. Expected: Search results for "hello" appear in Brave Search. Actual: Safari navigates to neither DuckDuckGo nor Brave Search. For further reference, please see: Sample Xcode project: GitHub link Demo video: GitHub link Environment I’ve confirmed this issue on the following environments: Safari Technology Preview 202 (macOS Sonoma 14.6.1 (23G93)) iOS 18 RC (22A3354) This issue does not occur in the latest release version of Safari 17.6 (19618.3.11.11.5) on macOS, so I believe it started with the current development version of Safari. Context My Safari extension, Redirect Web for Safari, uses DNR to redirect one web page to another. While the extension is not specifically designed to change the default search engine, some users use it to set their preferred search engine. Unfortunately, this issue will break their use case. Additional Information This issue only occurs when searching from the address bar. It does not happen when searching directly from https://duckduckgo.com. I haven’t submitted this issue via Feedback Assistant because I’m unsure if it’s a bug or intentional behavior. I’d like to confirm if this is by design first.
2
0
898
Sep ’24
Navigation-related listeners are not called after opening an embedded Web page
I made a Safari Web extension that's supposed to work like this: WHEN: Safari is opening http://example.com/ THEN: The extension opens a page embedded in the extension instead. This is the implementation of background.js: browser.tabs.onUpdated.addListener(async function (tabId) { const tab = await browser.tabs.get(tabId); if (tab.url == "http://example.com/") { const destination = browser.runtime.getURL("embedded-page.html"); browser.tabs.update(tabId, { url: destination }); } }, null); This is the source project: https://www.icloud.com/iclouddrive/042qIjivEoJ0V3qIcLGcytAPA When opening http://www.example.com/ for the first time, it successfully navigates to the embedded page. However, once that navigation is done, the extension no longer works that way unless I re-enable the extension. It's like the listeners are removed by that navigation. This is the video of this issue: https://www.icloud.com/iclouddrive/0f9Yl1jC9eQ8OmgH8vAtEA6Pw Can you replicate this on your Mac? And do you know what's the cause? This happens for a listener of browser.webNavigation.onBeforeNavigate too. Maybe more. On the other hand, when I set a normal page such as https://www.apple.com/ to destination, It always works fine for me. So I'm wondering if this issue is related to the embedded page. FYI, I already reported this issue as FB9967637 on 27th March but no reply from Apple as of now. My environment macOS Monterey 12.3.1 (21E258) Safari 15.4
2
0
1.5k
May ’22
SFSafariApplication.dispatchMessage() switches Safari to foreground?
I'm developing a Safari web extension for macOS that calls SFSafariApplication.dispatchMessage() (Swift) to communicate with background.js and the popup. However, I noticed that the method forcefully switches Safari to foreground. It seems it happens after calling browser.runtime.sendNativeMessage(''); in JavaScript. Is there a way to avoid that behavior? Or perhaps I'm misunderstanding something? This is a sample project and its video (Safari is switched to foreground every 3 seconds.): Sample project: https://www.dropbox.com/s/vs7h128ef1ji34q/ForcefulForegroundIssuePlayground.zip?dl=0 Video: https://www.dropbox.com/s/7pjbh1rihnh068l/Screen%20Recording%202021-12-23%20at%205.42.44%20pm.mov?dl=0 By the way, I already submitted a feedback for this as FB9804951 about 2 weeks ago but no response from Apple so far and I don't know if Apple will take any action for that or not even after the new year so I decided to ask here as well.
2
0
1.1k
Dec ’21
Can a Safari extension detect a page navigation error?
When the user tries to open a non-existing URL such as https://dsjiksfdakjf.com, Safari shows a built-in error page that displays texts like this: Safari Can’t Find the Server Safari can’t open the page “https://dsjiksfdakjf.com” because Safari can’t find the server “dsjiksfdakjf.com”. Can a Safari extension detect when this happen? Background of question I'd like to allow users to redirect from a broken or censored (HTTP 451) URL to another URL as a fallback, so that my users won't loose what they can still do other than just closing the tab. I've been looking for the solution but so far, no luck. I couldn't find out such functionalities from SFSafariExtensionHandler, SFSafariPage, etc. JavaScript files of extensions are not loaded for that error page either. I even wonder if it actually can't detect and what I can do for now is just to submit the feedback to Apple...
1
0
1.3k
Oct ’21
NSWindow presented on Safari extension (.appex) is not resizable?
I'm trying to present a resizable NSWindow defined like this: let window = NSWindow() window.contentViewController = NSHostingController( rootView: Rectangle().frame(minWidth: 100, minHeight: 100)) window.styleMask.insert([.closable, .resizable]) Generally, I can resize this window but somehow I can NOT when it's presented from Safari app extension (.appex). Did I miss something? Does anyone know what's happening?
1
0
1k
Aug ’21
Drag & Drop with NSTableViewDiffableDataSource
I'm now trying to add Drag &amp; Drop feature to my NSTableView which uses NSTableViewDiffableDataSource for its data source. However, I can't implement the methods for Drag &amp; Drop like tableView(:, acceptDrop:, row:, dropOperation:). My code looks like this: swift class MyViewController: NSViewController { private let tableView: NSTableView = {...}() private lazy var dataSource = MyDataSource(tableView: tableView) ... } class MyDataSource: NSTableViewDiffableDataSourceSection, Model { ...     override func tableView(_ tableView: NSTableView, draggingSession session: NSDraggingSession, willBeginAt screenPoint: NSPoint, forRowIndexes rowIndexes: IndexSet) { ...     } } Since NSTableViewDiffableDataSource implements NSTableViewDataSource protocol which provides Drag &amp; Drop methods, I thought the above overriding method would work but I got this error. Method does not override any method from its superclass What happened? And if this is expected, how can I implement Drag &amp; Drop with NSTableViewDiffableDataSource?
3
1
2.2k
Feb ’21