Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
Is there a correct way to fetch data with a SwiftUI ViewModel?
Background + Example Code
Let's say I have a SwiftUI ViewModel like so:
class ViewModel: ObservableObject {
@Published var strs: [String] = []
func fetchStrs() async {
// This function would have fetching logic for whatever type the model stored
// Here, we are just storing some strings for simplicity.
// We wait one second to mimic an API Call
try await Task.sleep(nanoseconds: UInt64(1 * Double(NSEC_PER_SEC)))
self.strs = ["Hello", "World", "!"]
}
}
Since the ViewModel would have that function to fetchStrs from the API, we could get this information in two ways. I could either use a Task and get the Strings in the initializer like so:
init() {
Task {
await fetchStrs()
}
}
Or I could use a .onAppear method in my View (.task does basically the same thing with a Task in onAppear) like so:
struct ExampleView: View {
@StateObject var viewModel = ViewModel()
var body: some View {
//... List of strings here
.task {
viewModel.fetchStrs()
}
}
}
Question
As seen above, I have two major ways to get dynamic data from an API at runtime. However, which one should I use? Are there any sort of Swift style conventions that lean toward one or the other? I recognize that .task or .onAppear may be later than expected in some cases, but that shouldn't matter because the method is asynchronous. Is there a correct way of getting these data, or is it developer preference?

0 comment threads