Skip to content

Commit d955bc2

Browse files
authored
fix(swift): updated concurrency in quickstart (#7828)
1 parent d230333 commit d955bc2

File tree

1 file changed

+76
-65
lines changed
  • src/pages/[platform]/start/quickstart

1 file changed

+76
-65
lines changed

src/pages/[platform]/start/quickstart/index.mdx

Lines changed: 76 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1884,7 +1884,15 @@ Once you are done, add the API dependencies to your project. Select **File > Add
18841884

18851885
![Shows the Amplify API library for Swift selected](/images/lib/getting-started/ios/set-up-swift-9.png)
18861886

1887-
After adding the dependencies, update the `init` part of your `MyAmplifyAppApp.swift` file with the following code:
1887+
After adding the dependencies, update the `import` part of your `MyAmplifyAppApp.swift` file with the following code:
1888+
1889+
```swift title="MyAmplifyAppApp.swift"
1890+
import Amplify
1891+
import AWSCognitoAuthPlugin
1892+
import AWSAPIPlugin
1893+
```
1894+
1895+
Then, update the `init()` part of your `MyAmplifyAppApp.swift` file with the following code:
18881896

18891897
```swift title="MyAmplifyAppApp.swift"
18901898
init() {
@@ -1902,31 +1910,31 @@ Create a new file called `TodoViewModel.swift` and the `createTodo` function wit
19021910

19031911
```swift title="TodoViewModel.swift"
19041912
import Amplify
1913+
import SwiftUI
19051914

19061915
@MainActor
19071916
class TodoViewModel: ObservableObject {
1908-
func createTodo() {
1917+
func createTodo() async {
19091918
let creationTime = Temporal.DateTime.now()
19101919
let todo = Todo(
1911-
content: "Random Todo \(creationTime)",
1920+
content: "Random Todo \(creationTime.iso8601String)",
19121921
isDone: false,
19131922
createdAt: creationTime,
19141923
updatedAt: creationTime
19151924
)
1916-
Task {
1917-
do {
1918-
let result = try await Amplify.API.mutate(request: .create(todo))
1919-
switch result {
1920-
case .success(let todo):
1921-
print("Successfully created todo: \(todo)")
1922-
case .failure(let error):
1923-
print("Got failed result with \(error.errorDescription)")
1924-
}
1925-
} catch let error as APIError {
1926-
print("Failed to create todo: ", error)
1927-
} catch {
1928-
print("Unexpected error: \(error)")
1925+
do {
1926+
let result = try await Amplify.API.mutate(request: .create(todo))
1927+
switch result {
1928+
case .success(let todo):
1929+
print("Successfully created todo: \(todo)")
1930+
todos.append(todo)
1931+
case .failure(let error):
1932+
print("Got failed result with \(error.errorDescription)")
19291933
}
1934+
} catch let error as APIError {
1935+
print("Failed to create todo: ", error)
1936+
} catch {
1937+
print("Unexpected error: \(error)")
19301938
}
19311939
}
19321940
}
@@ -1946,23 +1954,21 @@ class TodoViewModel: ObservableObject {
19461954
/// ...
19471955
}
19481956

1949-
func listTodos() {
1957+
func listTodos() async {
19501958
let request = GraphQLRequest<Todo>.list(Todo.self)
1951-
Task {
1952-
do {
1953-
let result = try await Amplify.API.query(request: request)
1954-
switch result {
1955-
case .success(let todos):
1956-
print("Successfully retrieved list of todos: \(todos)")
1957-
self.todos = todos.elements
1958-
case .failure(let error):
1959-
print("Got failed result with \(error.errorDescription)")
1960-
}
1961-
} catch let error as APIError {
1962-
print("Failed to query list of todos: ", error)
1963-
} catch {
1964-
print("Unexpected error: \(error)")
1959+
do {
1960+
let result = try await Amplify.API.query(request: request)
1961+
switch result {
1962+
case .success(let todos):
1963+
print("Successfully retrieved list of todos: \(todos)")
1964+
self.todos = todos.elements
1965+
case .failure(let error):
1966+
print("Got failed result with \(error.errorDescription)")
19651967
}
1968+
} catch let error as APIError {
1969+
print("Failed to query list of todos: ", error)
1970+
} catch {
1971+
print("Unexpected error: \(error)")
19661972
}
19671973
}
19681974
}
@@ -1987,8 +1993,7 @@ struct ContentView: View {
19871993
}
19881994
}
19891995
Button(action: {
1990-
vm.createTodo()
1991-
vm.listTodos()
1996+
Task { await vm.createTodo() }
19921997
}) {
19931998
HStack {
19941999
Text("Add a New Todo")
@@ -2026,49 +2031,46 @@ class TodoViewModel: ObservableObject {
20262031
// ...
20272032
}
20282033

2029-
func deleteTodos(indexSet: IndexSet) {
2034+
func deleteTodos(indexSet: IndexSet) async {
20302035
for index in indexSet {
2031-
let todo = todos[index]
2032-
Task {
2033-
do {
2034-
let result = try await Amplify.API.mutate(request: .delete(todo))
2035-
switch result {
2036-
case .success(let todo):
2037-
print("Successfully deleted todo: \(todo)")
2038-
case .failure(let error):
2039-
print("Got failed result with \(error.errorDescription)")
2040-
}
2041-
} catch let error as APIError {
2042-
print("Failed to deleted todo: ", error)
2043-
} catch {
2044-
print("Unexpected error: \(error)")
2045-
}
2046-
}
2047-
}
2048-
}
2049-
2050-
func updateTodo(todo: Todo) {
2051-
Task {
20522036
do {
2053-
let result = try await Amplify.API.mutate(request: .update(todo))
2037+
let todo = todos[index]
2038+
let result = try await Amplify.API.mutate(request: .delete(todo))
20542039
switch result {
20552040
case .success(let todo):
2056-
print("Successfully updated todo: \(todo)")
2041+
print("Successfully deleted todo: \(todo)")
2042+
todos.remove(at: index)
20572043
case .failure(let error):
20582044
print("Got failed result with \(error.errorDescription)")
20592045
}
20602046
} catch let error as APIError {
2061-
print("Failed to updated todo: ", error)
2047+
print("Failed to deleted todo: ", error)
20622048
} catch {
20632049
print("Unexpected error: \(error)")
20642050
}
20652051
}
20662052
}
2053+
2054+
func updateTodo(todo: Todo) async {
2055+
do {
2056+
let result = try await Amplify.API.mutate(request: .update(todo))
2057+
switch result {
2058+
case .success(let todo):
2059+
print("Successfully updated todo: \(todo)")
2060+
case .failure(let error):
2061+
print("Got failed result with \(error.errorDescription)")
2062+
}
2063+
} catch let error as APIError {
2064+
print("Failed to updated todo: ", error)
2065+
} catch {
2066+
print("Unexpected error: \(error)")
2067+
}
2068+
}
20672069
}
20682070

20692071
```
20702072

2071-
Update the `List` in the `ContentView.swift` file with the following code:
2073+
Update the `List` in the `ContentView.swift` file with code to fetch the todos when the View is displayed and to call `deleteTodos(indexSet:)` when the user left-swipe a todo.
20722074

20732075
```swift title="ContentView.swift"
20742076
struct ContentView: View {
@@ -2081,11 +2083,14 @@ struct ContentView: View {
20812083
List {
20822084
ForEach($vm.todos, id: \.id) { todo in
20832085
TodoRow(vm: vm, todo: todo)
2084-
}.onDelete { indexSet in
2085-
vm.deleteTodos(indexSet: indexSet)
2086-
vm.listTodos()
2086+
}
2087+
.onDelete { indexSet in
2088+
Task { await vm.deleteTodos(indexSet: indexSet) }
20872089
}
20882090
}
2091+
.task {
2092+
await vm.listTodos()
2093+
}
20892094
// ... Add new Todo button
20902095
}
20912096
}
@@ -2096,6 +2101,8 @@ struct ContentView: View {
20962101
Lastly, create a new file called `TodoRow.swift` with the following code:
20972102

20982103
```swift title="TodoRow.swift"
2104+
import SwiftUI
2105+
20992106
struct TodoRow: View {
21002107
@ObservedObject var vm: TodoViewModel
21012108
@Binding var todo: Todo
@@ -2104,15 +2111,19 @@ struct TodoRow: View {
21042111
Toggle(isOn: $todo.isDone) {
21052112
Text(todo.content ?? "")
21062113
}
2107-
.toggleStyle(SwitchToggleStyle())
2114+
.toggleStyle(.switch)
21082115
.onChange(of: todo.isDone) { _, newValue in
21092116
var updatedTodo = todo
21102117
updatedTodo.isDone = newValue
2111-
vm.updateTodo(todo: updatedTodo)
2112-
vm.listTodos()
2118+
Task { await vm.updateTodo(todo: updatedTodo) }
21132119
}
21142120
}
21152121
}
2122+
2123+
#Preview {
2124+
@State var todo = Todo(content: "Hello Todo World 20240706T15:23:42.256Z", isDone: false)
2125+
return TodoRow(vm: TodoViewModel(), todo: $todo)
2126+
}
21162127
```
21172128

21182129
This will update the UI to show a toggle to update the todo `isDone` and a swipe to delete the todo. Now if you run the application you should see the following flow.

0 commit comments

Comments
 (0)