diff --git a/public/images/lib/getting-started/ios/set-up-swift-6.png b/public/images/lib/getting-started/ios/set-up-swift-6.png index 0014e131281..ad8114dcdfc 100644 Binary files a/public/images/lib/getting-started/ios/set-up-swift-6.png and b/public/images/lib/getting-started/ios/set-up-swift-6.png differ diff --git a/src/pages/[platform]/start/quickstart/index.mdx b/src/pages/[platform]/start/quickstart/index.mdx index 52a33af50d1..df7b7be1482 100644 --- a/src/pages/[platform]/start/quickstart/index.mdx +++ b/src/pages/[platform]/start/quickstart/index.mdx @@ -1862,9 +1862,13 @@ const schema = a.schema({ Todo: a .model({ content: a.string(), +// highlight-start isDone: a.boolean().required() +// highlight-end }) +// highlight-start .authorization((allow) => [allow.owner()]) +// highlight-end }); export type Schema = ClientSchema; @@ -1872,7 +1876,9 @@ export type Schema = ClientSchema; export const data = defineData({ schema, authorizationModes: { +// highlight-start defaultAuthorizationMode: 'userPool' +// highlight-end } }); ``` @@ -1892,34 +1898,52 @@ Once you are done, add the API dependencies to your project. Select **File > Add ![Shows the Amplify API library for Swift selected](/images/lib/getting-started/ios/set-up-swift-9.png) -After adding the dependencies, update the `init` part of your `MyAmplifyAppApp.swift` file with the following code: +After adding the dependencies, import the `AWSAPIPlugin` and update the `init` part of your `MyAmplifyAppApp.swift` file with the following code: ```swift title="MyAmplifyAppApp.swift" -init() { - do { - try Amplify.add(plugin: AWSCognitoAuthPlugin()) - try Amplify.add(plugin: AWSAPIPlugin(modelRegistration: AmplifyModels())) - try Amplify.configure(with: .amplifyOutputs) - } catch { - print("Unable to configure Amplify \(error)") +import Amplify +import Authenticator +import AWSCognitoAuthPlugin +// highlight-start +import AWSAPIPlugin +// highlight-end +import SwiftUI + +@main +struct MyApp: App { + init() { + do { + try Amplify.add(plugin: AWSCognitoAuthPlugin()) +// highlight-start + try Amplify.add(plugin: AWSAPIPlugin(modelRegistration: AmplifyModels())) +// highlight-end + try Amplify.configure(with: .amplifyOutputs) + } catch { + print("Unable to configure Amplify \(error)") + } } + + // ... } ``` Create a new file called `TodoViewModel.swift` and the `createTodo` function the following code: ```swift title="TodoViewModel.swift" +import Foundation import Amplify @MainActor class TodoViewModel: ObservableObject { + @Published var todos: [Todo] = [] + func createTodo() { - let creationTime = Temporal.DateTime.now() + let creationTime = Date.now + .formatted(date: .omitted, time: .standard) + let todo = Todo( - content: "Random Todo \(creationTime)", - isDone: false, - createdAt: creationTime, - updatedAt: creationTime + content: "Random Todo - \(creationTime)", + isDone: false ) Task { do { @@ -1927,6 +1951,7 @@ class TodoViewModel: ObservableObject { switch result { case .success(let todo): print("Successfully created todo: \(todo)") + todos.append(todo) case .failure(let error): print("Got failed result with \(error.errorDescription)") } @@ -1951,14 +1976,13 @@ class TodoViewModel: ObservableObject { @Published var todos: [Todo] = [] func createTodo() { - /// ... + // ... } - +// highlight-start func listTodos() { - let request = GraphQLRequest.list(Todo.self) Task { do { - let result = try await Amplify.API.query(request: request) + let result = try await Amplify.API.query(request: .list(Todo.self)) switch result { case .success(let todos): print("Successfully retrieved list of todos: \(todos)") @@ -1973,20 +1997,21 @@ class TodoViewModel: ObservableObject { } } } +// highlight-end } ``` -This will assign the value of the fetched todos into a Published object. +This will assign the value of the fetched todos into a Published object. Now let's update the UI code to observe the todos. Update the `VStack` in the `ContentView.swift` file with the following code: ```swift title="ContentView.swift" struct ContentView: View { - - // Create an observable object instance. +// highlight-start @StateObject var vm = TodoViewModel() +// highlight-end var body: some View { Authenticator { state in @@ -1996,17 +2021,17 @@ struct ContentView: View { await state.signOut() } } - Button(action: { - vm.createTodo() - vm.listTodos() - }) { +// highlight-start + Button(action: vm.createTodo) { HStack { - Text("Add a New Todo") + Text("Add Todo") Image(systemName: "plus") } } - .accessibilityLabel("New Todo") + .accessibilityLabel("Add Todo") } + .onAppear(perform: vm.listTodos) +// highlight-end } } } @@ -2036,6 +2061,7 @@ class TodoViewModel: ObservableObject { // ... } +// highlight-start func deleteTodos(indexSet: IndexSet) { for index in indexSet { let todo = todos[index] @@ -2045,6 +2071,7 @@ class TodoViewModel: ObservableObject { switch result { case .success(let todo): print("Successfully deleted todo: \(todo)") + todos.remove(at: index) case .failure(let error): print("Got failed result with \(error.errorDescription)") } @@ -2074,11 +2101,12 @@ class TodoViewModel: ObservableObject { } } } +// highlight-end } ``` -Update the `List` in the `ContentView.swift` file with the following code: +Add a `List` in the `ContentView.swift` file with the following code: ```swift title="ContentView.swift" struct ContentView: View { @@ -2088,14 +2116,19 @@ struct ContentView: View { Authenticator { state in VStack { // ... Sign out Button +// highlight-start List { - ForEach($vm.todos, id: \.id) { todo in - TodoRow(vm: vm, todo: todo) - }.onDelete { indexSet in - vm.deleteTodos(indexSet: indexSet) - vm.listTodos() + ForEach(vm.todos.indices, id: \.self) { index in + Toggle(isOn: $vm.todos[index].isDone) { + Text(vm.todos[index].content ?? "") + } + .onChange(of: vm.todos[index].isDone) { _, _ in + vm.updateTodo(todo: vm.todos[index]) + } } + .onDelete(perform: vm.deleteTodos(indexSet:)) } +// highlight-end // ... Add new Todo button } } @@ -2103,28 +2136,6 @@ struct ContentView: View { } ``` -Lastly, create a new file called `TodoRow.swift` with the following code: - -```swift title="TodoRow.swift" -struct TodoRow: View { - @ObservedObject var vm: TodoViewModel - @Binding var todo: Todo - - var body: some View { - Toggle(isOn: $todo.isDone) { - Text(todo.content ?? "") - } - .toggleStyle(SwitchToggleStyle()) - .onChange(of: todo.isDone) { _, newValue in - var updatedTodo = todo - updatedTodo.isDone = newValue - vm.updateTodo(todo: updatedTodo) - vm.listTodos() - } - } -} -``` - 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.