Skip to content

Commit 75dff0e

Browse files
authored
Add SensoryFeedback API support (#668)
1 parent 2846907 commit 75dff0e

File tree

10 files changed

+918
-5
lines changed

10 files changed

+918
-5
lines changed

Configurations/Shared/basic/OpenSwiftUI.xcconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ GCC_PREPROCESSOR_DEFINITIONS_OPENSWIFTUI = OPENSWIFTUI=1
22

33
SWIFT_ACTIVE_COMPILATION_CONDITIONS_OPENSWIFTUI = OPENSWIFTUI
44

5-
OPENSWIFTUI_AVAILABILITY_MACRO = "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v1_0:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v1_4:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v2_0:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_macOS_v2_0:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v2_1:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v2_3:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v3_0:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v3_2:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v3_4:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v4_0:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v4_1:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v4_4:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v5_0:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v5_1:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v5_2:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v5_4:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v6_0:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v7_0:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0"
5+
OPENSWIFTUI_AVAILABILITY_MACRO = "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v1_0:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v1_4:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v2_0:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_macOS_v2_0:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v2_1:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v2_3:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v3_0:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v3_2:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v3_4:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v4_0:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v4_1:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v4_4:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v5_0:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v5_1:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v5_2:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v5_4:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v5_5:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v6_0:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v7_0:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0"
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
OPENSWIFTUI_AVAILABILITY_MACRO = "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v1_0:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v1_4:iOS 13.4, macOS 10.15.4, tvOS 13.4, watchOS 6.2" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v2_0:iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_macOS_v2_0:macOS 11.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v2_1:iOS 14.2, macOS 11.0, tvOS 14.1, watchOS 7.1" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v2_3:iOS 14.5, macOS 11.3, tvOS 14.5, watchOS 7.4" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v3_0:iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v3_2:iOS 15.2, macOS 12.1, tvOS 15.2, watchOS 8.3" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v3_4:iOS 15.4, macOS 12.3, tvOS 15.4, watchOS 8.5" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v4_0:iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v4_1:iOS 16.1, macOS 13.0, tvOS 16.1, watchOS 9.1" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v4_4:iOS 16.4, macOS 13.3, tvOS 16.4, watchOS 9.4" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v5_0:iOS 17.0, macOS 14.0, tvOS 17.0, watchOS 10.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v5_1:iOS 17.1, macOS 14.1, tvOS 17.1, watchOS 10.1, visionOS 1.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v5_2:iOS 17.2, macOS 14.2, tvOS 17.2, watchOS 10.2, visionOS 1.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v5_4:iOS 17.4, macOS 14.4, tvOS 17.4, watchOS 10.4, visionOS 1.1" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v6_0:iOS 18.0, macOS 15.0, tvOS 18.0, watchOS 11.0, visionOS 2.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v7_0:iOS 19.0, macOS 16.0, tvOS 19.0, watchOS 12.0, visionOS 3.0"
1+
OPENSWIFTUI_AVAILABILITY_MACRO = "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v1_0:iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v1_4:iOS 13.4, macOS 10.15.4, tvOS 13.4, watchOS 6.2" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v2_0:iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_macOS_v2_0:macOS 11.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v2_1:iOS 14.2, macOS 11.0, tvOS 14.1, watchOS 7.1" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v2_3:iOS 14.5, macOS 11.3, tvOS 14.5, watchOS 7.4" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v3_0:iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v3_2:iOS 15.2, macOS 12.1, tvOS 15.2, watchOS 8.3" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v3_4:iOS 15.4, macOS 12.3, tvOS 15.4, watchOS 8.5" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v4_0:iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v4_1:iOS 16.1, macOS 13.0, tvOS 16.1, watchOS 9.1" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v4_4:iOS 16.4, macOS 13.3, tvOS 16.4, watchOS 9.4" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v5_0:iOS 17.0, macOS 14.0, tvOS 17.0, watchOS 10.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v5_1:iOS 17.1, macOS 14.1, tvOS 17.1, watchOS 10.1, visionOS 1.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v5_2:iOS 17.2, macOS 14.2, tvOS 17.2, watchOS 10.2, visionOS 1.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v5_4:iOS 17.4, macOS 14.4, tvOS 17.4, watchOS 10.4, visionOS 1.1" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v5_5:iOS 17.5, macOS 14.5, tvOS 17.5, watchOS 10.5, visionOS 1.2" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v6_0:iOS 18.0, macOS 15.0, tvOS 18.0, watchOS 11.0, visionOS 2.0" "-Xfrontend" "-enable-experimental-feature" "-Xfrontend" "AvailabilityMacro=OpenSwiftUI_v7_0:iOS 19.0, macOS 16.0, tvOS 19.0, watchOS 12.0, visionOS 3.0"

Package.resolved

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,7 @@ extension [SwiftSetting] {
469469
.enableExperimentalFeature("AvailabilityMacro=OpenSwiftUI_v5_1:\(ignoreAvailability ? minimumVersion : "iOS 17.1, macOS 14.1, tvOS 17.1, watchOS 10.1, visionOS 1.0")"),
470470
.enableExperimentalFeature("AvailabilityMacro=OpenSwiftUI_v5_2:\(ignoreAvailability ? minimumVersion : "iOS 17.2, macOS 14.2, tvOS 17.2, watchOS 10.2, visionOS 1.0")"),
471471
.enableExperimentalFeature("AvailabilityMacro=OpenSwiftUI_v5_4:\(ignoreAvailability ? minimumVersion : "iOS 17.4, macOS 14.4, tvOS 17.4, watchOS 10.4, visionOS 1.1")"),
472+
.enableExperimentalFeature("AvailabilityMacro=OpenSwiftUI_v5_5:\(ignoreAvailability ? minimumVersion : "iOS 17.5, macOS 14.5, tvOS 17.5, watchOS 10.5, visionOS 1.2")"),
472473
.enableExperimentalFeature("AvailabilityMacro=OpenSwiftUI_v6_0:\(ignoreAvailability ? minimumVersion : "iOS 18.0, macOS 15.0, tvOS 18.0, watchOS 11.0, visionOS 2.0")"),
473474
.enableExperimentalFeature("AvailabilityMacro=OpenSwiftUI_v7_0:\(ignoreAvailability ? minimumVersion : "iOS 19.0, macOS 16.0, tvOS 19.0, watchOS 12.0, visionOS 3.0")"),
474475
.enableExperimentalFeature("AvailabilityMacro=_distantFuture:iOS 99.0, macOS 99.0, tvOS 99.0, watchOS 99.0, visionOS 99.0"),

Sources/OpenSwiftUI/Integration/Hosting/UIKit/View/UIHostingView.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,11 @@ open class _UIHostingView<Content>: UIView, XcodeViewDebugDataProvider where Con
124124
didChangeColorScheme(from: oldValue)
125125
}
126126
}
127-
127+
128+
// TODO
129+
130+
let feedbackCache: UIKitSensoryFeedbackCache<Content> = .init()
131+
128132
// TODO
129133

130134
// var currentAccessibilityFocusStore: AccessibilityFocusStore = .init()
@@ -177,7 +181,7 @@ open class _UIHostingView<Content>: UIView, XcodeViewDebugDataProvider where Con
177181
base.setupNotifications()
178182
}
179183
// RepresentableContextValues.current =
180-
184+
feedbackCache.host = self
181185
// TODO
182186
HostingViewRegistry.shared.add(self)
183187
Update.end()
@@ -512,6 +516,8 @@ extension _UIHostingView: ViewRendererHost {
512516
if let displayGamut = DisplayGamut(rawValue: traitCollection.displayGamut.rawValue) {
513517
environment.displayGamut = displayGamut
514518
}
519+
// TODO
520+
environment.feedbackCache = feedbackCache
515521
viewGraph.setEnvironment(environment)
516522
}
517523

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//
2+
// AppKitFeedbackImplementation.swift
3+
// OpenSwiftUI
4+
//
5+
// Audited for 6.5.4
6+
// Status: Complete
7+
8+
#if os(macOS)
9+
import AppKit
10+
import OpenSwiftUICore
11+
12+
// MARK: - View + platformSensoryFeedback
13+
14+
extension View {
15+
nonisolated func platformSensoryFeedback<Base>(
16+
_ base: Base
17+
) -> some View where Base: SensoryFeedbackGeneratorModifier {
18+
modifier(base)
19+
}
20+
}
21+
22+
// MARK: - HapticFeedbackManagerImplementation
23+
24+
struct HapticFeedbackManagerImplementation: PlatformSensoryFeedback {
25+
var pattern: NSHapticFeedbackManager.FeedbackPattern
26+
27+
func setUp() {
28+
_openSwiftUIEmptyStub()
29+
}
30+
31+
func tearDown() {
32+
_openSwiftUIEmptyStub()
33+
}
34+
35+
func generate() {
36+
NSHapticFeedbackManager.defaultPerformer.perform(
37+
pattern,
38+
performanceTime: .default
39+
)
40+
}
41+
}
42+
43+
// MARK: - FeedbackRequestContext
44+
45+
struct FeedbackRequestContext {
46+
func implementation(type: SensoryFeedback.FeedbackType) -> (any PlatformSensoryFeedback)? {
47+
switch type {
48+
case .alignment: HapticFeedbackManagerImplementation(pattern: .alignment)
49+
case .levelChange: HapticFeedbackManagerImplementation(pattern: .levelChange)
50+
default: nil
51+
}
52+
}
53+
}
54+
#endif

0 commit comments

Comments
 (0)