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:
import Amplifyimport AWSDataStorePlugin
- In the same file, create a function to configure Amplify:
func configureAmplify() { let dataStorePlugin = AWSDataStorePlugin(modelRegistration: AmplifyModels()) do { try Amplify.add(plugin: dataStorePlugin) try Amplify.configure() print("Initialized Amplify"); } catch { // simplified error handling for the tutorial print("Could not initialize Amplify: \(error)") }}
- Now call the
configureAmplify()
function in your App's initializer.
@mainstruct TodoApp: App { // Add a default initializer and configure Amplify init() { configureAmplify() }
// Additional functions...}
-
Build and run the application. In the Xcode console window, you'll see a log line indicating success:
Initialized 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()
:Amplify.Logging.logLevel = .infoSetting the log level to
.info
, re-building and re-running the application should render additional log statements:[Amplify] ConfiguringInitialized 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:
import Amplify
- In the same file (
ContentView.swift
), update the body view to call a function calledperformOnAppear()
using the.task()
modifier:
var body: some View { Text("Hello, World!") .task { await performOnAppear() }}
- In the same file, add an
async
function calledperformOnAppear()
:
func performOnAppear() async { do { let item = Todo(name: "Build iOS Application", description: "Build an iOS application using Amplify") let savedItem = try await Amplify.DataStore.save(item) print("Saved item: \(savedItem.name)") } catch { print("Could not save item to DataStore: \(error)") }}
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:
import SwiftUIimport Amplify
struct ContentView: View { var body: some View { Text("Hello, World!") .task { await performOnAppear() } }
func performOnAppear() async { do { let item = Todo(name: "Build iOS Application", description: "Build an iOS application using Amplify") let savedItem = try await Amplify.DataStore.save(item) print("Saved item: \(savedItem.name)") } catch { print("Could not save item to DataStore: \(error)") } }}
- Build and run the application. In the console output, you'll see an indication that the item was saved successfully:
Initialized AmplifySaved 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:
let item = Todo(name: "Finish quarterly taxes", priority: .high, 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:
Initialized AmplifySaved 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:
do { let todos = try await Amplify.DataStore.query(Todo.self) for todo in todos { print("==== Todo ====") print("Name: \(todo.name)") if let description = todo.description { print("Description: \(description)") } if let priority = todo.priority { print("Priority: \(priority)") } }} catch { print("Could not query DataStore: \(error)")}
- Build and run the application. In the console output, you'll see both items returned:
Initialized Amplify==== Todo ====Name: Build an iOS application using AmplifyDescription: Build an iOS application using Amplify==== Todo ====Name: Finish quarterly taxesDescription: Taxes are due for the quarter next weekPriority: 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:
let todos = try await Amplify.DataStore.query(Todo.self, 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:
Initialized Amplify==== Todo ====Name: Finish quarterly taxesDescription: Taxes are due for the quarter next weekPriority: 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:
do { let todos = try await Amplify.DataStore.query(Todo.self, where: Todo.keys.name.eq("Finish quarterly taxes")) guard todos.count == 1, var updatedTodo = todos.first else { print("Did not find exactly one todo, bailing") return } updatedTodo.name = "File quarterly taxes" let savedTodo = try await Amplify.DataStore.save(updatedTodo) print("Updated item: \(savedTodo.name)")} catch { print("Unable to perform operation: \(error)")}
-
Build and run the application. In your console output, you'll see an indication that the item was updated successfully:
Initialized AmplifyUpdated 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:
do { let todos = try await Amplify.DataStore.query(Todo.self, where: Todo.keys.name.eq("File quarterly taxes")) guard todos.count == 1, let toDeleteTodo = todos.first else { print("Did not find exactly one todo, bailing") return } try await Amplify.DataStore.delete(toDeleteTodo) print("Deleted item: \(toDeleteTodo.name)")} catch { print("Unable to perform operation: \(error)")}
- Build and run the application. In the console output, you'll see an indication that the item was deleted successfully:
Initialized AmplifyDeleted 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.