I'm now developing a Safari extension that redirects web pages, then I got here.
As timothy.hatcher said, it's shame that there is no perfect solution so far. Any workarounds I tried has some problems that they send a network request for the source URL or they are unstable. So I gave up and I just use window.location.href for now. FWIW, the code I wrote is below.
By the way, I submitted a feedback as he suggested. I hope many other people will also submit it.
Code
Swift
class SafariExtensionHandler: SFSafariExtensionHandler {
override func messageReceived(withName messageName: String, from page: SFSafariPage, userInfo: [String : Any]? = nil) {
page.getPropertiesWithCompletionHandler { [weak self] properties in
guard let self = self else {
return
}
switch messageName {
case "pageLoaded":
guard let url = properties?.url else {
break
}
self.redirectIfNeeded(currentPage: page, url: url)
default:
break
}
}
}
override func page(_ page: SFSafariPage, willNavigateTo url: URL?) {
guard let url = url else {
return
}
redirectIfNeeded(currentPage: page, url: url)
}
private func redirectIfNeeded(currentPage: SFSafariPage, url: URL) {
				let redirectIsNeeded = <#put your condition here#>
				guard redirectIsNeeded else {
						return
				}
				// You may need to delay this code with `DispatchQueue.main.asyncAfter(deadline:)` or something like that
				// because this can't redirect a web page that has the `Location` response header.
				currentPage.redirect(to: url)
}
}
private extension SFSafariPage {
func redirect(to url: URL) {
dispatchMessageToScript(
withName: "redirectPage",
userInfo: ["url": url.absoluteString])
}
}
Javascript
(function () {
if (window.top === window) {
safari.self.addEventListener(
'message',
(event) => {
if (document.hidden) {
return;
}
switch (event.name) {
case 'redirectPage':
window.location.href = event.message.url;
break;
}
},
false);
safari.extension.dispatchMessage('pageLoaded');
}
})();
Post
Replies
Boosts
Views
Activity
Setting the scroll view's automaticallyAdjustsContentInsets property to false solved my problem.
In my case, I needed to set it to scrollView.contentView rather than the scroll view itself, like this:
swift
scrollView.automaticallyAdjustsContentInsets = false
scrollView.contentInsets = .init(top: 20, left: 0, bottom: 0, right: 0)
Sorry, I mean, like this.
swift
scrollView.contentView.automaticallyAdjustsContentInsets = false
scrollView.contentView.contentInsets = .init(top: 20, left: 0, bottom: 0, right: 0)
You should use fill().
RoundedRectangle(cornerRadius: 8, style: .continuous)
.fill(Color(red: 255, green: 245, blue: 158))
Don't use background() for changing the color of RoundedRectangle. It just fills the background of the rounded rectangle rather than the rounded rectangle itself.
Apple recommends checking built-in en0, built-in en1, and non built-in en0 in that order.
This is the details:
https://developer.apple.com/documentation/appstorereceipts/validating_receipts_on_the_device
@DSNET If you want to change the displayed extension name on Safari's Preferences window, changing CFBundleDisplayName (not CBBundleDisplayName) should work for Safari extensions too, but you need to reopen Safari to reflect it.
I've just chatted with an Apple developer (Timothy Hatcher) in the WWDC's lab.
According to him, this has already been fixed internally and will be deployed soon.
So this issue will be solved once your users update the Safari version to (hopefully) 15.6 or later, since the current version is 15.5.
Thanks, Timothy. 🙂
Just an update; I've just chatted with an Apple developer (Timothy Hatcher) in the WWDC's lab. According to him, it's not solved yet, but at least Apple recognizes it's a bug. A certain famous company also sent the same feedback before mine, so my FB9804951 is internally marked as duplicated. I hope it'll be fixed soon. Thanks Timothy. 🙂
I'm also facing the same issue so I've sent Apple my feedback on Feedback Assistant as FB10748429.
The more feedback, The more they care about this issue.
Unfortunately, Just posting "same" or "any news?" in the developer forums never changes Apple's priority. The only way to change it is to submit feedback on Feedback Assistant.
As far as I can see, only dcordero sent feedback on this thread but it's not enough.
I need your help. Please submit your own feedback and let's change Apple's mind.
I also need this for a certain educational institution that wants my app for their thousands of Macs. I would like to provide it free of charge. This feature will be essential for my use case.
As the App Store Commerce Engineer suggested in this thread, I submitted feedback as FB11830690.
If you also agree that this is needed, I want you to submit the same feedback as mine.
The more feedback Apple receives, the higher priority they will set for this issue!
My app was rejected because of this. I sent them a link to this forum, and then they approved it. Thanks Apple.
If you can't find your certificate in the list of Settings > General > About > Certificate Trust Settings, run this command to place your certificate in your simulator:
xcrun simctl keychain booted add-root-cert <path to your certificate>
If drag and drop didn't work for you, try it.
I believe this hasn't been addressed yet, and +1 for this functionality on macOS.
On iOS 17, you can prohibit your kids from disabling/enabling extensions by limiting adult websites from the Settings app > Screen Time > Content & Privacy Restrictions > Store, Web, Siri & Game Center Content > Web Content. However, on macOS Sonoma, you can't prohibit them similarly.
I'm a developer of a Safari extension called Redirect Web for Safari, which can redirect users from any web page to another. Some users use it to protect their kids from unwanted websites. Recently, I received user feedback to add passcode protection so their kids won't be able to turn off the redirect rules. However, if the kids can turn off the extension, they can bypass the protection by turning it off, diminishing the benefit of the passcode protection. Therefore, this functionality is essential to implement it.
If you, reading my comment, have the same demand, I hope you will push the Boost button of this thread.
Furthermore, I sent a feature request to Apple as FB14709779 through Feedback Assistant. It would be great if you could also submit it. The more feedback we send, the higher the possibility that Apple will prioritize this issue.
@seithogei@gmail.com's solution worked for me as well!
Additionally, the answer from StackOverflow also worked for me. (= Right-click the Download button and select "Download Linked File" from the context menu to download the key.):
https://stackoverflow.com/a/78357842/4366470
But this is a workaround. I hope Apple will fix this issue anyways.
@jeffjohnson Thanks for checking it. I see, tthat's strange. I still haven't seen the sample extension working correctly on Safari Technology Preview 202. I've tried to make it work for 30 minutes, but it never does.
By the way, I also succeeded in replicating this issue on Safari 17.6. Specifically, when I search from the address bar for the first time in a new tab, it correctly redirects to Brave. However, after that, it doesn't work with the same tab. This is the demo:
https://github.com/user-attachments/assets/c8a84403-c878-44a5-8748-91721c0ea66b
It works again when I open another new tab.
So, on my end, the issue seems to have worsened rather than newly appeared.