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 String
s 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