iPhoneからAWS S3に、ライブラリから選択した画像ファイルを直接アップロードする

# 準備

- AWSアカウント
- [AWS Cognit(Manage Federated Identities)] (https://ap-northeast-1.console.aws.amazon.com/cognito/home?region=ap-northeast-1)
- AWS S3 でバケットを用意する。

# AWS Cognitの設定

僕はここでかなり詰まりました・・・
とりあえず、Manage Federated Identitiesから新しくpoolを作るんですが、

![hoge.png](https://qiita-image-store.s3.amazonaws.com/0/102160/728edb32-0bf7-e570-543f-da2b782510bd.png)

適当な名前を付けて、Enable access to unauthenticated identitiesにチェックをしてクリエイトしましょう。

そして、こいつにS3との連携を許可してやらなきゃいけないんですが、これの次の画面では、何も考えず**許可**を押してください。
※ここでRoleの編集をしようとして四苦八苦した・・・

そしてS3との連携許可については以下のリンクから行います
https://console.aws.amazon.com/iam/home#roles

ここで任意のRoleを選び、ポリシーのアタッチで、
**AmazonS3FullAccess**
を選択。

またインラインポリシーの「ポリシーの編集」をおして、以下のように編集します。

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "mobileanalytics:PutEvents",
                "cognito-sync:*",
                "cognito-identity:*",
                "s3:*"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}
```

これで設定は完了なのですが、**S3とCognitのRegionが同じになっていることは必ず確認しましょう。**
※ここでも超苦しんだ・・・

# iPhone側の実装

とりあえず、**AWSS3**をpod install して以下のコードを貼り付けて実行してみてください。

AppDelegate.swiftに以下の記述を追加。
Cognitの自分のpoolのsample codeをコピペしてるだけです。

```swift
import AWSS3

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        let credentialsProvider = AWSCognitoCredentialsProvider(regionType:.APNortheast1,
                                                                identityPoolId: "sample codeに書いてあるpool idを書いてください。"
        let configuration = AWSServiceConfiguration(region:.APNortheast1, credentialsProvider:credentialsProvider)
        AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = configuration

        return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
    }

```

ViewController

```swift
import UIKit
import AWSS3
     
     class ViewController: UIViewController, UIImagePickerViewControllerDelegate, UINavigationControllerDelegate {
     
         override func viewDidLoad() {
             super.viewDidLoad()
             setImagePickerController()
         }
     
         func setImagePickerController() {
             if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary) {
                 let imagePickerController = UIImagePickerController()
                 imagePickerController.sourceType = .PhotoLibrary
                 imagePickerController.allowsEditing = true
                 imagePickerController.delegate = profileEditVM
                 presentViewController(imagePickerController, animated: true, completion: nil)
             }
         }
     
         func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
             let uploadFileURL = editingInfo![UIImagePickerControllerReferenceURL] as! NSURL
             let imageName = uploadFileURL.lastPathComponent
             let documentDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first! as String
     
             let localPath = (documentDirectory as NSString).stringByAppendingPathComponent(imageName!)
     
             let image = editingInfo![UIImagePickerControllerOriginalImage] as! UIImage
             let data = UIImagePNGRepresentation(image)
             data!.writeToFile(localPath, atomically: true)
             
             let imageData = NSData(contentsOfFile: localPath)!
             let imageURL = NSURL(fileURLWithPath: localPath)
             
             let S3BucketName: String = "作ったバケット名を入れてください。"
             let S3UploadKeyName: String = "public/sample.png"
             
             let transferUtility = AWSS3TransferUtility.defaultS3TransferUtility()
             let expression = AWSS3TransferUtilityUploadExpression()
             
             transferUtility.uploadFile(imageURL, bucket: S3BucketName, key: S3UploadKeyName, contentType: "image/jpeg", expression: expression, completionHander: nil).continueWithBlock { (task) -> AnyObject! in
             if let error = task.error {
                 print("Error: \(error.localizedDescription)")
             }
             if let exception = task.exception {
                 print("Exception: \(exception.description)")
             }
             if let _ = task.result {
                 print("Upload Starting!")
             }
                 return nil;
             }
             
             picker.dismissViewControllerAnimated(true, completion: nil)
         }

     }
```

とりあえず備忘録がてらなので細かい解説はないですが、2016/6/25現在うまくいった方法を抜けなく載せたので、誰かのお役に立てば幸いです...
たぶんこれでうまくいくのですが何か問題あれば教えて下さい。