10 October 2022
As of Xcode 14.0, adding a backgroundTask
modifier to anything more than a single view will likely cause a not super-helpful compiler error.
Say you have something like this:
@main
struct WeatherApp: App {
@StateObject var weatherData = WeatherDataStore()
var body: some Scene {
WindowGroup {
SimpleWeatherView()
.environmentObject(weatherData)
}
.backgroundTask(.appRefresh("WeatherCheck")) {
await updateWeatherData()
}
}
}
Xcode will not be happy, letting you know that Command CompileSwift failed with a nonzero exit code
. Not exactly the most helpful, though digging in to the build output yields this gem:
$@_opaqueReturnTypeOf("$s7SwiftUI5ScenePAAE14backgroundTask_6actionQrAA010BackgroundE0Vyqd__qd_0_G_qd_0_qd__YaYbcts8SendableRd__sAIRd_0_r0_lF", 0) __>>>, (), ()> // user: %38
Please submit a bug report (https://swift.org/contributing/#reporting-bugs) and include the project and the crash backtrace.
Turns out that for now you will need to encapsulate the view and its modifiers into a single view like this:
@main
struct WeatherApp: App {
var body: some Scene {
WindowGroup {
TemporaryWrapperView()
}
.backgroundTask(.appRefresh("WeatherCheck")) {
await updateWeatherData()
}
}
}
struct TemporaryWrapperView: View {
@StateObject var weatherData = WeatherDataStore()
var body: some View {
SimpleWeatherView()
.environmentObject(weatherData)
}
}
For more details check out this thread on the Apple Developer forums. As stated there, if all is well this workaround should hopefully not be needed once Xcode 14.1 ships.