LoginSignup
15
14

More than 5 years have passed since last update.

AWS AmplifyによるiOSアプリ開発入門(Part2)

Last updated at Posted at 2018-11-27

概要

iOSアプリからS3にデータをアップロードする部分を実装します。
また、認証部分はCognitoを使い、S3バケットの作成はAWS Amplifyを使って行います。

前提条件

AWS AmplifyによるiOSアプリ開発入門(Part1)が完了していること
Part1で作成したXcodeプロジェクトをそのまま使用します

AWS Amplifyを使ってS3バケットを作成


# Xcodeのルートプロジェクトに移動
$ cd ~/Downloads/amplify-learn

# S3バケットを作成
$ amplify add storage
# サービスを聞かれるので、「Content」を選択
# ラベル名を聞かれるので、任意のラベル名を入力(今回はデフォルトの設定のまま)
# S3のバケット名を聞かれるので、任意の名前を入力(今回はデフォルトの設定のまま)
# 誰がアクセス出来るかを聞かれるので、「Auth users only」を選択
# 認証ユーザーの権限を聞かれるので、「read/write」を選択

# S3バケットを作成するようにクラウド側に命令
$ amplify push
# 続けていいか聞かれるので、trueを選択

上記コマンドを実行すると、S3バケットが作成されます
また、IDプールで設定されている認証されたロールに、作成したバケットへのアクセス権限が
付与されていることが確認できると思います
→つまり、Cognitoで認証されたユーザは今回作成したS3バケットにアクセスできる権限が自動的に付与されれるということ

S3アップロード機能の実装

まずは、必要となるSDKのインストールを行います
Podfileを以下のように編集してください

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' # S3用のSDKを追加
end

# Xcodeのルートプロジェクトに移動
$ cd ~/Downloads/amplify-learn

# 必要なSDKを追加
$ pod install --repo-update

次に、ボタンをクリックするとデータをアップロードする機能を追加します
amplify-learn.xcworkspaceを開きます
Main.storyboardに「S3アップロードボタン」を追加し、ViewController.swiftに対してアクション接続を追加してください
connectionはAction、NameをuploadDataToS3として設定します

ViewController.swiftを以下のように修正してください
transferUtility.uploadData関数の引数であるバケット名は適宜変更してください

ViewController.swift
import UIKit
import AWSMobileClient

// 以下を追加
import AWSS3

class ViewController: UIViewController {

    @IBAction func pushLogoutButton(_ sender: Any) {
        // サインアウト処理
        AWSMobileClient.sharedInstance().signOut()

        // サインイン画面を表示
        AWSMobileClient.sharedInstance().showSignIn(navigationController: self.navigationController!, { (userState, error) in
            if(error == nil){       //Successful signin
                DispatchQueue.main.async {
                    print("Logged In")
                }
            }
        })
    }

    // 以下の関数内の処理を追加
    @IBAction func uploadDataToS3(_ sender: Any) {
        let expression = AWSS3TransferUtilityUploadExpression()
        expression.progressBlock = {(task, progress) in
            DispatchQueue.main.async(execute: {
                // Do something e.g. Update a progress bar.
            })
        }

        var completionHandler: AWSS3TransferUtilityUploadCompletionHandlerBlock?
        completionHandler = { (task, error) -> Void in
            DispatchQueue.main.async(execute: {
                // Do something e.g. Alert a user for transfer completion.
                // On failed uploads, `error` contains the error object.
            })
        }

        let data: Data = ("hello world").data(using: .utf8)! // Data to be uploaded
        let transferUtility = AWSS3TransferUtility.default()

        let format:DateFormatter = DateFormatter()
        format.dateFormat = "yyyyMMdd-hhmmss"
        let dateString:String = format.string(from: Date())

        transferUtility.uploadData(data,
           bucket: "YOUR_BUCKET_NAME",
           key: "uploads/"+dateString+".txt",
           contentType: "text/plain",
           expression: expression,
           completionHandler: completionHandler).continueWith {
            (task) -> AnyObject? in
            if let error = task.error {
                print("Error: \(error.localizedDescription)")
            }

            if let _ = task.result {
                // Do something with uploadTask.
            }
            return nil;
        }
    }


    override func viewDidLoad() {
        super.viewDidLoad()

        AWSMobileClient.sharedInstance().initialize { (userState, error) in
            if let userState = userState {
                switch(userState){
                case .signedIn:
                    DispatchQueue.main.async {
                        print("Logged In")
                    }
                case .signedOut:
                    AWSMobileClient.sharedInstance().showSignIn(navigationController: self.navigationController!, { (userState, error) in
                        if(error == nil){       //Successful signin
                            DispatchQueue.main.async {
                                print("Logged In")
                            }
                        }
                    })
                default:
                    AWSMobileClient.sharedInstance().signOut()
                }
            } else if let error = error {
                print(error.localizedDescription)
            }
        }
    }
}

上記コードの詳細な説明は行いませんが、重要な関数は以下です。
この部分で、認証周りのデフォルトの設定を取得してくれますので、
認証周りを意識せずにS3アップロードを行うことが可能です。
すでにサインイン済みであればデータをS3にアップロードできますし、サインアウト状態では、アップロードできません。

let transferUtility = AWSS3TransferUtility.default()

最終的な画面は以下の図のようになるかと思います

iPhone_XR_-_12_1 2.png

S3アップロードボタンをクリックすると、S3にデータが送信され保存されていることが確認できると思います。
※もし、サインイン画面が表示された場合は、Part1で作成したユーザでサインインを行ってください

まとめ

AWS Amplifyを使用したS3バケットの作成方法について説明しました。
もちろん、AWS CLIからもバケットを作成することは出来ますが、AWS Amplifyを用いると、
プロジェクトごとにバックエンドをまとめることが可能になりますので便利です。
つまり、amplify deleteとすると、CognitoもS3バケットもまとめて削除できます。

また、iOS SDKを使用して、データをS3に保存する部分も説明しました。
AWSMobileClientを使えば、バックエンドの処理をすべて任せることが出来るので、
S3アップロードの実装で認証周りを気にする必要はありません。

次はApp Syncとの連携について書く予定ですが、少し時間がかかるかもですorz

15
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
14