App/Sources/InAppBrowser.swift
23 lines · 956 bytes
2 symbols in this file
1import SafariServices
2import SwiftUI
3import UIKit
4
5/// Opens web links in Safari's in-app browser over the current screen, so people stay in the app.
6/// Other schemes (mailto:, settings) go to the system as usual.
7@MainActor
8enum InAppBrowser {
9 static let action = OpenURLAction { url in
10 guard url.scheme == "https" || url.scheme == "http", let top = topViewController() else { return .systemAction }
11 let safari = SFSafariViewController(url: url)
12 safari.dismissButtonStyle = .done
13 top.present(safari, animated: true)
14 return .handled
15 }
16
17 private static func topViewController() -> UIViewController? {
18 let scene = UIApplication.shared.connectedScenes.compactMap { $0 as? UIWindowScene }.first { $0.activationState == .foregroundActive }
19 var top = scene?.keyWindow?.rootViewController
20 while let presented = top?.presentedViewController { top = presented }
21 return top
22 }
23}