Page updated Jan 16, 2024

Set up Amplify DataStore

Amplify iOS v1 is now in Maintenance Mode until May 31st, 2024. This means that we will continue to include updates to ensure compatibility with backend services and security. No new features will be introduced in v1.

Please use the latest version (v2) of Amplify Library for Swift to get started.

If you are currently using v1, follow these instructions to upgrade to v2.

Amplify libraries should be used for all new cloud connected applications. If you are currently using the AWS Mobile SDK for iOS, you can access the documentation here.

DataStore with Amplify

Amplify DataStore provides a programming model for leveraging shared and distributed data without writing additional code for offline and online scenarios, which makes working with distributed, cross-user data just as simple as working with local-only data.

Note: this allows you to start persisting data locally to your device with DataStore, even without an AWS account.

Goal

To setup and configure your application with Amplify DataStore and use it to persist data locally on a device.

Prerequisites

  • An iOS application targeting at least iOS 13.0 with Amplify libraries integrated

Install Amplify Libraries

  1. To install Amplify Libraries in your application, open your project in Xcode and select File > Add Packages....

  2. Enter the Amplify iOS GitHub repo URL (https://github.com/aws-amplify/amplify-swift) into the search bar and click Add Package.

Note: Up to Next Major Version should be selected from the Dependency Rule dropdown.

  1. Lastly, choose AWSDataStorePlugin and Amplify. Then click Add Package.

To install the Amplify DataStore to your application, add AmplifyPlugins/AWSDataStorePlugin. Your Podfile should look similar to:

1target 'MyAmplifyApp' do
2 use_frameworks!
3 pod 'Amplify'
4 pod 'AmplifyPlugins/AWSDataStorePlugin'
5end

To install, download and resolve these pods, execute the command:

1pod install --repo-update

Now you can open your project by opening the .xcworkspace file using the following command:

1xed .

Setup local development environment

To use Amplify, you must first initialize it for use in your project. If you haven't already done so, run this command:

1amplify init

The base structure for a DataStore app is created by adding a new GraphQL API to your app.

1# For new APIs
2amplify add api
3
4# For existing APIs
5amplify update api

The CLI will prompt you to configure your API. Select GraphQL as the API type and reply to the questions as shown below. Conflict detection is required when using DataStore to sync data with the cloud.

1? Please select from one of the below mentioned services:
2 `GraphQL`
3? Here is the GraphQL API that we will create. Select a setting to edit or continue:
4 `Name`
5? Provide API name:
6 `BlogAppApi`
7? Here is the GraphQL API that we will create. Select a setting to edit or continue:
8 `Authorization modes: API key (default, expiration time: 7 days from now)`
9? Choose the default authorization type for the API
10 `API key`
11? Enter a description for the API key:
12 `BlogAPIKey`
13? After how many days from now the API key should expire (1-365):
14 `365`
15? Configure additional auth types?
16 `No`
17? Here is the GraphQL API that we will create. Select a setting to edit or continue:
18 `Conflict detection (required for DataStore): Disabled`
19? Enable conflict detection?
20 `Yes`
21? Select the default resolution strategy
22 `Auto Merge`
23? Here is the GraphQL API that we will create. Select a setting to edit or continue:
24 `Continue`
25? Choose a schema template
26 `Single object with fields (e.g., “Todo” with ID, name, description)`

Troubleshooting: Cloud sync will fail without the conflict detection configuration. To enable it for an existing project, run amplify update api and choose Enable DataStore for entire API.

The amplify add api command adds a new AmplifyConfig group to your Xcode project. It will contain the following files:

  • AmplifyConfig/
    • amplifyconfiguration.json
    • awsconfiguration.json
    • schema.graphql

Idiomatic persistence

DataStore relies on platform standard data structures to represent the data schema in an idiomatic way. The persistence language is composed by data types that satisfies the Model interface and operations defined by common verbs such as save, query and delete.

Data schema

The first step to create an app backed by a persistent datastore is to define a schema. DataStore uses GraphQL schema files as the definition of the application data model. The schema contains data types and relationships that represent the app's functionality.

Sample schema

For the next steps, let's start with a schema for a small blog application. Currently, it has only a single model. New types and constructs will be added to this base schema as more concepts are presented.

Open the schema.graphql file located by default at amplify/backend/{api_name}/ and define a model Post as follows.

1type Post @model {
2 id: ID!
3 title: String!
4 status: PostStatus!
5 rating: Int
6 content: String
7}
8
9enum PostStatus {
10 ACTIVE
11 INACTIVE
12}

Now you will to convert the platform-agnostic schema.graphql into platform-specific data structures. DataStore relies on code generation to guarantee schemas are correctly converted to platform code.

Like the initial setup, models can be generated either using the IDE integration or Amplify CLI directly.

Code generation: Platform integration

On iOS the amplify CLI offers an Xcode integration that automatically adds the Amplify-specific files to your project.

  1. Run the command:

    1amplify codegen models
  2. The amplify codegen models command adds a new AmplifyModels group to your Xcode project. It will contain the following files:

  • AmplifyModels/
    • AmplifyModels.swift
    • Post.swift
    • Post+Schema.swift
    • PostStatus.swift
  1. Build the project (Cmd+b).

Code generation: Amplify CLI

Models can also be generated using the Amplify CLI directly.

In your terminal, make sure you are in your project/root folder and execute the codegen command:

1amplify codegen models

You can find the generated files at amplify/generated/models/.

Initialize Amplify DataStore

To initialize the Amplify DataStore call Amplify.add(plugin:) method and add the AWSDataStorePlugin, then call Amplify.configure().

Add the following imports to the top of your AppDelegate.swift file:

1import Amplify
2import AWSDataStorePlugin
1import Amplify
2import AmplifyPlugins

Add the following code

Create a custom AppDelegate, and add to your application:didFinishLaunchingWithOptions method

1class AppDelegate: NSObject, UIApplicationDelegate {
2 func application(
3 _ application: UIApplication,
4 didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
5 ) -> Bool {
6
7 do {
8 // AmplifyModels is generated in the previous step
9 let dataStorePlugin = AWSDataStorePlugin(modelRegistration: AmplifyModels())
10 try Amplify.add(plugin: dataStorePlugin)
11 try Amplify.configure()
12 print("Amplify configured with DataStore plugin")
13 } catch {
14 print("Failed to initialize Amplify with \(error)")
15 return false
16 }
17
18 return true
19 }
20}

Then in the App scene, use UIApplicationDelegateAdaptor property wrapper to use your custom AppDelegate

1@main
2struct MyAmplifyApp: App {
3 @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
4
5 var body: some Scene {
6 WindowGroup {
7 ContentView()
8 }
9 }
10}

Add to your AppDelegate's application:didFinishLaunchingWithOptions method

1func application(
2 _ application: UIApplication,
3 didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
4) -> Bool {
5
6 do {
7 // AmplifyModels is generated in the previous step
8 let dataStorePlugin = AWSDataStorePlugin(modelRegistration: AmplifyModels())
9 try Amplify.add(plugin: dataStorePlugin)
10 try Amplify.configure()
11 print("Amplify configured with DataStore plugin")
12 } catch {
13 print("Failed to initialize Amplify with \(error)")
14 return false
15 }
16
17 return true
18}

Upon building and running this application you should see the following in your console window:

1Amplify configured with DataStore plugin

Persistence operations

Now the application is ready to execute persistence operations. The data will be persisted to a local database, enabling offline-first use cases by default.

Even though a GraphQL API is already added to your project, the cloud synchronization will only be enabled when the API plugin is initialized and the backend provisioned. See the Next steps for more info.

Writing to the database

To write to the database, create an instance of the Post model and save it.

1let post = Post(title: "Create an Amplify DataStore app",
2 status: .active)
3
4Amplify.DataStore.save(post) { result in
5 switch result {
6 case .success:
7 print("Post saved successfully!")
8 case .failure(let error):
9 print("Error saving post \(error)")
10 }
11}
1let post = Post(title: "Create an Amplify DataStore app",
2 status: .active)
3let saveSink = Amplify.DataStore.save(post).sink {
4 if case let .failure(error) = $0 {
5 print("Error saving post \(error)")
6 }
7}
8receiveValue: {
9 print("Post saved successfully! \($0)")
10}

Reading from the database

To read from the database, the simplest approach is to query for all records of a given model type.

1Amplify.DataStore.query(Post.self) { result in
2 switch result {
3 case .success(let posts):
4 print("Posts retrieved successfully: \(posts)")
5 case .failure(let error):
6 print("Error retrieving posts \(error)")
7 }
8}
1let querySink = Amplify.DataStore.query(Post.self).sink {
2 if case let .failure(error) = $0 {
3 print("Error retrieving posts \(error)")
4 }
5}
6receiveValue: { posts in
7 print("Posts retrieved successfully: \(posts)")
8}

Next steps

Congratulations! You’ve created and retrieved data from the local database. Check out the following links to see other Amplify DataStore use cases and advanced concepts: