Aws appsync ios

Aws appsync ios DEFAULT

Getting Started with AWS AppSync for iOS

Most apps nowadays require a back end to work. Need user accounts? You’ll need a back end for that. Want to sync data across devices? Guess what, you’ll need a back end. Targeted push notifications? Back end… you get the idea.

You may have heard the acronym BaaS (Back end as a service) before. BaaS tools offer integration with cloud storage services via the use of simple APIs. Once configured, these BaaS services function the same way any other API would with little to no upfront back end knowledge required.

In this tutorial, you’ll use Amazon’s BaaS offering called AppSync along with the Amplify framework to add a back end component to your iOS app. You’ll learn how to:

  • Install AWS Amplify and its dependencies
  • Implement models using GraphQL and generate local files with Amplify
  • Perform CRUD operations on your data
  • Save your application’s data to AWS AppSync

You’ll learn all this by implementing a to do list app with SwiftUI. The app will allow you to create, delete and complete to dos while keeping your app’s data synchronized with the AppSync cloud service. The app will work both with and without an internet connection as well!

Getting Started

Download the project materials using the Download Materials button at the top or bottom of this tutorial. Open RazeList.xcodeproj inside the starter folder.

RazeList helps your to dos stay in sync across all your iOS devices. It’s your one source of truth for all of your to dos, and more importantly, all of your “dones”! When you’re finished with this tutorial, you’ll always know where you are with your tasks, no matter which device you’re using.

Inside Xcode, build and run the project.

Initial view when running the app

Right now, the project is nothing more than a greeting. You’re going to change that, but there are a few prerequisites you need to take care of first.

About GraphQL and AppSync

Before writing any code, you’ll first need to learn what GraphQL is and how it works with AppSync.

What is GraphQL?

GraphQL was developed by Facebook in 2012; it’s a query language and server-side runtime for executing queries designed to work with server-side APIs.

If you’ve worked with server-side APIs before, you’re likely already familiar with REST. REST APIs work by exposing multiple endpoints for applications, each one designed for a specific data type. Most APIs these days would be considered RESTful; however, the REST standard is loosely interpreted so you’ll likely have a different experience across multiple REST APIs.

Contrary to REST, GraphQL only exposes a single endpoint which you interact with via queries. With this approach, clients only access the data they need and minimize the amount of data sent over the network. The best way to see how GraphQL operates is with an example.

type Todo { id: ID! name: String! description: String completed: Boolean! }

Above is an example of a GraphQL schema describing the type, the basic to do structure you’ll use when building RazeList. The server defines this type so that you can fetch it. Assume you have a screen in your app that lists all to dos, but only requires the and fields. This is how you would fetch the data for that screen, using a GraphQL query:

query TodoQuery { listTodos { items { name completed } } }

This GraphQL query only accesses the data required by specifying the fields it cares about. You send this query to the server and the server responds with a data structure that matches your query. Adding and removing fields in this way would require changes to the API when using REST, whereas here, you can just change the query inside the app, without having to modify the server at all.

GraphQL with AWS AppSync

AWS AppSync does all the heavy lifting of your back-end web service. It acts as a bridge between GraphQL and other AWS services such as data storage, caching and real-time updates.

AppSync provides a dashboard for your project where you can view and query your data, as well as add custom functionality through custom functions.

Your app will communicate with AppSync via GraphQL behind the scenes; however, you’ll be using the AppSync iOS framework to abstract away a lot of this complexity. After some configuration, you’ll only talk your back end in a type-safe way.

Installing the Amplify Framework

You’re going to start by installing the project dependencies. You may already have some (or all) of these installed. If that’s the case, you can skip to the relevant section.

Installing npm

Node Package Manager (npm) is a package manager and CLI (command line interface) for managing Node.js packages. In this project, you’ll be using npm to install the Amplify CLI.

If you’re unsure if you have npm installed, open Terminal and type , then press Enter. If it’s installed, you should see the version number printed in the Terminal window.

npm is installed along with Node.js. To install both Node.js and npm navigate to the node.js website and click the download link labeled LTS. At the time of writing, the current LTS version is 14.15.1 LTS.

Once downloaded, open the .pkg file, and you should see the following:

Initial step of Node.js installation

Click Continue and follow the steps. When the installation completes, restart Terminal and type and press Enter. You should now see the version number.

Installing Amplify CLI

Amplify is installed via the command line. Inside Terminal, type the following and press Enter.

Enter your system password when required. You’ll see a lot of activity in the Terminal window as npm does its thing. When Amplify is installed, you should see something like the following:

---------------------------------------- Successfully installed the Amplify CLI ----------------------------------------

Once this process completes, enter the following command and press Enter:

amplify configure

This command will open the AWS login page in a new browser window. If you don’t already have an AWS account, you’ll need to sign up for one before completing this step. Signing up is quick and easy; instructions on how to do this can be found at the AWS knowledge center. When you’re done, be sure to continue the tutorial from this point.

Log in into your AWS account in the browser window. Once logged in, return to the Terminal window and press Enter.

Next you’ll need to specify your region. Choose the region that best represents your location with the arrow keys and then press Enter.

Next enter the username for your new user and press Enter. This can be anything you want.

This will direct you to the AWS console to finish the setup. Click through the setup process using the buttons at the bottom, and be sure that AdministratorAccess is checked on the permissions screen.

AWS add user administrator access

On the success screen of user setup, copy your Access key ID and Secret access key to a secure location — you will need them later. Be sure to click Show when copying the Secret Access Key.

User API key and Secret

Return to the Terminal window and press Enter.

When prompted by Terminal, enter your Access Key ID and Secret Access Key.

Finally, press Enter one last time when asked for the Profile Name. This will set your profile to default.

Installing CocoaPods

You will use CocoaPods to add the AppSync frameworks to your project. If you are not familiar with CocoaPods, you can learn about it in our CocoaPods Tutorial for Swift

CocoaPods is installed through Ruby, which is already installed on your Mac. Open Terminal, type the following command and press Enter.

After a short delay you should see in the Terminal window.

Adding Amplify to the Project

Now that you’re all set up with dependencies, you can move on to setting up the project in Xcode. Make sure you close Xcode for the next step… yes you heard that right!

Open a Terminal screen, and use to navigate to the starter project directory. Then, type the following into the terminal window:

pod init

Once the command completes, you’ll notice a new file named Podfile has appeared inside your project directory. Open Podfile in a text editor and add the following below :

pod 'Amplify' pod 'Amplify/Tools' pod 'AmplifyPlugins/AWSAPIPlugin' pod 'AmplifyPlugins/AWSDataStorePlugin'

Navigate back to the terminal window and type the following command:

pod install

After a few seconds, you should see the following message:

Pod installation complete! There are 4 dependencies from the Podfile and 12 total pods installed.

Voilà! Just like that, your packages have been installed and included in your project.

Open the project directory in Finder, you’ll notice you now have a workspace file called RazeList.xcworkspace, which CocoaPods created. Double-click this file and your project will open in Xcode. Use this file from now on to open your project instead of RazeList.xcodeproj, because it’s the one that contains all the dependencies needed.

Adding AppSync Script

You’re almost over the finish line. The last thing you need to do before writing any code is add a Run Script to the Build Phases tab inside Xcode. This script performs some tasks needed to use AppSync in your project.

Select the RazeList project inside Xcode. In the project explorer, click Build Phases. Click the + button and select New Run Script Phase.

Steps to add a run script phase

You’ll notice a new Run Script entry at the bottom of the list. Click the arrow to expand it.

Steps for adding code to a run script phase

Inside the code editor at the top, add the following code:


Now build and run the project. The build will take a little longer this time, because Xcode executes the Run Script as part of the build process. When the build finishes, you’ll have a few more files inside your project; you’ll be working with these in the next section. It’s important that you wait for the project to build before moving onto the next stage.

Initializing Amplify

Once the build process is complete, you’ll need to initialize amplify within your project. You’ll know the build has done its job as you’ll see a new folder called AmplifyConfig in the Project navigator.

Make sure you’re in the project directory in Terminal and enter the following command:

amplify init

Enter the following information when prompted:

? Enter a name for the environment Press Enter ? Choose your default editor None ? Do you want to use an AWS profile? Y ? Please choose the profile you want to use Press Enter for default

In the same Terminal window, enter the following command and then press Enter.

amplify add api

Enter the following information when prompted. Press enter on other steps to use the default setting.

? Please select from one of the below mentioned services: GraphQL ? Provide API name: Press Enter to set this to your directory name.

Next enter the following command.

amplify push

Enter the following information when prompted.

? Are you sure you want to continue? Y ? Do you want to generate code for your newly created GraphQL API N

This may seem like a lot of setup, but Amplify has done a lot for you. You’ve created a user, set up an app and added it the AWS dashboard, created a GraphQL API and published it to AWS. Everything from here is good to go!

Creating Models Using GraphQL

When working with a back-end service, you’ll likely want to represent your data types as models. Amplify saves you the trouble of having to type them up yourself. Isn’t that nice?

You still need to tell Amplify what to generate, however, and you’ll do that with GraphQL!

Open schema.graphql inside the AmplifyConfig group.

Replace the contents of this file with the following:

type Todo @model { id: ID! name: String! description: String completed: Boolean! }

Next, open amplifytools.xcconfig in the same directory. Change and to .

Build and run your project. When the build finishes, there will be a new directory in your Project navigator called AmplifyModels. Changing the line above in the configuration told Amplify to generate your model files for you from the GraphQL schema and update your configuration on AWS. Expand AmplifyModels and take a look around. You’ll see Todo.swift containing your model and some helper files.

Using Amplify in the App

In the Project navigator on the left, open AppMain.swift and add the following imports:

import Amplify import AmplifyPlugins

Inside the class, add the following code before in the function:

let apiPlugin = AWSAPIPlugin(modelRegistration: AmplifyModels()) let dataStorePlugin = AWSDataStorePlugin(modelRegistration: AmplifyModels()) do { try Amplify.add(plugin: apiPlugin) try Amplify.add(plugin: dataStorePlugin) try Amplify.configure() print("Initialized Amplify") } catch { print("Could not initialize Amplify: \(error)") }

Build and run the project.

Initial Hello World screen when building app

There are no visual changes to speak of, but you’ve fully configured your project to work with AppSync and Amplify.

Building the To Do List UI

With the libraries installed, CocoaPods set up and models generated, it’s time to make RazeList come to life.

Some of the SwiftUI coding for this tutorial has been done for you, but you still need to build the main to do list. That’s what you’ll be doing in this section.

Adding Rows to the To Do List

You’ll start by defining the row. Right click the Views group and select the New File option. Choose SwiftUI View and click Next. Name the file TodoRowView.swift and create it.

Open that file and, just below the declaration, add the following.

// 1 let todoItem: Todo // 2 let onToggleCompleted: (Todo) -> Void

The to do row defines two requirements.

  1. A model to use for rendering.
  2. A closure called when the user toggles the completed state.

This will cause an error as the preview doesn’t pass in these dependencies. Replace the entire contents of with the following:

struct TodoRowView_Previews: PreviewProvider { static var previews: some View { TodoRowView( todoItem: Todo( id: UUID().uuidString, name: "Build this cool app", description: "I need to finish building this awesome todo list app :]", completed: false)) { _ in } } }

Next, you’ll define a method called when the todo is toggled by the user. Add the following method to :

func toggleCompleted() { withAnimation { onToggleCompleted(todoItem) } }

This function simply wraps in an animation block that will animate the movement of the row between sections.

Next, replace the entire with the following:

var body: some View { // 1 VStack(alignment: .leading, spacing: 8) { HStack(spacing: 10) { // 2 Button(action: { onToggleCompleted(todoItem) }) { Image(systemName: todoItem.completed ? "checkmark.square" : "square") .imageScale(.large) .foregroundColor(todoItem.completed ? .pink : .primary) } // 3 Text( .font(.system(size: 18, weight: .semibold)) } // 4 if let description = todoItem.description { Text(description) .font(.system(size: 14, weight: .medium)) .padding(.leading, 32) .padding(.trailing, 10) .foregroundColor(.gray) } } }

Here’s what the above code does:

  1. Define a container.
  2. Define an containing a button with a checkbox image. The image is either checked or unchecked depending on the state the to do model’s property. Tapping the button will call .
  3. The second item in the stack is a view containing the name of the to do.
  4. If the to do contains a description, render it inside a view.

Setting up Your Data

Open TodoListViewModel.swift. Add the following code inside the class implementation:

@Published var todos: [Todo] = [] @Published var completedTodos: [Todo] = []

conforms to . Conforming to this protocol allows the object to publish updates when the state changes. Using the property wrapper tells the object to broadcast changes through its publisher to anyone listening. SwiftUI uses this to redraw the UI when the object updates.

If you want to learn more about , check out Combine: Asynchronous Programming with Swift.

Next, open TodoListView.swift and add the following code inside the view implementation:

@ObservedObject var viewModel = TodoListViewModel()

Here you’re creating a reference to using the property wrapper. Creating a property in this way tells SwiftUI that you care about the state of this object and it should respond to changes.

Adding Sections

Next you’ll define two sections, one for to dos and one for completed to dos. Generally speaking, you want to aim to keep the property light. With that in mind, you’ll define these two sections as computed properties.

Add the first section to :

var todoSection: some View { // 1 Group { // 2 if viewModel.todos.isEmpty { Text("Nothing to do!") } else { // 3 ForEach(viewModel.todos, id: \.id) { todo in // 4 TodoRowView(todoItem: todo) { todo in withAnimation { // Toggle complete } } .padding(.vertical, 6) } .onDelete(perform: viewModel.deleteTodos) } } }

Taking it bit-by-bit:

  1. You can’t optionally return a view or view, so they’re wrapped inside a .
  2. If there are no to dos in your list, return a view reflecting this.
  3. If there are to dos, loop through each to do inside a .
  4. For each to do in the list, generate a and pass in the current to do.

You’ll do the same thing next with the completed to dos. Below the property, add the following:

var completedTodoSection: some View { Group { if viewModel.completedTodos.isEmpty { Text("Completed Tasks Appear Here") } else { ForEach(viewModel.completedTodos, id: \.id) { todo in TodoRowView(todoItem: todo) { todo in withAnimation { // Toggle complete } } .padding(.vertical, 6) } .onDelete(perform: viewModel.deleteCompletedTodos) } } }

The only difference here is that you’ve replaced references to with .

Now you’ve defined your two list sections, it’s time to see them in action!

Replace the contents of with the following:

// 1 List { // 2 Section(header: Text("Todo")) { todoSection } // 3 Section(header: Text("Completed")) { completedTodoSection } } // 4 .listStyle(GroupedListStyle())

The code above does the following:

  1. Creates a list to contain the sections you created earlier.
  2. Embeds the to do section inside a view.
  3. Embeds the completed to dos section inside a view.
  4. Gives the list a grouped style. This will separate the sections and apply some default styling.

Build and run to see the result.

Razelist todo initial screen with empty content

You’re finally rid of the hello world app! Nice.

Adding a To Do

In the final part of this section, you’ll integrate the add to do screen. The UI has already been built, so this is a fairly simple step.

Go to TodoListView.swift and add a new property inside the view implementation:

@State var addNewTodoPresented: Bool = false

This will be in charge of presenting and dismissing the add to do view.

At the bottom of , on the line after , add the following view modifiers:

// 1 .navigationBarItems( trailing: Button(action: { addNewTodoPresented.toggle() }) { Image(systemName: "plus") .imageScale(.large) } ) // 2 .sheet(isPresented: $addNewTodoPresented) { AddTodoView { name, description in // add todo addNewTodoPresented.toggle() } }

This looks a bit complicated but is actually fairly straightforward:

  1. The view modifier adds navigation items to the navigation bar of the enclosing . You’re adding a single button here, which toggles when tapped.
  2. The view modifier presents a model when the state is . The closure returns the view to be presented. In this case, you’re returning .

Build and run to see the result.

Add new todo screen

You now have an add button in the navigation bar and a screen to add new todos!

Creating and Editing To Dos

You’re all set up and have a functioning UI. The last thing you need to do is wire everything up!

Open TodoListViewModel.swift and add a new import.

import Amplify

Adding To Dos

Next, add the following method:

func createTodo(name: String, description: String?) { // 1 let item = Todo(name: name, description: description, completed: false) // 2 todos.append(item) // 3 { result in switch result { case .success(let savedItem): print("Saved item: \(") case .failure(let error): print("Could not save item with error: \(error)") } } }

With all the configuration from the previous steps, this is all you need to save data to your local and cloud data stores. Here’s what’s happening:

  1. Creates a new to do item using the variables passed in.
  2. Adds it to the local array.
  3. Using the Amplify framework, adds the to do to your data store.

Next open TodoListView.swift, and scroll down to the modifier at the end of . In the closure on the line above , add a call to the function.

viewModel.createTodo(name: name, description: description)

You can save todos now, but that’s no good unless you can load them!

Back in TodoListViewModel.swift, replace with the following.

func loadToDos() { Amplify.DataStore.query(Todo.self) { result in switch result { case .success(let todos): self.todos = todos.filter { !$0.completed } completedTodos = todos.filter { $0.completed } case .failure(let error): print("Could not query DataStore: \(error)") } } }

Now in TodoListView.swift add a new view modifier underneath .

.onAppear { viewModel.loadToDos() }

Build and run the project to add your first todo!

Adding a new todo

Completing To Dos

So far, the app is great for showing you what you need to do — but not so good at letting you complete those tasks.

Open TodoListViewModel. Scroll to the bottom and add the following new method after :

func toggleComplete(_ todo: Todo) { // 1 var updatedTodo = todo updatedTodo.completed.toggle() // 2 { result in switch result { case .success(let savedTodo): print("Updated item: \( )") case .failure(let error): print("Could not update data with error: \(error)") } } // 3 if updatedTodo.completed { if let index = todos.firstIndex(where: { $ == }) { todos.remove(at: index) completedTodos.insert(updatedTodo, at: 0) } // 4 } else { if let index = completedTodos.firstIndex(where: { $ == }) { completedTodos.remove(at: index) todos.insert(updatedTodo, at: 0) } } }

Okay, that’s a fair chunk of code. Here’s what it does:

  1. Make a mutable copy of the to do so it can be modified, then toggle the completed value.
  2. Using Amplify, save the to do back to your data store.
  3. If the to do is completed, remove it from and add it to .
  4. If the to do is not completed, remove it from and add it to .

Open TodoListView.swift and navigate to the two properties at the top. In and , you’ll notice two placeholder comments . Replace that comment in both places with the following:


Build and run the app. Now you can tap each todo in either list and change the completed state with a cool animation!

Toggling the complete state of todos

Deleting To Dos

The final thing you need add is a way to delete rows. Swipe-to-delete already exists in the UI, so you just need to wire it up.

Open TodoListViewModel.swift, and you’ll notice three delete methods at the top. These will act as helpers to delete to do items from their respective list.

Add the following method:

func delete(todo: Todo) { Amplify.DataStore.delete(todo) { result in switch result { case .success: print("Deleted item: \(") case .failure(let error): print("Could not update data with error: \(error)") } } }

This method deletes the model from the data store by calling from the Amplify framework.

Next, replace the three delete methods above with the following:

// 1 func deleteItems(at offsets: IndexSet, from todoList: inout [Todo]) { for index in offsets { let todo = todoList[index] delete(todo: todo) } todoList.remove(atOffsets: offsets) } // 2 func deleteTodos(at offsets: IndexSet) { deleteItems(at: offsets, from: &todos) } // 3 func deleteCompletedTodos(at offsets: IndexSet) { deleteItems(at: offsets, from: &completedTodos) }

Here’s what you’ve done:

  1. The first delete method calls , which you just added.
  2. This method routes the call to delete with the array.
  3. This method routes the call to delete with the array.

Build and run the project. You can now swipe to delete todos!

Deleting a todo gif

You now have a to do list that allows you to add, edit and delete to dos. It works offline and stays synchronized to an AWS back end.

Where to Go From Here?

You can download the completed version of the project using the Download Materials button at the top or bottom of this tutorial.

You now know the basics of integrating and using AppSync with Amplify in your iOS apps — but there’s a lot more to learn! GraphQL can do much more than what you’ve covered here.

When you’re ready for your next steps with AWS and Amplify, check out Using AWS as a Back End: Authentication & API and Using AWS as a Back End: The Data Store API.

Check out our tutorial GraphQL Using the Apollo Framework: Getting Started to see more practical examples. You can also learn a lot more about GraphQL on the official GraphQL website.

You should also look at the official AWS AppSync tutorials Amazon has produced for further learning.

If you have any questions, please join the discussion in the forum below! Weekly

The newsletter is the easiest way to stay up-to-date on everything you need to know as a mobile developer.

Get a weekly digest of our tutorials and courses, and receive a free in-depth email course as a bonus!


AWS AppSync for iOS

AppSync Setup with Amplify



Get an overview of Amazon’s BaaS offering, AppSync, along with their Amplify framework. They work together to add a back end component to your iOS app.


Use GraphQL


AWS AppSync acts as a bridge between GraphQL and other AWS services such as data storage, caching and real-time updates.


Install npm


npm (Node Package Manager) is a command line interface (CLI) for managing Node.js packages. You’ll need npm installed for installing AWS Amplify.


Install the Amplify CLI


npm makes it simple to install Amplify. All you need to do is bring an AWS account, which is simple and easy to set up.


Initialize Amplify with SPM


You can employ the Swift Package Manager for installation of all the Amplify libraries you will need.


Create Models Using GraphQL


Using a GraphQL schema, you can tell Amplify what models to generate. Afterwards, you’ll be able to interact with them using Swift.




You’ve created a user, set up an app, and added it to the AWS dashboard. You also created a GraphQL API and published it to AWS. You’re all set up to use AppSync!


Integrate AppSync into an App



With the libraries installed, and models generated, it’s time to make RazeList, a to-do app, come to life!


Configure Amplify in an App


Before “configuring” Amplify, you’ll need to import libraries, and create instances of appropriate plugins.


Add Rows to the To Do List


Create a Row view that will correspond with a Todo instance. Then, add some published Todos to the view model.


Add Sections


Create two sections: one for to-dos that you still need doing, and the other, for ones you’ve completed.


Add a To Do


The final step of getting the UI working, before we get back to focusing on AppSync specifically, is to integrate the “add to do” screen.


Edit To Dos


Amplify has save and query methods which makes interacting with the cloud a breeze. You can either use them with Combine, or deal with them synchronously.


Complete To Dos


So far, the app is great for showing you what you need to do — but not so good at letting you complete those tasks. AppSync to the rescue, again!


Delete To Dos


The final thing you need to add is a way to delete rows. Swipe-to-delete already exists in the UI, so you just need to wire it up.




You now know the basics of integrating and using AppSync with Amplify in your iOS apps — but there’s a lot more to learn!


This course is intended for developers who are interested in learning how to integrate Amazon’s BaaS technology. A good understanding of Swift, SwiftUI, and Combine will be helpful for following along with integration into the app you’ll be working on in this course.

  • AWS AppSync
  • AWS Amplify
  • GraphQL


Jessy Catterwaul

Fascinated by technology consistently making learning easier, Jessy enjoys exploring new techniques involving creative software...

Julia Zinchenko

Graphic designer and illustrator based in Ukraine

Christine Sweigart

Christine is Razeware's administrative assistant and video editor. For many years she fostered a strong dislike of green...

Video Editor
  1. Arknights reroll guide
  2. Best router tool 2019
  3. Golden light restaurant supply
  4. Mercury outboard reverse lock

AWS AppSync SDK for iOS

{ "name": "AWSAppSync", "path": "/usr/src/package", "targets": [ { "name": "AWSAppSync", "path": "AWSAppSyncClient", "type": "library", "c99name": "AWSAppSync", "sources": [ "AWSAppSyncAuthProvider.swift", "AWSAppSyncAuthType.swift", "AWSAppSyncCache.swift", "AWSAppSyncCacheConfigurationMigration.swift", "AWSAppSyncClient.swift", "AWSAppSyncClientConfiguration.swift", "AWSAppSyncClientConfigurationError.swift", "AWSAppSyncClientConflictResolutionExtensions.swift", "AWSAppSyncClientError.swift", "AWSAppSyncClientInfo.swift", "AWSAppSyncClientInfoError.swift", "AWSAppSyncClientLogFormatter.swift", "AWSAppSyncClientS3ObjectsExtensions.swift", "AWSAppSyncConnection.swift", "AWSAppSyncHTTPNetworkTransport.swift", "AWSAppSyncMutations.swift", "AWSAppSyncRetryStrategy.swift", "AWSAppSyncServiceConfig.swift", "AWSAppSyncServiceConfigError.swift", "AWSAppSyncSubscriptionError.swift", "AWSAppSyncSubscriptionWatcher.swift", "AWSAppSyncSubscriptionWatcherStatus.swift", "AWSNetworkTransport.swift", "AWSS3ObjectProtocol.swift", "Apollo/Sources/Apollo/AWSGraphQLSubscriptionResponse.swift", "Apollo/Sources/Apollo/ApolloClient.swift", "Apollo/Sources/Apollo/ApolloStore.swift", "Apollo/Sources/Apollo/AsynchronousOperation.swift", "Apollo/Sources/Apollo/Collections.swift", "Apollo/Sources/Apollo/DataLoader.swift", "Apollo/Sources/Apollo/GraphQLDependencyTracker.swift", "Apollo/Sources/Apollo/GraphQLError.swift", "Apollo/Sources/Apollo/GraphQLExecutor.swift", "Apollo/Sources/Apollo/GraphQLInputValue.swift", "Apollo/Sources/Apollo/GraphQLOperation.swift", "Apollo/Sources/Apollo/GraphQLQueryWatcher.swift", "Apollo/Sources/Apollo/GraphQLResponse.swift", "Apollo/Sources/Apollo/GraphQLResponseGenerator.swift", "Apollo/Sources/Apollo/GraphQLResult.swift", "Apollo/Sources/Apollo/GraphQLResultAccumulator.swift", "Apollo/Sources/Apollo/GraphQLResultNormalizer.swift", "Apollo/Sources/Apollo/GraphQLSelectionSet.swift", "Apollo/Sources/Apollo/GraphQLSelectionSetMapper.swift", "Apollo/Sources/Apollo/HTTPNetworkTransport.swift", "Apollo/Sources/Apollo/InMemoryNormalizedCache.swift", "Apollo/Sources/Apollo/JSON.swift", "Apollo/Sources/Apollo/JSONSerializationFormat.swift", "Apollo/Sources/Apollo/JSONStandardTypeConversions.swift", "Apollo/Sources/Apollo/Locking.swift", "Apollo/Sources/Apollo/NetworkTransport.swift", "Apollo/Sources/Apollo/NormalizedCache.swift", "Apollo/Sources/Apollo/Promise.swift", "Apollo/Sources/Apollo/Record.swift", "Apollo/Sources/Apollo/RecordSet.swift", "Apollo/Sources/Apollo/Result.swift", "Apollo/Sources/Apollo/ResultOrPromise.swift", "Apollo/Sources/Apollo/Utilities.swift", "Internal/AWSAppSyncRetryHandler.swift", "Internal/AWSAppSyncSubscriptionMetadataCache.swift", "Internal/AWSConfigurationFile.swift", "Internal/AWSMutationCache.swift", "Internal/AWSMutationRetryAdviceHelper.swift", "Internal/AWSMutationRetryNotifier.swift", "Internal/AWSMutationState.swift", "Internal/AWSOfflineMutation.swift", "Internal/AWSPerformMutationQueue.swift", "Internal/AWSRequestBuilder.swift", "Internal/AWSSQLiteNormalizedCache.swift", "Internal/AppSyncLogHelper.swift", "Internal/AppSyncLogWrapper.swift", "Internal/AppSyncSubscriptionWithSync.swift", "Internal/AuthInterceptor/IAMAuthInterceptor.swift", "Internal/AuthInterceptor/LambdaAuthInterceptor.swift", "Internal/BasicAWSAPIKeyAuthProvider.swift", "Internal/CachedMutationOperation.swift", "Internal/Foundation+Utils.swift", "Internal/InternalS3ObjectDetails.swift", "Internal/NetworkReachabilityNotifier.swift", "Internal/SQLiteSerialization.swift", "Internal/SessionMutationOperation.swift", "Internal/SubscriptionFactory/APIKeyBasedConnectionPool.swift", "Internal/SubscriptionFactory/AppSyncRealTimeClientOIDCAuthProvider.swift", "Internal/SubscriptionFactory/ConnectionPool/BasicSubscriptionConnectionFactory.swift", "Internal/SubscriptionFactory/IAMBasedConnectionPool.swift", "Internal/SubscriptionFactory/LambdaBasedConnectionPool.swift", "Internal/SubscriptionFactory/OIDCBasedConnectionPool.swift", "Internal/SubscriptionFactory/SubscriptionConnectionFactory.swift", "Internal/SubscriptionFactory/UserPoolsBasedConnectionPool.swift", "Internal/SubscriptionMessageQueue.swift", "Internal/SyncConfiguration.swift", "Internal/SyncStrategy.swift", "NetworkReachability.swift" ], "module_type": "SwiftTarget", "product_memberships": [ "AWSAppSync" ], "target_dependencies": [] } ], "products": [ { "name": "AWSAppSync", "type": { "library": [ "automatic" ] }, "targets": [ "AWSAppSync" ] } ], "platforms": [], "dependencies": [ { "url": "", "name": "AWSiOSSDKV2", "requirement": { "range": [ { "lower_bound": "2.26.0", "upper_bound": "2.27.0" } ] } }, { "url": "", "name": "AppSyncRealTimeClient", "requirement": { "range": [ { "lower_bound": "1.4.3", "upper_bound": "2.0.0" } ] } }, { "url": "", "requirement": { "range": [ { "lower_bound": "0.12.0", "upper_bound": "1.0.0" } ] } }, { "url": "", "name": "Reachability", "requirement": { "range": [ { "lower_bound": "5.0.0", "upper_bound": "6.0.0" } ] } } ], "tools_version": "5.3" }

Building a Client App

If you are building complete client application workflows, including integration with other AWS services such as Amazon Cognito, Amazon S3, or Amazon Pinpoint to provide full capabilities around User Sign-Up/Sign-In, rich media, and analytics we suggest using the Amplify Framework. Amplify is an opinionated client framework for building web and mobile applications with full support for building apps from your local workstation, including GraphQL provisioning and workflows for CI/CD. This includes JavaScript-based application support (such as React, React Native, Angular, and Vue) as well as native iOS and Android.

Additionally, you can use the AppSync SDK for Apollo to perform GraphQL queries or mutations from a NodeJS application, such as a Lambda function with the following tutorial.


Ios aws appsync

User settings sync for iOS with AWS AppSync

Amazon Cognito Sync is a service that you can use for syncing application-related user profile data across devices. The client library caches the data locally so that the app can read and write data, regardless of the device connectivity state. The data stored is generally shown as a key-value pair, where the keys and values are both strings.

However, many organizations need to store data in a common store. For example, you might want to do backend searches to enable you to segment users, do A/B testing, store binary data like profile pictures, or link the data to alternate data sources.

In a previous article, I created a data store for storing user settings by using AWS AppSync, which provides a similar structure as Amazon Cognito Sync, but has some additional functionality. AWS AppSync is a GraphQL-based managed service with real-time and offline capabilities.

In this article, I build a simple iOS application that demonstrates the ability to synchronize application-related user profile data across devices by using the data store that I created earlier. If you haven’t already done so, return to the previous article and set up the cloud data store.

Option 1: Quick start (15 minutes)

In this quick start option, I take an existing project that you can download, update it to specify the location of the user settings store in the AWS Cloud, run the sample mobile app, then verify that the data is stored in the appropriate place.

  1. Download the sample repository. Choose Clone or download, and then choose Download ZIP.
  2. Unpack the ZIP file.
  3. Open the Terminal app, and then use cd to change directory to the location of the unpacked files.
  4. Run the following:
  5. Open the project in Xcode by double-clicking on from within Finder.
  6. Expand to find the file.
  7. Open in the editor. Change the following variables:
    • Set to the region that your GraphQL API is deployed to.
    • Set to the URL of the GraphQL API.

You can find these values from the AWS AppSync console. The API is listed immediately after choosing the API from the API list. The region is embedded in the URL.

  1. Download the file and add it to your project:
    • Open the AWS Mobile Hub console, and then choose your project.
    • Choose the Integrate button on the iOS app panel.
    • Choose Download Cloud Config. This downloads the file.
    • Drag and drop the file onto your project in the same location as the project file.
    • Choose Finish.
  2. Run your app in the simulator.

The sample mobile app provides four theme options. Changing the theme also changes the colors that are associated with the app. If you check the backend data store, you’ll see that your theme is stored in the settings store. Also, if you implement the Android version of the app, you’ll notice that changes to the theme on iOS are also reflected in the Android app.

Option 2: Access the settings store from your own app

When you integrate user settings with your own app, you need to specify the model and operations. Then you create a repository pattern to synchronize the settings with the AWS AppSync backend. You can use any project for this option. For this walkthrough, I’m using the AWS Mobile iOS Notes app, and have already walked through the complete tutorial for integrating analytics, authentication and data access. Ensure that you have a working app before starting this section.

Step 1: Create the GraphQL schema and operations files

Create a new folder in the root of your iOS project for the GraphQL files. The root folder is called and contains the file for the project. To create the folder within Xcode:

  • Right-click MyNotes and choose New Group.
  • Type the name GraphQLOperations as the name of the new group.

Download the AWS AppSync schema:

  • Open the AWS AppSync console and choose your GraphQL API.
  • At the bottom of the API page, choose the iOS tab.
  • Under step 3, choose schema.json from the Export schema drop-down.
    • Do NOT download the schema.graphql file because that’s not needed for the code generation process that follows.
  • Drag and drop the file into the GraphQLOperations folder within Xcode.
  • Choose Finish.

Create an file:

  • Right-click GraphQLOperations and choose New File.
  • Type Empty in the search field, then press Enter. Choose Empty in the Other section.
  • Choose Next.
  • Type operations.graphql in the Save As field, and then choose Create.
  • Copy the following code into the newly created file:

Step 2: Generate the iOS code for GraphQL

First, install the code generator. In a terminal, run:

This only needs to be done once. Then change the directory to your project directory (this contains the file). To generate the appropriate code, run:

This should be entered on a single line. Add the generated file to your Xcode project:

  • Right-click the MyNotes folder within your Xcode project.
  • Choose Add Files to “MyNotes”.
  • Find and choose API.swift.
  • Choose Add.

Step 3: Add the AWS Mobile Client SDK to the project

Close Xcode. Open a terminal at your project root (the directory contains a ). Open the , and add the following dependencies (example):

Save the file, and then run pod install. After the installation is completed, re-open Xcode by double-clicking the file. Rebuild your app by using Project > Build.

Step 4: Initialize the AWS AppSync client

Create a new Swift file called with the following contents:

As before, replace the region and endpoint URL with the values from the AWS AppSync console. Then open . Add the following variable to the class:

Add the initialization code to the method for customizing the application launch:

Step 5: Obtain (and store) the settings

Edit the file. Add the following to the top of the file:

This code imports the AWS AppSync library. It also extends to allow us to specify RGB hex values (such as those used in HTML and CSS). Add the following variable to the top of the class:

Add the following function to the class to change the color of the header based on the theme:

Finally, add the following function to the class to perform the query and update the theme with the returned values:

The is a class that’s created during code generation. You can add a new view controller to update the settings by using a mutation as well. Refer to the AWS AppSync Developer Guide for more details on running a mutation.

Run the Notes app to see your stored theme. The navigation bar changes color quickly within the simulator to the theme you selected in the sample mobile app. Now close the app and open the sample mobile app. Choose a different theme, then switch back to the Notes app and note that the navigation bar has changed color.


AWS AppSync provides many benefits over Amazon Cognito Sync for application settings, and we’ve just scratched the surface here. In AWS AppSync, you can store basic key-value pairs, complex objects, or even users’ profile pictures—and this data will be synchronized to all user devices. In addition, AWS AppSync offers a single-data access layer for application data with real-time updates and offline capabilities. This makes it an ideal tool for cloud-enabled data-driven apps. Learn more about AWS AppSync now.

Realtime Chat App with AWS DynamoDB - AWS Amplify

AWS AppSync SDK for iOS

ReleaseCocoaPodsCarthage compatibleBuild StatusDocumentation StatusSwiftTwitter Follow

The AWS AppSync SDK for iOS enables you to access your AWS AppSync backend and perform operations like , , and . The SDK also includes support for offline operations. This SDK is based off of the Apollo project found here. Please log questions for this client SDK in this repo and questions for the AppSync service in the official AWS AppSync forum.


Note: AWS AppSync uses Swift 5.1. Use Xcode 11.0 or greater to build.

Installing the SDK

Via Swift Package Manager

  1. Swift Package Manager is distributed with Xcode. To start adding the AWS SDK to your iOS project, open your project in Xcode and select File > Swift Packages > Add Package Dependency.

  2. Enter the URL for the AWS AppSync SDK for iOS GitHub repo () into the search bar and click Next.

  3. You'll see the repository rules for which version of the SDK you want Swift Package Manager to install. Choose the first rule, Version, and select Up to Next Major as it will use the latest compatible version of the dependency that can be detected from the branch, then click Next.

  4. Choose the AWSAppSync package product and click Finish.

  5. In your source file, import the SDK using .

Via CocoaPods

  1. Add the following line to your Podfile:

    pod'AWSAppSync','~> 3.4.1'


    # Uncomment the next line to define a global platform for your project# platform :ios, '9.0'target'EventsApp'do# Comment the next line if you're not using Swift and don't want to use dynamic frameworksuse_frameworks!# Pods for EventsApppod'AWSAppSync','~> 3.4.1'end
  2. Run to install the AppSync SDK, then open the file (not the file) in Xcode.

  3. Now Build your project to start using the SDK. Whenever a new version of the SDK is released you can update by running and rebuilding your project to use the new features.

  4. In your source file, import the SDK using .

Via Carthage

XCFrameworks (recommended)

Carthage supports XCFrameworks in Xcode 12 or above. Follow the steps below to consume the AWS SDK for iOS using XCFrameworks:

  1. Install Carthage 0.37.0 or greater.

  2. Add the following to your :

  3. Then run the following command:

  4. On your application targets’ General settings tab, in the Embedded Binaries section, drag and drop each xcframework you want to use from the Carthage/Build folder on disk.

Note: If you are using XCFrameworks (i.e., either Carthage or Dynamic Frameworks), the module is named as to work around a Swift issue. To use , import it as:

and use it your app code without the suffix.

Frameworks with "fat libraries" (not recommended)

To build platform-specific framework bundles with multiple architectures in the binary, (Xcode 11 and below)

  1. Add the following to your Cartfile:

  2. Once complete, run and open the with Xcode and chose your . In the tab, find , then choose the button.

  3. Choose the button, navigate to the files under and select and its required dependencies:

    • AWSAppSync.framework
    • AWSCore.framework
    • Reachability.framework
    • SQLite.framework
    • AppSyncRealTimeClient.framework
    • Starscream.framework

    Do not select the if needed check box when prompted.

  4. Under the tab in your , choose the button on the top left and then select . Setup the build phase as follows. Make sure this phase is below the Embed Frameworks phase.



    • Shell: /bin/sh
    • Show environment variables in build log: Checked
    • Run script only when installing: Not checked
    • Input Files: Empty
    • Output Files: Empty
  5. Now Build your project to start using the SDK. Whenever a new version of the SDK is released you can update by running and rebuilding your project to use the new features.

    Note: Currently, the AWSAppSync SDK for iOS builds the Carthage binaries using Xcode 12.0. To consume the pre-built binaries your Xcode version needs to be the same. Otherwise you will have to build the frameworks on your machine by passing flag to command.

  6. In your source file, import the SDK using .


To use the AppSync SDK, you will need to use from the AWS Amplify CLI. This command will generate Swift-language files corresponding to your schema. You can interact with these classes instead of operating on GraphQL query documents, directly. You can find the instructions to use the codegen here.


You can find a sample app which uses the AppSync SDK here:


You can find a step by step walk through of setting up codegen backend and accessing it via the iOS client here:


Contributing guidelines are noted here.

Testing Contributions

If you are contributing to the SDK, it is recommended to add some unit and/or integration tests and evaluate against existing tests.

Invoking tests

The target is configured to run both Unit and Integration tests in its configuration. After completing integration test setup following the instructions below, you can run both suites by invoking "Product > Test" (⌘-U) in Xcode.

To run only one suite of tests (Unit or Integration), select the appropriate target from the Scheme selector and invoke "Product > Test" (⌘-U). While Unit tests run much faster than Integration tests, we recommend running both before submitting a PR.

Setting up unit tests

Unit Tests do not require any specific setup and can be run directly from your Xcode IDE.

  • NOTE: Currently, any test that requires network activity is placed in Integration tests, even if the test hits localhost and not a valid service.

Setting up integration tests

To run integration tests, you will need the following:

  • Two AppSync API instances with an schema.
    • The first AppSync instance should be configured to use a Cognito Identity Pool with unauthenticated identities supported.
      • The Cognito Identity Pool's unauth role should have the permission.
    • The second instance should be configured to use API Key authentication.

You can get the backend setup by following the steps below:

  1. Create a stack with an AppSync API using API Key authentication
    1. Go to the AWS CloudFormation console.
    2. Click on Create stack and then select Upload a template file. Click Choose File, and navigate to the Cloud Formation Template in this project:
    3. Click Next
    4. Type a "Stack name" and a "ResourceNamePrefix"
      • We recommend using a "ResourceNamePrefix" that makes it easy to tell that the stack is used for AppSync tests, such as .
      • Because you will create two stacks for these tests, one using API Key authentication and one using IAM (Cognito Identity) authentication, we recommend selecting a stack name that makes it easy to differentiate between the two, such as and .
    5. Select the Auth Type
    6. Once the stack is complete, click on the Output tab.
    7. Copy the appropriate values to the test configuration file :
    8. Create another CloudFormation Stack following steps 1-6 above, but select the "IAM" Auth Type in step 5.
      1. Copy the appropriate values to the test configuration file :
      2. Create another CloudFormation Stack following step 1-6 above with as the Auth type (we'll change that later)
        1. Create a Lambda function using the template provided in this project at

        2. Once the stack is complete click on the Outputs tab

        3. Copy the appropriate values to the test configuration file :

          • Go to the AWS AppSync console, select the newly created AppSync instance

          • In the section, change the default authentication type to and select the Lambda function created at the previous step

        Note: You must either provide all values in the or in code. There is no mechanism to handle partial overrides of one source with the other. All values must be specified before running the integration tests.

        Option 1: Use a test configuration file

        Add a file (see sample below) in the folder and replace the values for , , , and regions if required:

        { "AppSyncEndpoint": "", "AppSyncRegion": "us-east-1", "CognitoIdentityPoolId": "us-east-1:abcd1234-1234-12324-b4b7-aaa0c0831234", "CognitoIdentityPoolRegion": "us-east-1", "AppSyncEndpointAPIKey": "", "AppSyncEndpointAPIKeyRegion": "us-east-1", "AppSyncAPIKey": "da2-sad3lkh23422", "BucketName": "bucketName", "BucketRegion": "us-east-1", "AppSyncMultiAuthAPIKey": "da2-sd34s5ffxz" }

        Note: The endpoint uses based auth, while uses the based auth.

        Option 2: Edit defaults in source code

        Edit the file with appropriate values.

        Now you should be able to run the integration tests by invoking "Product > Test" (⌘-U) in Xcode.


        This library is licensed under the Amazon Software License.


        You will also be interested:

        As a result, I had to make a gate. Because she pulled me out of the house several times, so that I would help her to open them, then close them. And then I made them.

        256 257 258 259 260