From 6bd6d66c44b5321c6aeb89423e1497781caae6f9 Mon Sep 17 00:00:00 2001 From: Kyle Date: Sun, 18 Oct 2026 12:41:40 +0800 Subject: [PATCH 1/2] feat(preview): present #Preview content as a SwiftUI preview - Add a DeveloperToolsSupport.Preview initializer that takes an OpenSwiftUI view body and wraps it in a SwiftUI view, so Xcode applies the platform canvas, such as the visionOS window canvas. - Expand #Preview with a local view builder function, as SwiftUI does, instead of an extra Group. - Deprecate _previewVC(). --- Docs/Preview.md | 23 +++++---- .../Integration/LegacyPreviewProvider.swift | 6 +-- .../Integration/PreviewShims.swift | 34 ++++++++++++-- Sources/OpenSwiftUI/Macro/PreviewMacro.swift | 6 +-- Sources/OpenSwiftUIMacros/PreviewMacro.swift | 43 +++++++---------- .../PreviewMacroTests.swift | 47 ++++++++++++------- 6 files changed, 95 insertions(+), 64 deletions(-) diff --git a/Docs/Preview.md b/Docs/Preview.md index 4e543eee1..6256654d2 100644 --- a/Docs/Preview.md +++ b/Docs/Preview.md @@ -8,9 +8,9 @@ OpenSwiftUI declares a `Preview` macro overload whose view builder produces `OpenSwiftUI.View`. UIKit and AppKit continue to provide the controller-oriented Preview overloads. When these modules are imported together, Swift selects the matching macro from the type produced by the body: -1. `#Preview` with an `OpenSwiftUI.View` body resolves to OpenSwiftUI's macro and collects the content in a `Group` -2. `_previewVC()` wraps that content in `NSHostingController` or `UIHostingController` -3. The expansion emits the `DeveloperToolsSupport.PreviewRegistry` that Xcode discovers and returns a preview containing the resulting controller +1. `#Preview` with an `OpenSwiftUI.View` body resolves to OpenSwiftUI's macro +2. The expansion emits the `DeveloperToolsSupport.PreviewRegistry` that Xcode discovers. Like SwiftUI's expansion, `makePreview()` applies `ViewBuilder` to the body through a local `__b_buildView(body:)` function +3. The result goes to OpenSwiftUI's `Preview.init(_:traits:body:)` overload, which takes an `OpenSwiftUI.View` body ```swift import AppKit @@ -27,7 +27,7 @@ import OpenSwiftUI The first declaration uses OpenSwiftUI's Preview macro because its body produces an `OpenSwiftUI.View`. The second continues to use AppKit's Preview macro because its body produces an `NSViewController`. The same overload selection applies to UIKit and `UIViewController`; these common cases do not require explicit module qualification. -Native macOS targets return an `NSViewController`; iOS, Mac Catalyst, and visionOS targets return a `UIViewController`. The current hosting-controller path does not support tvOS or watchOS because OpenSwiftUI does not provide a hosting controller on those platforms. +The initializer puts the view in an `NSHostingController` on macOS, or a `UIHostingController` on iOS, Mac Catalyst, and visionOS. It then wraps the controller in a SwiftUI view and uses SwiftUI's view Preview initializer. Xcode applies the platform canvas to SwiftUI previews only, for example the visionOS window canvas and camera controls. The current path does not support tvOS or watchOS because OpenSwiftUI does not provide a hosting controller on those platforms. The macro accepts the same `traits:` and additional trait arguments as SwiftUI's view Preview macro. @@ -43,17 +43,20 @@ Xcode Preview's XOJIT loading model requires both `OpenSwiftUI.framework` and `O Link `OpenSwiftUICore` with `-ObjC` when building the framework so Objective-C categories from the static `OpenSwiftUI_SPI` dependency are retained in the Core dylib. This is a framework-build setting; consumers of the resulting XCFrameworks do not need to add `-ObjC`. -Consumers that integrate the XCFrameworks directly instead of using `OpenSwiftUI-spm` must provide the matching macro plugin separately. Without it, they can still wrap the view with `_previewVC()` explicitly so overload resolution selects the platform Preview macro. For example, on macOS: +Consumers that integrate the XCFrameworks directly instead of using `OpenSwiftUI-spm` must provide the matching macro plugin separately. Without it, they can declare a `PreviewProvider` instead: ```swift -import AppKit import OpenSwiftUI -#Preview("HostingVC") { - ContentView()._previewVC() +struct ContentView_Previews: PreviewProvider { + static var previews: some View { + ContentView() + } } ``` +The `_previewVC()` helper is deprecated. It wraps the view in a hosting controller for the UIKit and AppKit Preview macros, so it does not get the visionOS window canvas. + ### The `waitingForPreviewThunks` Problem In Xcode Preview mode, SwiftUI gates graph instantiation behind a `waitingForPreviewThunks` flag (checked via `XCODE_RUNNING_FOR_PREVIEWS` env var). After all preview dylibs are loaded, `PreviewsInjection.framework` calls `SwiftUI.__previewThunksHaveFinishedLoading()` to unblock graph hosts. @@ -104,8 +107,8 @@ sequenceDiagram The current shim-based approach is a temporary bridge. The long-term goal is for OpenSwiftUI to have its **own** native preview support: ### Phase 1: Native OpenSwiftUI Preview Expansion -- Replace the current hosting-controller registry body with one that previews `OpenSwiftUI.View` directly -- Eliminate the internal `_previewVC()` shim and hosting controller wrapper +- Replace the hosting controller inside `Preview.init(_:traits:body:)` with a preview that renders `OpenSwiftUI.View` directly +- Remove the deprecated `_previewVC()` shim and the hosting controller wrapper - Keep the `#Preview { MyView() }` source interface while changing its implementation ### Phase 2: Own Preview Thunk Registration diff --git a/Sources/OpenSwiftUI/Integration/LegacyPreviewProvider.swift b/Sources/OpenSwiftUI/Integration/LegacyPreviewProvider.swift index bf25669dd..a931b4f2b 100644 --- a/Sources/OpenSwiftUI/Integration/LegacyPreviewProvider.swift +++ b/Sources/OpenSwiftUI/Integration/LegacyPreviewProvider.swift @@ -46,7 +46,7 @@ private class LegacyPreviewProviderWitness: SwiftUI.PreviewProvider { private static func nativePreview(_ preview: OpenSwiftUI._Preview) -> SwiftUI.AnyView { var view = SwiftUI.AnyView( - LegacyPreviewView(content: preview.content) + NativePreviewView(content: preview.content) .previewDisplayName(preview.displayName) .previewDevice(preview.device.map { SwiftUI.PreviewDevice(rawValue: $0.rawValue) }) .previewLayout(preview.layout) @@ -93,7 +93,7 @@ private struct LegacyPreviewContext: OpenSwiftUI.PreviewContext, SwiftUI.Preview } #if (os(iOS) || os(visionOS)) -private struct LegacyPreviewView: SwiftUI.UIViewControllerRepresentable { +struct NativePreviewView: SwiftUI.UIViewControllerRepresentable { var content: OpenSwiftUI.AnyView func makeUIViewController(context: Context) -> OpenSwiftUI.UIHostingController { @@ -118,7 +118,7 @@ private struct LegacyPreviewView: SwiftUI.UIViewControllerRepresentable { } } #elseif os(macOS) -private struct LegacyPreviewView: SwiftUI.NSViewControllerRepresentable { +struct NativePreviewView: SwiftUI.NSViewControllerRepresentable { var content: OpenSwiftUI.AnyView func makeNSViewController(context: Context) -> OpenSwiftUI.NSHostingController { diff --git a/Sources/OpenSwiftUI/Integration/PreviewShims.swift b/Sources/OpenSwiftUI/Integration/PreviewShims.swift index e8702d12d..a4019951f 100644 --- a/Sources/OpenSwiftUI/Integration/PreviewShims.swift +++ b/Sources/OpenSwiftUI/Integration/PreviewShims.swift @@ -3,16 +3,14 @@ // OpenSwiftUI // // Bridging helpers for Xcode Preview support. -// Wraps OpenSwiftUI views in hosting controllers so they can be used with -// AppKit and UIKit's #Preview macros. +// Presents OpenSwiftUI views as SwiftUI previews for the #Preview macro. import OpenSwiftUICore -// Helper method before we add native preview thunk support for OpenSwiftUI. - #if canImport(AppKit) && !targetEnvironment(macCatalyst) public import AppKit extension OpenSwiftUI.View { + @available(*, deprecated, message: "Use the OpenSwiftUI #Preview macro or PreviewProvider instead.") public func _previewVC() -> NSViewController { OpenSwiftUI.NSHostingController(rootView: self) } @@ -20,8 +18,36 @@ extension OpenSwiftUI.View { #elseif canImport(UIKit) public import UIKit extension OpenSwiftUI.View { + @available(*, deprecated, message: "Use the OpenSwiftUI #Preview macro or PreviewProvider instead.") public func _previewVC() -> UIViewController { OpenSwiftUI.UIHostingController(rootView: self) } } #endif + +#if canImport(DeveloperToolsSupport) && canImport(SwiftUI) && (os(macOS) || os(iOS) || os(visionOS)) +public import DeveloperToolsSupport +import SwiftUI + +@available(iOS 17.0, macOS 14.0, visionOS 1.0, *) +extension DeveloperToolsSupport.Preview { + /// Creates a preview of an OpenSwiftUI view. + /// + /// - Parameters: + /// - name: An optional display name for the preview. + /// - traits: An optional list of traits that customize the preview. + /// - body: A closure that produces the OpenSwiftUI view to preview. + @MainActor + public init( + _ name: String? = nil, + traits: PreviewTrait..., + body: @escaping @MainActor () -> any OpenSwiftUI.View + ) { + // Swift cannot forward a variadic list, so combine the traits first. + let trait = traits.reduce(PreviewTrait()) { PreviewTrait($0, $1) } + self.init(name, traits: trait) { + NativePreviewView(content: OpenSwiftUI.AnyView(body())) + } + } +} +#endif diff --git a/Sources/OpenSwiftUI/Macro/PreviewMacro.swift b/Sources/OpenSwiftUI/Macro/PreviewMacro.swift index 3f806d6cf..1517e3be5 100644 --- a/Sources/OpenSwiftUI/Macro/PreviewMacro.swift +++ b/Sources/OpenSwiftUI/Macro/PreviewMacro.swift @@ -8,8 +8,7 @@ import OpenSwiftUICore /// Creates an Xcode preview from an OpenSwiftUI view. /// -/// The macro hosts the view in a platform view controller and registers it with -/// Xcode Previews. +/// The macro registers the view with Xcode Previews. @available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) @freestanding(declaration) public macro Preview( @@ -22,8 +21,7 @@ public macro Preview( /// Creates an Xcode preview with traits from an OpenSwiftUI view. /// -/// The macro hosts the view in a platform view controller and registers it and -/// its traits with Xcode Previews. +/// The macro registers the view and its traits with Xcode Previews. @available(iOS 17.0, macOS 14.0, tvOS 17.0, watchOS 10.0, *) @freestanding(declaration) public macro Preview( diff --git a/Sources/OpenSwiftUIMacros/PreviewMacro.swift b/Sources/OpenSwiftUIMacros/PreviewMacro.swift index 035a328b7..bf8b71735 100644 --- a/Sources/OpenSwiftUIMacros/PreviewMacro.swift +++ b/Sources/OpenSwiftUIMacros/PreviewMacro.swift @@ -17,7 +17,7 @@ package struct PreviewMacro: DeclarationMacro { if let body = node.trailingClosure { trailingClosure = wrappedBody(body) } else if let bodyIndex = arguments.lastIndex(where: { $0.label?.text == "body" }) { - arguments[bodyIndex].expression = ExprSyntax(wrappedBody(arguments[bodyIndex].expression)) + arguments[bodyIndex].expression = wrappedBody(arguments[bodyIndex].expression) trailingClosure = nil } else { throw MacroExpansionErrorMessage("#Preview requires a view body") @@ -71,40 +71,33 @@ package struct PreviewMacro: DeclarationMacro { return [registry] } - private static func wrappedBody(_ body: ExprSyntax) -> ClosureExprSyntax { + private static func wrappedBody(_ body: ExprSyntax) -> ExprSyntax { + // A referenced body already matches the OpenSwiftUI Preview initializer. guard let closure = body.as(ClosureExprSyntax.self) else { - // A referenced body returns an existential View, so erase its - // result to a concrete root before creating the hosting controller. - let wrappedBody: ExprSyntax = """ - { - OpenSwiftUI::AnyView((\(body))()) - ._previewVC() - } - """ - return wrappedBody.as(ClosureExprSyntax.self)! + return body } - return wrappedBody(closure) + return ExprSyntax(wrappedBody(closure)) } private static func wrappedBody(_ body: ClosureExprSyntax) -> ClosureExprSyntax { + // Apply the view builder to the statements without an extra root view. + let buildView: DeclSyntax = + """ + func __b_buildView(@OpenSwiftUI::ViewBuilder body: () -> any OpenSwiftUI::View) -> any OpenSwiftUI::View { + body() + } + """ let content = ClosureExprSyntax(statements: body.statements) - let group = FunctionCallExprSyntax( - callee: DeclReferenceExprSyntax( - moduleSelector: ModuleSelectorSyntax(moduleName: .identifier("OpenSwiftUI")), - baseName: .identifier("Group") - ), - trailingClosure: content - ) - let previewVC = FunctionCallExprSyntax( - callee: MemberAccessExprSyntax( - base: group, - period: .periodToken(leadingTrivia: .newline), - declName: DeclReferenceExprSyntax(baseName: .identifier("_previewVC")) + let returnBuiltView = ReturnStmtSyntax( + expression: FunctionCallExprSyntax( + callee: DeclReferenceExprSyntax(baseName: .identifier("__b_buildView")), + trailingClosure: content ) ) var wrappedBody = body wrappedBody.statements = CodeBlockItemListSyntax([ - CodeBlockItemSyntax(item: .expr(ExprSyntax(previewVC))) + CodeBlockItemSyntax(item: .decl(buildView)), + CodeBlockItemSyntax(item: .stmt(StmtSyntax(returnBuiltView))), ]) return wrappedBody.formatted().cast(ClosureExprSyntax.self) } diff --git a/Tests/OpenSwiftUIMacrosTests/PreviewMacroTests.swift b/Tests/OpenSwiftUIMacrosTests/PreviewMacroTests.swift index be39e56ae..e2f238942 100644 --- a/Tests/OpenSwiftUIMacrosTests/PreviewMacroTests.swift +++ b/Tests/OpenSwiftUIMacrosTests/PreviewMacroTests.swift @@ -37,10 +37,12 @@ final class PreviewMacroTests: XCTestCase { static func makePreview() throws -> DeveloperToolsSupport::Preview { DeveloperToolsSupport::Preview("HostingVC") { - OpenSwiftUI::Group { + func __b_buildView(@OpenSwiftUI::ViewBuilder body: () -> any OpenSwiftUI::View) -> any OpenSwiftUI::View { + body() + } + return __b_buildView { ContentView() } - ._previewVC() } } } @@ -73,10 +75,12 @@ final class PreviewMacroTests: XCTestCase { static func makePreview() throws -> DeveloperToolsSupport::Preview { DeveloperToolsSupport::Preview { - OpenSwiftUI::Group { + func __b_buildView(@OpenSwiftUI::ViewBuilder body: () -> any OpenSwiftUI::View) -> any OpenSwiftUI::View { + body() + } + return __b_buildView { CounterView() } - ._previewVC() } } } @@ -108,10 +112,12 @@ final class PreviewMacroTests: XCTestCase { static func makePreview() throws -> DeveloperToolsSupport::Preview { DeveloperToolsSupport::Preview { - OpenSwiftUI::Group { + func __b_buildView(@OpenSwiftUI::ViewBuilder body: () -> any OpenSwiftUI::View) -> any OpenSwiftUI::View { + body() + } + return __b_buildView { ContentView() } - ._previewVC() } } } @@ -146,13 +152,15 @@ final class PreviewMacroTests: XCTestCase { static func makePreview() throws -> DeveloperToolsSupport::Preview { DeveloperToolsSupport::Preview { - OpenSwiftUI::Group { + func __b_buildView(@OpenSwiftUI::ViewBuilder body: () -> any OpenSwiftUI::View) -> any OpenSwiftUI::View { + body() + } + return __b_buildView { Text("Primary") if showsSecondary { Text("Secondary") } } - ._previewVC() } } } @@ -192,10 +200,12 @@ final class PreviewMacroTests: XCTestCase { traits: .sizeThatFitsLayout, .fixedLayout(width: 320, height: 200) ) { - OpenSwiftUI::Group { + func __b_buildView(@OpenSwiftUI::ViewBuilder body: () -> any OpenSwiftUI::View) -> any OpenSwiftUI::View { + body() + } + return __b_buildView { ContentView() } - ._previewVC() } } } @@ -227,10 +237,12 @@ final class PreviewMacroTests: XCTestCase { static func makePreview() throws -> DeveloperToolsSupport::Preview { DeveloperToolsSupport::Preview("Explicit", body: { - OpenSwiftUI::Group { + func __b_buildView(@OpenSwiftUI::ViewBuilder body: () -> any OpenSwiftUI::View) -> any OpenSwiftUI::View { + body() + } + return __b_buildView { ContentView() } - ._previewVC() }) } } @@ -263,10 +275,7 @@ final class PreviewMacroTests: XCTestCase { } static func makePreview() throws -> DeveloperToolsSupport::Preview { - DeveloperToolsSupport::Preview("Expression", body: { - OpenSwiftUI::AnyView((previewBody)()) - ._previewVC() - }) + DeveloperToolsSupport::Preview("Expression", body: previewBody) } } """, @@ -296,9 +305,11 @@ final class PreviewMacroTests: XCTestCase { static func makePreview() throws -> DeveloperToolsSupport::Preview { DeveloperToolsSupport::Preview { - OpenSwiftUI::Group { + func __b_buildView(@OpenSwiftUI::ViewBuilder body: () -> any OpenSwiftUI::View) -> any OpenSwiftUI::View { + body() + } + return __b_buildView { } - ._previewVC() } } } From f34611447665a2dd3653164cb3398998ac19c298 Mon Sep 17 00:00:00 2001 From: Kyle Date: Sun, 18 Oct 2026 12:59:01 +0800 Subject: [PATCH 2/2] refactor: use canImport(Darwin) for Apple platform guards --- Sources/COpenSwiftUI/Util/PreviewProvider.m | 3 --- .../Accessibility/AccessibilityChildBehavior.swift | 2 +- .../Accessibility/AccessibilityDeferredAttachment.swift | 2 +- Sources/OpenSwiftUI/Accessibility/AccessibilityFocus.swift | 4 ++-- Sources/OpenSwiftUI/Accessibility/AccessibilityRole.swift | 2 +- Sources/OpenSwiftUI/App/App/Stdout/StdoutApp.swift | 2 +- Sources/OpenSwiftUI/Event/Focus/FocusItem.swift | 2 +- .../Event/Responder/PlatformUnaryViewResponder.swift | 2 +- Sources/OpenSwiftUI/Integration/LegacyPreviewProvider.swift | 2 +- Sources/OpenSwiftUI/Integration/PreviewShims.swift | 2 +- .../OpenSwiftUI/View/Control/Button/BorderedButtonStyle.swift | 2 +- 11 files changed, 11 insertions(+), 14 deletions(-) diff --git a/Sources/COpenSwiftUI/Util/PreviewProvider.m b/Sources/COpenSwiftUI/Util/PreviewProvider.m index 1269c49ab..30ad208b3 100644 --- a/Sources/COpenSwiftUI/Util/PreviewProvider.m +++ b/Sources/COpenSwiftUI/Util/PreviewProvider.m @@ -5,8 +5,6 @@ #include "OpenSwiftUIBase.h" #if OPENSWIFTUI_TARGET_OS_DARWIN -#include -#if TARGET_OS_OSX || TARGET_OS_IOS || TARGET_OS_VISION #import #include @@ -385,5 +383,4 @@ + (void)load { #undef PREVIEW_PTRAUTH #endif /* __arm64__ || __x86_64__ */ -#endif /* TARGET_OS_OSX || TARGET_OS_IOS || TARGET_OS_VISION */ #endif /* OPENSWIFTUI_TARGET_OS_DARWIN */ diff --git a/Sources/OpenSwiftUI/Accessibility/AccessibilityChildBehavior.swift b/Sources/OpenSwiftUI/Accessibility/AccessibilityChildBehavior.swift index c6c05edf3..f5f5b1393 100644 --- a/Sources/OpenSwiftUI/Accessibility/AccessibilityChildBehavior.swift +++ b/Sources/OpenSwiftUI/Accessibility/AccessibilityChildBehavior.swift @@ -312,7 +312,7 @@ public struct AccessibilityChildBehavior: Hashable { for index in children.indices where children[index].platformElement != nil { let bridgedProperties = Graph.withoutUpdate { childProperties[index].bridgedElement.map { element -> AccessibilityProperties in - #if os(macOS) || os(iOS) || os(visionOS) + #if canImport(Darwin) element.bridgedProperties #else _openSwiftUIPlatformUnimplementedFailure() diff --git a/Sources/OpenSwiftUI/Accessibility/AccessibilityDeferredAttachment.swift b/Sources/OpenSwiftUI/Accessibility/AccessibilityDeferredAttachment.swift index b33d492f5..c2c174584 100644 --- a/Sources/OpenSwiftUI/Accessibility/AccessibilityDeferredAttachment.swift +++ b/Sources/OpenSwiftUI/Accessibility/AccessibilityDeferredAttachment.swift @@ -203,7 +203,7 @@ extension AccessibilityAttachment { var properties = properties let bridgedProperties = Graph.withoutUpdate { properties.bridgedElement.map { element -> AccessibilityProperties in - #if os(macOS) || os(iOS) || os(visionOS) + #if canImport(Darwin) element.bridgedProperties #else _openSwiftUIPlatformUnimplementedFailure() diff --git a/Sources/OpenSwiftUI/Accessibility/AccessibilityFocus.swift b/Sources/OpenSwiftUI/Accessibility/AccessibilityFocus.swift index 9be20e4d8..c02f85da7 100644 --- a/Sources/OpenSwiftUI/Accessibility/AccessibilityFocus.swift +++ b/Sources/OpenSwiftUI/Accessibility/AccessibilityFocus.swift @@ -36,7 +36,7 @@ struct AccessibilityFocus { if let node = platformAccessibilityElement.accessibilityNodeForPlatformElement { return node } - #if os(iOS) || os(visionOS) || os(macOS) + #if canImport(Darwin) var node: AccessibilityNode? platformAccessibilityElement.traverseAncestors { element in if let ancestor = element as? AccessibilityNode { @@ -70,7 +70,7 @@ struct AccessibilityFocus { ancestor == focusStoreNode { return .platformChildFocused } - #if os(iOS) || os(visionOS) || os(macOS) + #if canImport(Darwin) if let ancestor = ancestorAccessibilityNode { var isContainerChildFocused = false ancestor.traverseAncestors { element in diff --git a/Sources/OpenSwiftUI/Accessibility/AccessibilityRole.swift b/Sources/OpenSwiftUI/Accessibility/AccessibilityRole.swift index a76af973c..52d8e5353 100644 --- a/Sources/OpenSwiftUI/Accessibility/AccessibilityRole.swift +++ b/Sources/OpenSwiftUI/Accessibility/AccessibilityRole.swift @@ -13,7 +13,7 @@ import OpenSwiftUI_SPI struct AccessibilityRole { var resolved: Resolved - #if !os(macOS) && !os(iOS) && !os(visionOS) + #if !canImport(Darwin) struct Resolved { var traits: AXOpenSwiftUITraits var automationType: AXAutomationType? diff --git a/Sources/OpenSwiftUI/App/App/Stdout/StdoutApp.swift b/Sources/OpenSwiftUI/App/App/Stdout/StdoutApp.swift index f36ae1c10..84d0bdfd0 100644 --- a/Sources/OpenSwiftUI/App/App/Stdout/StdoutApp.swift +++ b/Sources/OpenSwiftUI/App/App/Stdout/StdoutApp.swift @@ -29,7 +29,7 @@ func runStdoutApp( print("OpenSwiftUI stdout renderer: no scene to render") return } - #if os(macOS) || os(iOS) || os(visionOS) + #if canImport(Darwin) let rootView = item.value.view .frame(width: options.surface.width, height: options.surface.height) .rootEnvironment(scenePhase: .active, sceneID: item.id) diff --git a/Sources/OpenSwiftUI/Event/Focus/FocusItem.swift b/Sources/OpenSwiftUI/Event/Focus/FocusItem.swift index ad8156ba8..1f404ead4 100644 --- a/Sources/OpenSwiftUI/Event/Focus/FocusItem.swift +++ b/Sources/OpenSwiftUI/Event/Focus/FocusItem.swift @@ -218,7 +218,7 @@ private struct PlatformSubtreeIterator: Sequence, IteratorProtocol { var count: Int = 0 mutating func next() -> PlatformView? { - #if os(iOS) || os(visionOS) || os(macOS) + #if canImport(Darwin) #if os(iOS) || os(visionOS) guard count < 10 else { return nil } #else diff --git a/Sources/OpenSwiftUI/Event/Responder/PlatformUnaryViewResponder.swift b/Sources/OpenSwiftUI/Event/Responder/PlatformUnaryViewResponder.swift index 469e4849e..a03429231 100644 --- a/Sources/OpenSwiftUI/Event/Responder/PlatformUnaryViewResponder.swift +++ b/Sources/OpenSwiftUI/Event/Responder/PlatformUnaryViewResponder.swift @@ -5,7 +5,7 @@ // Audited for 6.5.4 // Status: Complete -#if os(iOS) || os(visionOS) || os(macOS) +#if canImport(Darwin) @_spi(ForOpenSwiftUIOnly) import OpenSwiftUICore diff --git a/Sources/OpenSwiftUI/Integration/LegacyPreviewProvider.swift b/Sources/OpenSwiftUI/Integration/LegacyPreviewProvider.swift index a931b4f2b..153529868 100644 --- a/Sources/OpenSwiftUI/Integration/LegacyPreviewProvider.swift +++ b/Sources/OpenSwiftUI/Integration/LegacyPreviewProvider.swift @@ -2,7 +2,7 @@ // LegacyPreviewProvider.swift // OpenSwiftUI -#if canImport(SwiftUI) && (os(macOS) || os(iOS) || os(visionOS)) +#if canImport(Darwin) import OpenSwiftUICore import SwiftUI diff --git a/Sources/OpenSwiftUI/Integration/PreviewShims.swift b/Sources/OpenSwiftUI/Integration/PreviewShims.swift index a4019951f..07516f589 100644 --- a/Sources/OpenSwiftUI/Integration/PreviewShims.swift +++ b/Sources/OpenSwiftUI/Integration/PreviewShims.swift @@ -25,7 +25,7 @@ extension OpenSwiftUI.View { } #endif -#if canImport(DeveloperToolsSupport) && canImport(SwiftUI) && (os(macOS) || os(iOS) || os(visionOS)) +#if canImport(DeveloperToolsSupport) public import DeveloperToolsSupport import SwiftUI diff --git a/Sources/OpenSwiftUI/View/Control/Button/BorderedButtonStyle.swift b/Sources/OpenSwiftUI/View/Control/Button/BorderedButtonStyle.swift index e41ffbfae..f03074a8f 100644 --- a/Sources/OpenSwiftUI/View/Control/Button/BorderedButtonStyle.swift +++ b/Sources/OpenSwiftUI/View/Control/Button/BorderedButtonStyle.swift @@ -53,7 +53,7 @@ public struct BorderedButtonStyle: PrimitiveButtonStyle { } public func makeBody(configuration: Configuration) -> some View { - #if os(macOS) || os(iOS) || os(visionOS) + #if canImport(Darwin) Button(configuration) #if os(iOS) || os(visionOS) .modifier(StaticIf(