-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ba95e2e
commit 1012fbe
Showing
6 changed files
with
65 additions
and
65 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,82 +1,82 @@ | ||
import Dependencies | ||
|
||
#if canImport(SafariServices) && canImport(SwiftUI) | ||
import SafariServices | ||
import SwiftUI | ||
import SafariServices | ||
import SwiftUI | ||
|
||
extension DependencyValues { | ||
/// A dependency that opens a URL in SFSafariViewController. | ||
/// | ||
/// In iOS, use SFSafariViewController in UIKit context. Otherwise use openURL in environment values | ||
/// | ||
/// - SeeAlso: https://sarunw.com/posts/sfsafariviewcontroller-in-swiftui/ | ||
@available(iOS 15, macOS 11, tvOS 14, watchOS 7, *) | ||
public var safari: SafariEffect { | ||
get { self[SafariKey.self] } | ||
set { self[SafariKey.self] = newValue } | ||
extension DependencyValues { | ||
/// A dependency that opens a URL in SFSafariViewController. | ||
/// | ||
/// In iOS, use SFSafariViewController in UIKit context. Otherwise use openURL in environment values | ||
/// | ||
/// - SeeAlso: https://sarunw.com/posts/sfsafariviewcontroller-in-swiftui/ | ||
@available(iOS 15, macOS 11, tvOS 14, watchOS 7, *) | ||
public var safari: SafariEffect { | ||
get { self[SafariKey.self] } | ||
set { self[SafariKey.self] = newValue } | ||
} | ||
} | ||
} | ||
|
||
@available(iOS 15, macOS 11, tvOS 14, watchOS 7, *) | ||
private enum SafariKey: DependencyKey { | ||
static let liveValue = SafariEffect { url in | ||
let stream = AsyncStream<Bool> { continuation in | ||
let task = Task { @MainActor in | ||
#if os(iOS) | ||
let vc = SFSafariViewController(url: url) | ||
UIApplication.shared.firstKeyWindow?.rootViewController?.present(vc, animated: true) | ||
continuation.yield(true) | ||
continuation.finish() | ||
#else | ||
EnvironmentValues().openURL(url) | ||
continuation.yield(true) | ||
continuation.finish() | ||
#endif | ||
} | ||
continuation.onTermination = { @Sendable _ in | ||
task.cancel() | ||
@available(iOS 15, macOS 11, tvOS 14, watchOS 7, *) | ||
private enum SafariKey: DependencyKey { | ||
static let liveValue = SafariEffect { url in | ||
let stream = AsyncStream<Bool> { continuation in | ||
let task = Task { @MainActor in | ||
#if os(iOS) | ||
let vc = SFSafariViewController(url: url) | ||
UIApplication.shared.firstKeyWindow?.rootViewController?.present(vc, animated: true) | ||
continuation.yield(true) | ||
continuation.finish() | ||
#else | ||
EnvironmentValues().openURL(url) | ||
continuation.yield(true) | ||
continuation.finish() | ||
#endif | ||
} | ||
continuation.onTermination = { @Sendable _ in | ||
task.cancel() | ||
} | ||
} | ||
return await stream.first(where: { _ in true }) ?? false | ||
} | ||
static let testValue = SafariEffect { _ in | ||
XCTFail(#"Unimplemented: @Dependency(\.safari)"#) | ||
return false | ||
} | ||
return await stream.first(where: { _ in true }) ?? false | ||
} | ||
static let testValue = SafariEffect { _ in | ||
XCTFail(#"Unimplemented: @Dependency(\.safari)"#) | ||
return false | ||
} | ||
} | ||
|
||
public struct SafariEffect: Sendable { | ||
private let handler: @Sendable (URL) async -> Bool | ||
public struct SafariEffect: Sendable { | ||
private let handler: @Sendable (URL) async -> Bool | ||
|
||
public init(handler: @escaping @Sendable (URL) async -> Bool) { | ||
self.handler = handler | ||
} | ||
public init(handler: @escaping @Sendable (URL) async -> Bool) { | ||
self.handler = handler | ||
} | ||
|
||
@available(watchOS, unavailable) | ||
@discardableResult | ||
public func callAsFunction(_ url: URL) async -> Bool { | ||
await self.handler(url) | ||
} | ||
@available(watchOS, unavailable) | ||
@discardableResult | ||
public func callAsFunction(_ url: URL) async -> Bool { | ||
await self.handler(url) | ||
} | ||
|
||
@_disfavoredOverload | ||
public func callAsFunction(_ url: URL) async { | ||
_ = await self.handler(url) | ||
@_disfavoredOverload | ||
public func callAsFunction(_ url: URL) async { | ||
_ = await self.handler(url) | ||
} | ||
} | ||
} | ||
|
||
#endif | ||
|
||
#if canImport(UIKit) | ||
import UIKit | ||
import UIKit | ||
|
||
extension UIApplication { | ||
@available(iOS 15.0, *) | ||
var firstKeyWindow: UIWindow? { | ||
return UIApplication.shared.connectedScenes | ||
.compactMap { $0 as? UIWindowScene } | ||
.filter { $0.activationState == .foregroundActive } | ||
.first?.keyWindow | ||
extension UIApplication { | ||
@available(iOS 15.0, *) | ||
var firstKeyWindow: UIWindow? { | ||
return UIApplication.shared.connectedScenes | ||
.compactMap { $0 as? UIWindowScene } | ||
.filter { $0.activationState == .foregroundActive } | ||
.first?.keyWindow | ||
} | ||
} | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters