使用AWS Amplify进行iOS应用程序开发入门(第3部分)
总结
使用iOS应用程序通过AppSync实现将数据存储到DynamoDB的部分,并使用GraphQL进行实现。
此外,使用Cognito进行身份验证部分,并使用AWS Amplify进行AppSync的构建。
前提条件
AWS Amplify入门iOS应用开发(第一部分)和AWS Amplify入门iOS应用开发(第二部分)已经完成。
我们将使用在第一部分创建的Xcode项目。
使用AWS Amplify构建AppSync。
# Xcodeのルートプロジェクトに移動
$ cd ~/Downloads/amplify-learn
# AppSyncを作成(実際に作成されるのは「amplify push」後)
$ amplify add api
# Please select from one of the below mentioned services
# →GraphQLを選択
# Provide API name
# →amplifylearnを選択(名前は任意)
# Choose an authorization type for the API
# →Amazon Cognito User Poolを選択
# Do you have an annotated GraphQL schema?
# →Noを選択
# Do you want a guided schema creation?
# yesを選択
# What best describes your project
# →Single object with fields (e.g., “Todo” with ID, name,description)を選択
# Do you want to edit the schema now?
# →Noを選択
# AppSyncを作成するようにクラウド側に命令
$ amplify push
# Are you sure you want to continue?
# →yを選択
# Do you want to generate code for your newly created GraphQL API
# →yを選択
# Enter the file name pattern of graphql queries, mutations and subscriptions(graphql/**/*.graphql)
# →デフォルトのままEnterキーを押す
# Do you want to generate/update all possible GraphQL operations - queries, mutations and subscriptions
# →yを選択
# Enter the file name for the generated code (API.swift)
# →デフォルトのままEnterキーを押す
本文介绍了上述命令的基本内容。
本次将使用GraphQL在云端进行数据交互。
对GraphQL的详细解释将在本次讨论中省略。
首先,在运行`amplify add api`命令时,GraphQL的模式定义将保存在`~/Downloads/amplify-learn/amplify/backend/api/amplifylearn/schema.graphql`文件中。
type Todo @model {
id: ID!
name: String!
description: String
}
@model指令表示将数据保存到DynamoDB,因此只需进行上述模式定义,执行amplify push后,DynamoDB表将自动创建。(有关指令说明,请参阅这里的“使用GraphQL转换器”部分)
通过运行$ amplify push,将会启动CloudFormation并创建AppSync。
您将被问到一些问题,但“Do you want to generate code for your newly created GraphQL API”是最重要的问题。
通过回答yes来自动创建在iOS中使用AppSync的函数。
首先,在graphql目录下会创建包含突变、查询和订阅定义的文件。

根据此文件,在Swift代码中自动生成且保存至API.swift的代码,可以方便地执行GraphQL的突变、查询和订阅,从而实现对GraphQL的简单操作。
而且,我们可以看到在awsconfig.json中添加了AppSync项目,并记录了GraphQL的终端节点。
"AppSync": {
"Default": {
"ApiUrl": "https://vf5rq526ubhxxxxxxxxxxxx.appsync-api.ap-northeast-1.amazonaws.com/graphql",
"Region": "ap-northeast-1",
"AuthMode": "AMAZON_COGNITO_USER_POOLS"
}
}
使用AppSync将数据存储到DynamoDB的实现部分
安装要使用的 iOS SDK。
请修改Podfile文件如下。
target 'amplify-learn' do
use_frameworks!
# Pods for amplify-learn
pod 'AWSMobileClient', '~> 2.7.0'
pod 'AWSAuthUI', '~> 2.7.0'
pod 'AWSUserPoolsSignIn', '~> 2.7.0'
pod 'AWSS3', '~> 2.7.0'
pod 'AWSAppSync', ' ~> 2.6.24' # AppSync用のSDKを追加
end
# Xcodeプロジェクトのルートに移動
$ cd ~/Downloads/amplify-learn
# 必要なSDKを追加
$ pod install --repo-update
最后,将API.swift包含到Xcode项目中。
amplify-learn.xcworkspaceを開く
プロジェクト直下にAPI.swiftをドラッグ&ドロップする
Copy items if neededのチェックを外し、Create groupsを選択し、「Finish」をクリックする
进行AppSync的设置
将以下代码添加到AppDelegeta.swift文件中。
进行AppSync的初始设置。
本次设置使用Cognito用户池。
注意:以下代码是摘录,所以请不要删除未提及的行。
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let databaseURL = URL(fileURLWithPath:NSTemporaryDirectory()).appendingPathComponent("database_name")
do {
// Initialize the AWS AppSync configuration
let appSyncConfig = try AWSAppSyncClientConfiguration(appSyncClientInfo: AWSAppSyncClientInfo(),
userPoolsAuthProvider: {
class MyCognitoUserPoolsAuthProvider : AWSCognitoUserPoolsAuthProviderAsync {
func getLatestAuthToken(_ callback: @escaping (String?, Error?) -> Void) {
AWSMobileClient.sharedInstance().getTokens { (tokens, error) in
if error != nil {
callback(nil, error)
} else {
callback(tokens?.idToken?.tokenString, nil)
}
}
}
}
return MyCognitoUserPoolsAuthProvider()}(),
databaseURL:databaseURL)
// Initialize the AWS AppSync client
appSyncClient = try AWSAppSyncClient(appSyncConfig: appSyncConfig)
} catch {
print("Error initializing appsync client. \(error)")
}
}
接下来在ViewController.swift中添加AppSync配置。
请注意以下代码也是一个摘要,所以请不要删除没有提到的行。
import AWSAppSync
class ViewController: UIViewController {
var appSyncClient: AWSAppSyncClient?
override func viewDidLoad() {
super.viewDidLoad()
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appSyncClient = appDelegate.appSyncClient
}
}
实现向DynamoDB添加记录的部分
请在ViewController.swift中添加以下函数来实现向DynamoDB中添加记录的部分。
func runMutation(){
let mutationInput = CreateTodoInput(name: "Use AppSync", description:"Realtime and Offline")
appSyncClient?.perform(mutation: CreateTodoMutation(input: mutationInput)) { (result, error) in
if let error = error as? AWSAppSyncClientError {
print("Error occurred: \(error.localizedDescription )")
}
if let resultError = result?.errors {
print("Error saving the item on server: \(resultError)")
return
}
}
}
我会简单解释一下上述代码。
CreateTodoInput(name: “Use AppSync”, description:”Realtime and Offline”)
CreateTodoInput是在API.swift文件中定义的一个函数,它是自动生成的一个结构体。
通过使用这个函数,我们可以创建输入参数。
在这个例子中,我们决定创建一个名为“Use AppSync”,描述为“Realtime and Offline”的TODO。
如果appSyncClient不为空,就执行appSyncClient.perform(mutation: CreateTodoMutation(input: mutationInput))这个方法,当执行完后会回调闭包(result, error)。这里也一样,CreateTodoMutation是在API.swift中定义的一个类。当执行appSyncClient.perform方法时,会调用设置在AppSync的createTodo上的resolver,并将数据添加到DynamoDB中。(参见下图)


让我们将按钮放置并配置为运行runMutation函数。
在Main.storyboard中添加一个名为“向Dynamo添加数据”的按钮,并向ViewController.swift添加一个动作连接。
连接类型为Action,名称设置为pushDataToDynamo。
函数应该类似以下内容。
@IBAction func pushDataToDynamo(_ sender: Any) {
runMutation()
}
当您点击”向Dynamo添加数据”按钮时,您会发现数据已成功添加到DynamoDB中。页面的布局如下图所示。

获取DynamoDB数据的实现部分
请按照向 Dynamo 添加数据的步骤,进行添加按钮和修改代码。
在Main.storyboard中添加一个名为“从 Dynamo 获取数据”的按钮,并将其连接到ViewController.swift上的动作。
连接应该是动作,名称设置为getDynamoData。
此外,请添加runQuery函数。
@IBAction func getDynamoData(_ sender: Any) {
runQuery()
}
func runQuery(){
appSyncClient?.fetch(query: ListTodosQuery()) {(result, error) in
if error != nil {
print(error?.localizedDescription ?? "")
return
}
result?.data?.listTodos?.items!.forEach { print(($0?.name)! + " " + ($0?.description)!) }
}
}
关于runQuery函数,简单解释一下。
runMutation函数具有相似的结构,但在result?.data?.listTodos?.items!.forEach { print(($0?.name)! + ” ” + ($0?.description)!) }部分,我们编写了一个操作,它将获取的记录的name和description显示在控制台上。
当您启动模拟器并单击“从Dynamo获取数据”按钮时,您会发现数据会显示在控制台上(见下图)。



订阅DynamoDB记录添加的部分的实现
实现在 DynamoDB 收到新数据时能够接收该数据的订阅功能。由于可以只接收新添加的数据而不是所有数据,所以可以用于实现发布包括更新信息在内的功能。
依旧进行按钮添加和代码修改。
在Main.storyboard中添加”开始订阅”按钮,并为ViewController.swift添加一个连接。
连接为Action类型,名为startSubscribe。
同时,请添加subscribe函数。
@IBAction func startSubscribe(_ sender: Any) {
subscribe()
}
var discard: Cancellable?
func subscribe() {
do {
discard = try appSyncClient?.subscribe(subscription: OnCreateTodoSubscription(), resultHandler: { (result, transaction, error) in
if let result = result {
print(result.data!.onCreateTodo!.name + " " + result.data!.onCreateTodo!.description!)
} else if let error = error {
print(error.localizedDescription)
}
})
} catch {
print("Error starting subscription.")
}
}
订阅功能与之前的功能具有相同的结构,但订阅的不同之处在于它会在后台持续运行。

总结
我使用AppSync来解释了如何对DynamoDB进行操作。但是,我省略了关于AppSync和GraphQL的详细说明,所以整篇文章可能不太容易理解。关于AppSync和GraphQL,由于我自己也没有完全理解,我计划在另一篇文章中进行详细解释。
通过AWS Amplify进行iOS应用开发的入门已经在本文中结束。
感谢您的阅读。