AWS上のRDS(MySQL)にiOSアプリからアクセスするための手順です。
すべての作業をスムーズに進めるため、次の作業を終えている必要があります。
- AWSアカウントの作成
- Python2.7、pipのインストール
- CocoaPodsのインストール
また、AWSで行うすべての作業が同一リージョンで行われることを前提としています。
AWSでRDSインスタンスを作成する
AWSコンソールのRDSにアクセスし、DBインスタンスの起動をクリックします。

ユースケースは開発/テストを選択し、次へをクリックします。
※使用する環境に適したユースケースを設定してください。

DB詳細の指定では最下部にある設定の各項目に入力します。
DBインスタンス識別子にはSampleInstanceと入力します。
マスターユーザの名前及びマスターパスワードにはDBにアクセス可能なユーザ情報を入力します。
マスターユーザのアカウント情報は後の作業使うため、メモに残します。
入力を終えたら次へをクリックします。

[詳細設定]の設定を行います。
ネットワーク&セキュリティの各項目を下図のように設定します。

データベースの設定ではデータベースの名前にSampleDBと入力します。
データベース名は後の作業で使うため、メモに残します。

その他項目は初期状態のままで問題ありません。
入力が完了したら最下部にあるDBインスタンスの作成をクリックします。
処理が完了するまで暫く待ちます。
処理中にDBインスタンスの詳細の表示をクリックしても問題ありません。

DBインスタンスの詳細画面の要約にあるDBインスタンスのステータスが利用可能であれば、正常にDBが作成されています。

セキュリティグループのインバウンド制約を変更し、Lambda関数からアクセスできるようにします。
セキュリティグループをクリックし、管理画面を表示します。

画面下部にあるインバウンドタブをクリックし、編集をクリックします。

ソース欄のIPアドレスを0.0.0.0/0に変更し、保存をクリックします。

セキュリティグループの管理画面を終了します。
最後にDBインスタンスの詳細画面から今後使用する情報をメモに残します。
- VPC
- サブネットグループ
- サブネット
- セキュリティグループ
- エンドポイント
Mobile HubでiOSアプリを追加する
AWSコンソールのMobile Hubにアクセスし、Createをクリックします。

プロジェクト名にSampleAppと入力し、Nextをクリックします。

Set up your backendでは何も行わずにNextをクリックします。

Connect to your backendでは何も行わずにDoneをクリックします。

SampleAppの設定画面下部Add More Backend Features中のCloud Logicをクリックします。

API nameにExecuteSQLと入力し、Create APIをクリックします。

この状態になるとAPIの作成完了です。
自動的にLambda及びAPI Gatewayにそれぞれ処理が追加されています。

Lambdaのデプロイパッケージを作成する
ローカル環境でLambdaにデプロイするためのパッケージを作成します。
環境はPython2.7を用います。
まず何れかの場所に作業フォルダを作成します。
テキストエディットで新規書類を作成し、次のコードを入力します。
"エンドポイント" "マスターユーザ名" "マスターユーザパスワード" "データベース名"はMySQLインスタンス作成時にメモした情報に置き換えます。
host_url = "エンドポイント"
db_username = "マスターユーザ名"
db_password = "マスターユーザパスワード"
db_name = "データベース名"
入力を終えたらrds_config.pyという名称で作業フォルダに保存します。
再度テキストエディットで新規書類を作成し、次のコードを入力します。
注意:Pythonはインデントが 超重要 な言語です。入力の際はインデントがズレないように気をつけます。
import sys
import logging
import rds_config
import pymysql
import json
rds_host = rds_config.host_url
name = rds_config.db_username
password = rds_config.db_password
db_name = rds_config.db_name
logger = logging.getLogger()
logger.setLevel(logging.INFO)
try:
conn = pymysql.connect(rds_host, user=name, passwd=password, db=db_name, connect_timeout=5)
except:
logger.error("ERROR: Unexpected error: Could not connect to MySql instance.")
sys.exit()
logger.info("SUCCESS: Connection to RDS mysql instance succeeded")
def handler(event, context):
if ("body" in event):
param = event["body"]
if (isinstance(param, unicode)):
paramDic = json.loads(param)
else:
paramDic = param
if ("sql" in paramDic):
sql = paramDic["sql"].strip()
logger.info(sql)
if sql.upper().find("SELECT") == 0:
with conn.cursor(pymysql.cursors.DictCursor) as cur:
cur.execute(sql)
data = cur.fetchall()
result = {
"body": json.dumps(data)
}
else:
with conn.cursor() as cur:
cur.execute(sql)
conn.commit()
result = {
"body": "executed: " + sql
}
else:
result = {
"body": """ "sql" param not exsists. """
}
else:
result = {
"body": "body is not exists"
}
return result
入力を終えたらapp.pyという名称で作業フォルダに保存します。
pipコマンドでpymysqlライブラリを作業フォルダにインストールします。
コンソールを開き、次のコマンドを実行します。
$pip install PyMySQL -t 作業フォルダのパス
作業フォルダ内に準備した4つのファイルとフォルダを圧縮します。
圧縮ファイル名はapp.zipとします。
注意:作業フォルダごと圧縮しないよう気をつけてください。
Lambda関数の実行環境を設定する
AWSコンソールのAWS Lambdaにアクセスし、画面左にある関数をクリックします。
表示された関数一覧にMobile Hubにより自動作成された関数があることを確認します。

関数名をクリックし、詳細画面を表示します。
関数コードの各項目を次のように変更します。
- コードエントリタイプを
.zip ファイルをアップロードに変更 - ランタイムを
Python2.7に変更 - ハンドラを
app.handlerに変更
関数パッケージアップロードをクリックし、先程作成したapp.zipを選択します。

続けてサブネットとセキュリティグループもメモを元に設定します。

サンプルアプリを実行
Mobile Hubからサンプルアプリのプロジェクトファイルをダウンロードし、正しくSQL問い合わせができることを確認します。
AWSコンソールのMobile Hubにアクセスし、SampleAppを選択します。

SampleApp詳細画面右上にあるResourcesをクリックします。

Downloadをクリックし、表示されるドロップダウンではiOS Swiftを選択します。

SampleApp-aws-my-sample-app-ios-swift.zipがダウンロードされるので、任意の場所で展開します。
コンソールを開き、以下のコマンドで関連ライブラリをインストールします。
$cd 展開したフォルダ内の podfile までのパス
$pod install
インストールが完了したらMySampleApp.xcworkspaceを開き、実行します。

サンプルアプリで動作確認
アプリトップ画面に表示されているCloud Logicをタップします。

案内画面下部にあるDemo Cloud Logicをタップします。

Select Method一覧にあるPOSTをタップします。

Request Bodyの値を書き換え、Invokeをタップすることで結果がResponseに表示されます。
一連のタスクを実行し、iOSアプリからAWS RDSに対して問い合わせが行われることを確認します。
Request bodyその1
{
"sql" : "create table Employee3 ( EmpID int NOT NULL, Name varchar(255) NOT NULL, PRIMARY KEY (EmpID))"
}
Response
executed: create table Employee3 ( EmpID int NOT NULL, Name varchar(255) NOT NULL, PRIMARY KEY (EmpID))
Request bodyその2
{
"sql" : "insert into Employee3 (EmpID, Name) values(1, 'Joe')"
}
Response
executed: insert into Employee3 (EmpID, Name) values(1, 'Joe')
Request bodyその3
{
"sql" : "insert into Employee3 (EmpID, Name) values(2, 'Bob')"
}
Response
executed: insert into Employee3 (EmpID, Name) values(2, 'Bob')
Request bodyその4
{
"sql" : "insert into Employee3 (EmpID, Name) values(3, 'Mary')"
}
Response
executed: insert into Employee3 (EmpID, Name) values(3, 'Mary')
Request bodyその5
{
"sql" : "select * from Employee3"
}
Response
[{\"EmpID\": 1, \"Name\": \"Joe\"}, {\"EmpID\": 2, \"Name\": \"Bob\"}, {\"EmpID\": 3, \"Name\": \"Mary\"}]









