Swift3からCognitoの未認証ユーザでアクセスしてみた

AWS公式のCognitoのサンプルコードを信じて実装していたが、見事にハマったのでここに手順をメモろうと思います。

サンプルコードはgithubにあげてます。
https://github.com/miyasue/AWSCognitoSample

## やりたいこと
Swift3.0環境で未認証ユーザとして登録したい。

## 環境
- XCode 8.2.1

## Cognitoとは
モバイルやネイティブアプリに対し、ユーザのログイン機能を簡単に実装できたり、ユーザに紐付くデータを格納、取り出しを行うことができます。

## CognitoのTwitter認証
面倒なTwitter認証が軽々できそうなイメージですが、本当に面倒なOAuth認証部分は自前で用意しないといけないという罠があります。あくまでOAuth認証で得たTokenとTokenSecretを使って、CognitoIDと紐付けることができるよ！な感じです。

## User Pools と Federated Identities
![p1.png](https://qiita-image-store.s3.amazonaws.com/0/142489/eae26134-ea31-b739-d896-d5f8812040e5.png "p1.png")


Cognitoへアクセスすると Manage your User Pools と Manage Federated Identitiesというボタンが出てわりと戸惑う感じですが、それぞれこんな機能です。

### User Pools
独自の認証プロバイダを作る機能です。TwitterやFacebookで認証する場合やそもそも未認証ユーザとして使いたい場合触る必要はありません。

### Federated Identities（今回は使いません）
User Poolsで作った独自のプロバイダやTwitter認証を使い、ログイン機能を提供します。


# Cognito設定
## Federated Identities
identity poolを作ります。

### 作成
![p2.png](https://qiita-image-store.s3.amazonaws.com/0/142489/398ab158-3fae-d989-7c4a-638dabd73216.png "p2.png")


### 設定
![p3.png](https://qiita-image-store.s3.amazonaws.com/0/142489/4319c53e-6045-3217-85ee-316e2f8f9c48.png "p3.png")

- Identity pool name：Pool名です。今回はSampleにしました。
- Unauthenticated identities：未認証ユーザでもクレデンシャルの使用を許可するかの設定です。今回は未認証ユーザでクレデンシャルを使いたいのでEnable access to unauthenticated identitiesにチェックを入れます。
- Authentication providers：認証に使用するプロバイダの設定です。TwitterやFacebook認証などを行う場合、ここでアプリ設定などを行います。今回はプロバイダによる認証を行わないので何も設定しません。

設定が完了したらCreate Poolを押して作成します。

### ロールの設定
![p4.png](https://qiita-image-store.s3.amazonaws.com/0/142489/e8466384-1f86-fef4-b1d6-3765f19fcd52.png "p4.png")

上が認証ユーザ用のロール、下が未承認ユーザ用のロールです。
今回はユーザ登録が目標なのでデフォルトで作成しますが、何かしらのAWSサービスを利用する場合はここに設定すればいいようです。

## アプリを作成

### SDK導入
SDKはAWS公式にも落ちているのですが、なんか動かなくてハマった。。。
Cocoapodで導入していきます。今回は認証しかしないのでAWSCognitoだけ指定すればOKです。

``` Podfile
target 'AWSCognitoSample' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  # Pods for AWSCognitoSample
  pod 'AWSCognito'
end
```

### ブリッジヘッダー追加
AWSのSDKはまだObjective-Cコードなので（悲）Swiftで使うためにブリッジヘッダーを追加する必要があります。

![p5.png](https://qiita-image-store.s3.amazonaws.com/0/142489/89cbda32-b5d3-30e2-350c-6a16c219c613.png "p5.png")

新規ファイル追加から CognitoUserpool-Bridging-Header.h というファイルを作成しました。

```CognitoUserpool-Bridging-Header.h
#import <AWSCore/AWSCore.h>
#import <AWSCognito/AWSCognito.h>
```

## XCodeにヘッダーを設定
Build SettingsのObjective-C Bridging Headerに先ほどのCognitoUserpool-Bridging-Header.hのパスを追加します。

![p7.png](https://qiita-image-store.s3.amazonaws.com/0/142489/4dff4179-4446-5ef0-8b2e-1d76a5efd85e.png "p7.png")

## Identity pool ID
AWS ConsoleからIdentity pool IDを取得しておきます。

![p8.png](https://qiita-image-store.s3.amazonaws.com/0/142489/7e4f7f25-3014-44a5-0dad-43c898478bf1.png "p8.png")

## ログイン用コードを記載する

AppDelegateにログインコードを記載していきます。

```AppDelegate.swift
let credentialsProvider = AWSCognitoCredentialsProvider(regionType:.APNortheast1, identityPoolId:"ap-northeast-1:********-****-****-****-************")
let configuration = AWSServiceConfiguration(region:.APNortheast1, credentialsProvider:credentialsProvider)
AWSServiceManager.default().defaultServiceConfiguration = configuration
        
let defaultServiceConfiguration = AWSServiceConfiguration(region: AWSRegionType.APNortheast1, credentialsProvider: credentialsProvider)
        
AWSServiceManager.default().defaultServiceConfiguration = defaultServiceConfiguration
credentialsProvider.getIdentityId()
```
※リージョンとIdentity pool IDは自分の環境に合わせて書き換えてください。

# 動かしてみる

XCodeからアプリ起動してみると・・・

![p9.png](https://qiita-image-store.s3.amazonaws.com/0/142489/53c934c5-9fda-e1aa-8dad-f70b4be97112.png "p9.png")

無事ユーザとして追加されました。