Getting Started with AWS AppSync for iOS
Learn how to consume GraphQL APIs in your SwiftUI iOS apps in a simple and type-safe way using AWS AppSync framework. By Alex Brown.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Getting Started with AWS AppSync for iOS
30 mins
- Getting Started
- About GraphQL and AppSync
- What is GraphQL?
- GraphQL with AWS AppSync
- Installing the Amplify Framework
- Installing npm
- Installing Amplify CLI
- Installing CocoaPods
- Adding Amplify to the Project
- Adding AppSync Script
- Initializing Amplify
- Creating Models Using GraphQL
- Using Amplify in the App
- Building the To Do List UI
- Adding Rows to the To Do List
- Setting up Your Data
- Adding Sections
- Adding a To Do
- Creating and Editing To Dos
- Adding To Dos
- Completing To Dos
- Deleting To Dos
- Where to Go From Here?
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.
sudo gem install cocoapods
After a short delay you should see Successfully installed cocoapods-VERSION
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 cd
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 # Pods for RazeList
:
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.
You’ll notice a new Run Script entry at the bottom of the list. Click the arrow to expand it.
Inside the code editor at the top, add the following code:
"${PODS_ROOT}/AmplifyTools/amplify-tools.sh"
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 push
and modelgen
to true
.
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 AppDelegate
class, add the following code before return true
in the application(_:didFinishLaunchingWithOptions:)
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.
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 TodoRowView
declaration, add the following.
// 1
let todoItem: Todo
// 2
let onToggleCompleted: (Todo) -> Void
The to do row defines two requirements.
- A
Todo
model to use for rendering. - 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 TodoRowView_Previews
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 TodoRowView
:
func toggleCompleted() {
withAnimation {
onToggleCompleted(todoItem)
}
}
This function simply wraps onToggleCompleted
in an animation block that will animate the movement of the row between sections.
Next, replace the entire body
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(todoItem.name)
.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:
- Define a
VStack
container. - Define an
HStack
containing a button with a checkbox image. The image is either checked or unchecked depending on the state the to do model’scompleted
property. Tapping the button will callonToggleCompleted(_:)
. - The second item in the stack is a
Text
view containing the name of the to do. - If the to do contains a description, render it inside a
Text
view.