I would like to be able to create a #Preview that uses some values that are computed with async/await.
Below is a sample code with the first 2 previews working fine. The last one calling an async func fails.
import SwiftUI
import SwiftData
struct TestUIView: View {
var passedValue:String
var body: some View {
Text("passedValue: \(passedValue)")
}
}
#Preview {
let passedValue="My value"
return TestUIView(passedValue: passedValue)
}
#Preview {
let passedValue=MyClass.getValue()
return TestUIView(passedValue: passedValue)
}
#Preview {
var passedValue:String {
get async {
return await MyClass.getValueAsync()
}
}
return TestUIView(passedValue: passedValue)
}
class MyClass {
public class func getValue() -> String {
return "from getValue"
}
public class func getValueAsync() async -> String {
return "from getValueAsync"
}
}
The Preview error is: Compiling failed: 'async' property access in a function that does not support concurrency
In the real app, the data passed on is created in async mode and once available passed on to the next View. I want to be able to use the same function that creates this data in the Preview, rather then creating some dummy data only for the #Preview.
The way you are going to solve this Preview Macro problem is the same way you would solve other issues such as using @State
variables: create a view struct within the macro.
#Preview("from getValueAsync") {
struct AsyncTestView: View {
@State var passedValue: String = ""
var body: some View {
TestUIView(passedValue: passedValue)
.task {
passedValue = await MyClass.getValueAsync()
}
}
}
return AsyncTestView()
}
You can also create it outside of your preview, but then archiving would not strip the code when creating a release. Another thing, If you are using multiple macros, it helps to name them.