I have a widget with a button that prints "Hello" to the console when tapped. This button is shown only on iOS 17.x and macOS 14.x, and is supposed to be hidden on lower versions.
Platform versions tested: iOS 16.6, iOS 17 beta 7 (21A5319a), macOS 13.4.1
Xcode version used: 15.0 beta 7 (15A5229h).
Expected behaviour: The button is hidden on iOS 16.x and macOS 13.x, and shown only on iOS 17 and macOS 14.
Observed behaviour: The button is hidden on iOS 16.6. However, on macOS 13.4.1, the widget crashes with this error:
dyld[5266]: Symbol not found: _$s7SwiftUI6ButtonV012_AppIntents_aB0E6intent5labelACyxGqd___xyXEtc0dE00D6IntentRd__lufC Referenced from: <3EB03A2B-BF9A-31EC-88B9-B4CF015DD35D> /Users/user/Library/Developer/Xcode/DerivedData/WidgetIntentTest-hfjndspaaxqvyuhgdzlznjikilce/Build/Products/Debug/WidgetIntentTest.app/Contents/PlugIns/WidgetExtension.appex/Contents/MacOS/WidgetExtension Expected in: <0A9F8825-DAF1-39A5-953C-C5ECACDC1B0B> /System/Library/Frameworks/_AppIntents_SwiftUI.framework/Versions/A/_AppIntents_SwiftUI
Here's the code:
The widget code with the button:
import WidgetKit
import SwiftUI
struct WidgetsEntryView: View {
var entry: Provider.Entry
@available(iOS 17, macOS 14, *)
var button: some View {
Button(intent: SayHelloIntent()) {
Text("Say hello")
}
}
var body: some View {
VStack {
Text("Hello there")
#if os(iOS)
if #available(iOS 17, *) {
button
}
#elseif os(macOS)
if #available(macOS 14, *) {
button
}
#endif
}
//ignore this if on iOS 16 or macOS 13
.widgetBackground(backgroundView: Color.clear)
}
}
The rest of the widget code
struct Provider: TimelineProvider {
func placeholder(in context: Context) -> SimpleEntry {
SimpleEntry(date: Date())
}
func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) {
completion(SimpleEntry(date: Date()))
}
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
let timeline = Timeline(entries: [SimpleEntry(date: Date())], policy: .atEnd)
completion(timeline)
}
}
struct SimpleEntry: TimelineEntry {
let date: Date
}
struct Widgets: Widget {
let kind: String = "Widgets"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider()) { entry in
WidgetsEntryView(entry: entry)
}
.configurationDisplayName("My Widget")
.description("This is an example widget.")
}
}
@main
struct WidgetIntentTestBundle: WidgetBundle {
var body: some Widget {
Widgets()
}
}
//ignore this if on iOS 16 or macOS 13
extension View {
func widgetBackground(backgroundView: some View) -> some View {
#if os(iOS)
if #available(iOSApplicationExtension 17.0, *) {
return containerBackground(for: .widget) {
backgroundView
}
} else {
return background(backgroundView)
}
#elseif os(macOS)
return background(backgroundView)
#endif
}
}
App Intent
import AppIntents
import WidgetKit
struct SayHelloIntent: AppIntent {
static var title: LocalizedStringResource = "Say Hello"
static var description = IntentDescription("prints hello to the console.")
func perform() async throws -> some IntentResult {
print("Hello")
return .result()
}
}
The app's ContentView
struct ContentView: View {
var body: some View {
VStack {
Text("Hello World")
}
.padding()
}
}
Is anyone else experiencing this issue? The Button initialiser I'm using is marked as available on macOS 13, so I don't see a reason why the widget would crash with that error (which I understand is because it can't find the Button code in SwiftUI on macOS 13.
For what it's worth the widget doesn't crash and works as expected when built using Mac catalyst 16.
Any help is welcome!