Integrate your app
Next you'll use the generated model to create, update, query, and delete data. In this section you'll initialize DataStore, and then manipulate Todo items.
Configure Amplify and DataStore
First, you'll add the DataStore plugin and configure Amplify.
- Open the main file of the application (
TodoApp.swift
) and add the following import statements at the top of the file:
1import Amplify2import AWSDataStorePlugin
- In the same file, create a function to configure Amplify:
1func configureAmplify() {2 let dataStorePlugin = AWSDataStorePlugin(modelRegistration: AmplifyModels())3 do {4 try Amplify.add(plugin: dataStorePlugin)5 try Amplify.configure()6 print("Initialized Amplify");7 } catch {8 // simplified error handling for the tutorial9 print("Could not initialize Amplify: \(error)")10 }11}
- Now call the
configureAmplify()
function in your App's initializer.
1@main2struct TodoApp: App {3 // Add a default initializer and configure Amplify4 init() {5 configureAmplify()6 }7
8 // Additional functions...9}
-
Build and run the application. In the Xcode console window, you'll see a log line indicating success:
1Initialized AmplifyOptionally, if you'd like to adjust the log level, you can do this by updating the
Amplify.Logging.logLevel
variable.For example, you can add the following line of code to the
configureAmplify()
function before callingAmplify.configure()
:1Amplify.Logging.logLevel = .infoSetting the log level to
.info
, re-building and re-running the application should render additional log statements:1[Amplify] Configuring2Initialized Amplify
Manipulating data
Create a Todo
Next, you'll create a Todo and save it to DataStore.
- Open
ContentView.swift
and add the following import statements at the top of the file:
1import Amplify
- In the same file (
ContentView.swift
), update the body view to call a function calledperformOnAppear()
using the.task()
modifier:
1var body: some View {2 Text("Hello, World!")3 .task {4 await performOnAppear()5 }6}
- In the same file, add an
async
function calledperformOnAppear()
:
1func performOnAppear() async {2 do {3 let item = Todo(name: "Build iOS Application",4 description: "Build an iOS application using Amplify")5 let savedItem = try await Amplify.DataStore.save(item)6 print("Saved item: \(savedItem.name)")7 } catch {8 print("Could not save item to DataStore: \(error)")9 }10}
This code creates a Todo item with two properties: a name and a description, and then calls Amplify.DataStore.save(:)
in order to store it on DataStore.
- After making the preceding updates to the
ContentView.swift
file, your code should look like the following:
1import SwiftUI2import Amplify3
4struct ContentView: View {5 6 var body: some View {7 Text("Hello, World!")8 .task {9 await performOnAppear()10 }11 }12
13 func performOnAppear() async {14 do {15 let item = Todo(name: "Build iOS Application",16 description: "Build an iOS application using Amplify")17 let savedItem = try await Amplify.DataStore.save(item)18 print("Saved item: \(savedItem.name)")19 } catch {20 print("Could not save item to DataStore: \(error)")21 }22 }23}
- Build and run the application. In the console output, you'll see an indication that the item was saved successfully:
1Initialized Amplify2Saved item: Build iOS Application
- Replace the item with a new Todo to save an additional item. Let's change the name and description, and add a priority:
1let item = Todo(name: "Finish quarterly taxes",2 priority: .high,3 description: "Taxes are due for the quarter next week")
- Build and run the application. In the console output, you'll see an indication that the item was saved successfully:
1Initialized Amplify2Saved item: Finish quarterly taxes
Query Todos
Now that you have some data in DataStore, you can run queries to retrieve those records.
- Edit your
performOnAppear()
method to remove the item creation and save operations, and replace it with the following code:
1do {2 let todos = try await Amplify.DataStore.query(Todo.self)3 for todo in todos {4 print("==== Todo ====")5 print("Name: \(todo.name)")6 if let description = todo.description {7 print("Description: \(description)")8 }9 if let priority = todo.priority {10 print("Priority: \(priority)")11 }12 }13} catch {14 print("Could not query DataStore: \(error)")15}
- Build and run the application. In the console output, you'll see both items returned:
1Initialized Amplify2==== Todo ====3Name: Build an iOS application using Amplify4Description: Build an iOS application using Amplify5==== Todo ====6Name: Finish quarterly taxes7Description: Taxes are due for the quarter next week8Priority: high
- Queries can also contain predicate filters. These will query for specific objects matching a certain condition.
The following predicates are supported:
Strings
eq
ne
le
lt
ge
gt
contains
notContains
beginsWith
between
Numbers
eq
ne
le
lt
ge
gt
between
Lists
contains
notContains
To use a predicate, pass an additional argument into your query. For example, you can use the following code to see all high priority items:
1let todos = try await Amplify.DataStore.query(Todo.self,2 where: Todo.keys.priority.eq(Priority.high))
In the above code, notice the addition of the predicate parameter as the second argument.
- Run the application. In the console output, you'll see only the high priority item returned:
1Initialized Amplify2==== Todo ====3Name: Finish quarterly taxes4Description: Taxes are due for the quarter next week5Priority: high
Update a Todo
You may want to change the contents of a record. Below, you'll query for a record, create a copy of it, modify it, and save it back to DataStore.
- Edit your
performOnAppear()
method to remove anything related to DataStore and replace it with the following code:
1do {2 let todos = try await Amplify.DataStore.query(Todo.self,3 where: Todo.keys.name.eq("Finish quarterly taxes"))4 guard todos.count == 1, var updatedTodo = todos.first else {5 print("Did not find exactly one todo, bailing")6 return7 }8 updatedTodo.name = "File quarterly taxes"9 let savedTodo = try await Amplify.DataStore.save(updatedTodo)10 print("Updated item: \(savedTodo.name)")11} catch {12 print("Unable to perform operation: \(error)")13}
-
Build and run the application. In your console output, you'll see an indication that the item was updated successfully:
1Initialized Amplify2Updated item: File quarterly taxes
Delete a Todo
To round out CRUD operations, you'll query for a record and then delete it from DataStore.
- Edit your
performOnAppear()
method to remove anything related to DataStore and replace it with the following code:
1do {2 let todos = try await Amplify.DataStore.query(Todo.self,3 where: Todo.keys.name.eq("File quarterly taxes"))4 guard todos.count == 1, let toDeleteTodo = todos.first else {5 print("Did not find exactly one todo, bailing")6 return7 }8 try await Amplify.DataStore.delete(toDeleteTodo)9 print("Deleted item: \(toDeleteTodo.name)")10} catch {11 print("Unable to perform operation: \(error)")12}
- Build and run the application. In the console output, you'll see an indication that the item was deleted successfully:
1Initialized Amplify2Deleted item: File quarterly taxes
Almost done
You just reached a very cool checkpoint. You have a fully featured CRUD application that saves and retrieves data in the local device, which means the app works without an AWS account and even without internet connection.
Next, let's connect it to AWS and make sure the data available in the cloud.