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.
Post History
Background + Example Code Let's say I have a SwiftUI ViewModel like so: class ViewModel: ObservableObject { @Published var strs: [String] = [] func fetchStrs() async { // T...
#3: Post edited
# Background + Code- Let's say I have a SwiftUI ViewModel like so:
- ```swift
- 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:
- ```swift
- init() {
- Task {
- await fetchStrs()
- }
- }
- ```
- Or I could use a [`.onAppear`](https://developer.apple.com/documentation/swiftui/view/onappear(perform:)) method in my `View` ([`.task`](https://developer.apple.com/documentation/swiftui/view/task(priority:_:)) does basically the same thing with a `Task` in `onAppear`) like so:
- ```swift
- 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?**
- # Background + Example Code
- Let's say I have a SwiftUI ViewModel like so:
- ```swift
- 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:
- ```swift
- init() {
- Task {
- await fetchStrs()
- }
- }
- ```
- Or I could use a [`.onAppear`](https://developer.apple.com/documentation/swiftui/view/onappear(perform:)) method in my `View` ([`.task`](https://developer.apple.com/documentation/swiftui/view/task(priority:_:)) does basically the same thing with a `Task` in `onAppear`) like so:
- ```swift
- 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?**
#2: Post edited
- # Background + Code
- Let's say I have a SwiftUI ViewModel like so:
- ```swift
- 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:
- ```swift
- init() {
- Task {
- await fetchStrs()
- }
- }
- ```
- Or I could use a [`.onAppear`](https://developer.apple.com/documentation/swiftui/view/onappear(perform:)) method in my `View` ([`.task`](https://developer.apple.com/documentation/swiftui/view/task(priority:_:)) does basically the same thing with a `Task` in `onAppear`) like so:
- ```swift
- struct ExampleView: View {
@ObservableObject 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?**
- # Background + Code
- Let's say I have a SwiftUI ViewModel like so:
- ```swift
- 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:
- ```swift
- init() {
- Task {
- await fetchStrs()
- }
- }
- ```
- Or I could use a [`.onAppear`](https://developer.apple.com/documentation/swiftui/view/onappear(perform:)) method in my `View` ([`.task`](https://developer.apple.com/documentation/swiftui/view/task(priority:_:)) does basically the same thing with a `Task` in `onAppear`) like so:
- ```swift
- 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?**
#1: Initial revision
Is there a correct way to fetch data with a SwiftUI ViewModel?
# Background + Code Let's say I have a SwiftUI ViewModel like so: ```swift 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: ```swift init() { Task { await fetchStrs() } } ``` Or I could use a [`.onAppear`](https://developer.apple.com/documentation/swiftui/view/onappear(perform:)) method in my `View` ([`.task`](https://developer.apple.com/documentation/swiftui/view/task(priority:_:)) does basically the same thing with a `Task` in `onAppear`) like so: ```swift struct ExampleView: View { @ObservableObject 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?**