diff --git a/Package.swift b/Package.swift index 2c5315fa9..5465a7855 100644 --- a/Package.swift +++ b/Package.swift @@ -6,8 +6,8 @@ import PackageDescription let package = Package( name: "SafariView", platforms: [ - .iOS(.v15), - .macCatalyst(.v15) + .iOS(.v14), + .macCatalyst(.v14) ], products: [ .library( diff --git a/Sources/SafariView/Environment.swift b/Sources/SafariView/Environment.swift index 4b13da90d..65c83cbc3 100644 --- a/Sources/SafariView/Environment.swift +++ b/Sources/SafariView/Environment.swift @@ -25,7 +25,7 @@ import SwiftUI -@available(iOS 15.0, macCatalyst 15.0, *) +@available(iOS 14.0, macCatalyst 14.0, *) public extension EnvironmentValues { /// The additional activies to include the share sheet displayed inside a ``SafariView`` diff --git a/Sources/SafariView/ExcludedActivityTypes.swift b/Sources/SafariView/ExcludedActivityTypes.swift index b661ea4a4..25b1ab5de 100644 --- a/Sources/SafariView/ExcludedActivityTypes.swift +++ b/Sources/SafariView/ExcludedActivityTypes.swift @@ -26,7 +26,7 @@ import Foundation import UIKit -@available(iOS 15.0, macCatalyst 15.0, *) +@available(iOS 14.0, macCatalyst 14.0, *) public extension SafariView { /// A struct used to exclude activity types from the share sheet of a ``SafariView``. diff --git a/Sources/SafariView/IncludedActivities.swift b/Sources/SafariView/IncludedActivities.swift index dd558f4ef..5b5f9b3e1 100644 --- a/Sources/SafariView/IncludedActivities.swift +++ b/Sources/SafariView/IncludedActivities.swift @@ -26,7 +26,7 @@ import Foundation import UIKit -@available(iOS 15.0, macCatalyst 15.0, *) +@available(iOS 14.0, macCatalyst 14.0, *) public extension SafariView { /// A struct used to include custom activities in the share sheet of a ``SafariView`` diff --git a/Sources/SafariView/Modifiers.swift b/Sources/SafariView/Modifiers.swift index 09c10ebff..5d51fdeb6 100644 --- a/Sources/SafariView/Modifiers.swift +++ b/Sources/SafariView/Modifiers.swift @@ -25,7 +25,7 @@ import SwiftUI -@available(iOS 15.0, macCatalyst 15.0, *) +@available(iOS 14.0, macCatalyst 14.0, *) public extension View { /// Set the automatic reader behavior of safari views within this view diff --git a/Sources/SafariView/Presentation.swift b/Sources/SafariView/Presentation.swift index 763715e38..8d97d3913 100644 --- a/Sources/SafariView/Presentation.swift +++ b/Sources/SafariView/Presentation.swift @@ -25,7 +25,7 @@ import SwiftUI -@available(iOS 15.0, macCatalyst 15.0, *) +@available(iOS 14.0, macCatalyst 14.0, *) public extension View { /// Presents a ``SafariView`` when a binding to a Boolean value that you provide is `true`. diff --git a/Sources/SafariView/SafariView.docc/View.md b/Sources/SafariView/SafariView.docc/View.md index 83c631f6b..cee02147a 100644 --- a/Sources/SafariView/SafariView.docc/View.md +++ b/Sources/SafariView/SafariView.docc/View.md @@ -10,14 +10,10 @@ A SafariView is best presented by using one the `safari` view modifiers, or via ### Creating a Safari View +- ``init(url:onInitialLoad:onInitialRedirect:onOpenInBrowser:)`` - ``init(url:activityButton:onInitialLoad:onInitialRedirect:onOpenInBrowser:)`` - ``init(url:activityButton:eventAttribution:onInitialLoad:onInitialRedirect:onOpenInBrowser:)`` -### Configuring the View - -- ``ActivityButton`` -- ``DismissButtonStyle`` - ### Custom Activities - ``IncludedActivities`` diff --git a/Sources/SafariView/SafariView.swift b/Sources/SafariView/SafariView.swift index 51f35d0f9..841b41032 100644 --- a/Sources/SafariView/SafariView.swift +++ b/Sources/SafariView/SafariView.swift @@ -28,7 +28,7 @@ import SwiftUI import UIKit /// A wrapper for `SFSafariViewController` in SwiftUI -@available(iOS 15.0, macCatalyst 15.0, *) +@available(iOS 14.0, macCatalyst 14.0, *) public struct SafariView: View { // MARK: - Initializers @@ -36,13 +36,34 @@ public struct SafariView: View { /// Create a SafariView /// - Parameters: /// - url: URL to load + /// - onInitialLoad: Closure to execute on initial load + /// - onInitialRedirect: Closure to execute on intial redirect + /// - onOpenInBrowser: Closure to execute if a user moves from a `SafariView` to `Safari.app` + public init( + url: URL, + onInitialLoad: ((_ didLoadSuccessfully: Bool) -> Void)? = nil, + onInitialRedirect: ((_ url: URL) -> Void)? = nil, + onOpenInBrowser: (() -> Void)? = nil + ) { + self.url = url + activityButton = nil + eventAttribution = nil + self.onInitialLoad = onInitialLoad + self.onInitialRedirect = onInitialRedirect + self.onOpenInBrowser = onOpenInBrowser + } + + /// Create a SafariView with a custom activity button + /// - Parameters: + /// - url: URL to load /// - activityButton: Custom activity button to include in the safari view /// - onInitialLoad: Closure to execute on initial load /// - onInitialRedirect: Closure to execute on intial redirect /// - onOpenInBrowser: Closure to execute if a user moves from a `SafariView` to `Safari.app` + @available(iOS 15.0, macCatalyst 15.0, *) public init( url: URL, - activityButton: ActivityButton? = nil, + activityButton: ActivityButton?, onInitialLoad: ((_ didLoadSuccessfully: Bool) -> Void)? = nil, onInitialRedirect: ((_ url: URL) -> Void)? = nil, onOpenInBrowser: (() -> Void)? = nil @@ -88,11 +109,13 @@ public struct SafariView: View { public typealias DismissButtonStyle = SFSafariViewController.DismissButtonStyle /// A convenience typealias for [`SFSafariViewController.ActivityButton`](https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller/activitybutton) + @available(iOS 15.0, macCatalyst 15.0, *) public typealias ActivityButton = SFSafariViewController.ActivityButton /// A convenience typealias for [`SFSafariViewController.PrewarmingToken`](https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller/prewarmingtoken) /// /// You can generate prewarming tokens for invalidation using the ``prewarmConnections(to:)`` static method. + @available(iOS 15.0, macCatalyst 15.0, *) public typealias PrewarmingToken = SFSafariViewController.PrewarmingToken /// Prewarm the connection to a list of provided URLs @@ -107,6 +130,7 @@ public struct SafariView: View { /// /// - Parameter URLs: The URLs to prewarm /// - Returns: A prewarming token for the provided URLs. + @available(iOS 15.0, macCatalyst 15.0, *) @discardableResult public static func prewarmConnections(to URLs: [URL]) -> PrewarmingToken { SFSafariViewController.prewarmConnections(to: URLs) @@ -127,6 +151,7 @@ public struct SafariView: View { // MARK: - View + @_documentation(visibility: internal) public var body: some View { Safari(parent: self) .ignoresSafeArea(.container, edges: .all) @@ -155,7 +180,7 @@ public struct SafariView: View { @Environment(\.safariViewExcludedActivityTypes) private var excludedActivityTypes: ExcludedActivityTypes - private let activityButton: ActivityButton? + private let activityButton: AnyObject? private let eventAttribution: AnyObject? private let url: URL private let onInitialLoad: ((Bool) -> Void)? @@ -172,7 +197,10 @@ public struct SafariView: View { let configuration = SFSafariViewController.Configuration() configuration.entersReaderIfAvailable = entersReaderIfAvailable configuration.barCollapsingEnabled = barCollapsingEnabled - configuration.activityButton = activityButton + if #available(iOS 15.0, macCatalyst 15.0, *), + let activityButton { + configuration.activityButton = unsafeDowncast(activityButton, to: ActivityButton.self) + } if #available(iOS 15.2, *), let eventAttribution { configuration.eventAttribution = unsafeDowncast(eventAttribution, to: UIEventAttribution.self)