こんにちは。ユーザーファースト室の中村(@_nkmrh)です。 先日リリースしたクックパッドアプリ v7.6.0 には iCloud の Keychain に保存されているクックパッドアカウントを、アプリから利用する機能を追加しています。具体的には次のような機能です。
1. Mac の Safari から cookpad にログインします
2. アカウント情報を iCloud Keychain に保存します
3. iPhoneのcookpadアプリを立ち上げ、ログインボタンをタップすると、Safari でログインしたアカウントが選択できるようになっています
このように、Mac 又は iPhone の Safari からクックパッドを利用していた人が、アプリにログインする際、面倒な入力をせずにログイン出来るようになりました。ぜひ試してみて下さい。
※この機能を使用するには、事前に下記の設定が必要です。また、iOS 8がインストールされたiPhone 5以降、iPad 第4世代、iPad Air、iPad mini、iPad mini Retinaディスプレイモデル、iPod touch 第5世代でご利用いただけます。
- Mac > System Preferences > iCloud > Keychain > ON
- iPhone >設定 > iCloud >キーチェーン > ON
- iPhone >設定 > Safari >パスワードと自動入力 >ユーザー名とパスワード > ON
実装
以降、この機能の実装方法を紹介します。
- Xcodeプロジェクトの Associated Domains に webcredentials の設定を追加します
- apple-app-site-association ファイルをWebサイトのルートに配置します
- アプリから SecRequestSharedWebCredential 関数を呼び、アカウント・パスワードを取得します
1. Associated Domains
Associated Domains にWebサイトのドメインを追加します。 - Xcode > Targets > Capabilities > Associated Domains
`webcredentials:example.com`
2. apple-app-site-association
apple-app-site-association ファイルを作成します。このファイルは、Webサイトのルートに配置しておくもので、連携するアプリのApp Idを記述したファイルをAppleが認可する証明書で署名したものです。
webcredentials.jsonファイルを作成し、以下の内容を記述します。
{"webcredentials":{"apps":["XXXXXXXXXX.com.example.myapp"]}}
※(XXXXXXXXXXの部分はApp Id Prefixを指定します)
.p12ファイルを Keychain Access.app から書き出します。SSL証明書を右クリックで選択し書き出しを選択します。
Certificates > SSL証明書 > Certificates.p12
※ Handoffを実装する際は iPhone Developer の証明書が使えたのですが、今回私が試した範囲では iPhone Developer の証明書ではうまくいきませんでした。うまくいかない場合は、Webサイトで使用しているSSL証明書を使用して下さい。
webcredentials.json ファイルを Certificates.p12 ファイルで署名します。下記のシェルスクリプトを実行して下さい。
#!/bin/sh openssl pkcs12 -in Certificates.p12 -clcerts-nokeys-out output_crt.pem openssl pkcs12 -in Certificates.p12 -nocerts-nodes-out output_key.pem openssl pkcs12 -in Certificates.p12 -cacerts-nokeys-out sample.ca-bundle cat webcredentials.json | openssl smime -sign-inkey output_key.pem -signer output_crt.pem -certfile sample.ca-bundle -noattr-nodetach-outform DER > apple-app-site-association
- 作成した apple-app-site-association をWebサイトのルートに配置します。
3. アプリの実装
iCloud Keychain のアカウント情報を取得するには SecRequestSharedWebCredential
関数を使用します。
void SecRequestSharedWebCredential ( CFStringRef fqdn, CFStringRef account, void (^completionHandler)( CFArrayRef credentials, CFErrorRef error) );
- 第一引数の `fqdn` は取得したいWebサイトのドメイン名を指定します。`NULL` を指定すると、Associated Domains の設定に追加したドメインが使われます。
- 第二引数の `account` はアカウント名を指定します。 `NULL` を指定すると利用可能なすべてのアカウントが返ります。
- 第3引数の `completionHandler` の第一引数 `credentials` に見つかったアカウント・パスワードが格納されます。
- 例
SecRequestSharedWebCredential(NULL, NULL, ^(CFArrayRef credentials, CFErrorRef error) { if (!error && CFArrayGetCount(credentials) > 0) { CFDictionaryRef credential = CFArrayGetValueAtIndex(credentials, 0); // credential から アカウントとパスワードが取得できます NSString *email = (__bridge NSString *)(CFDictionaryGetValue(credential, kSecAttrAccount)); NSString *pass = (__bridge NSString *)(CFDictionaryGetValue(credential, kSecSharedPassword)); dispatch_async(dispatch_get_main_queue(), ^{ // 取得した メールアドレスとパスワードでログインする }); } else { NSError *_error = (__bridge NSError*)error; // _error ? @"アカウントは見つかりませんでした。" : @"キャンセルボタンがタップされました。"; } });
また、アカウント情報の取得の他、追加・削除(SecAddSharedWebCredential
関数)・作成(
SecCreateSharedWebCredentialPassword
関数)が用意されています。
おわりに
いかがでしょうか。以上の手順で iOS アプリの面倒なアカウント入力を無くすことができます。ぜひ試してみてください。また、Keychain周りのライブラリ UICKeyChainStoreが Shared Web Credentials に対応しているのでこちらを利用するのも良いと思います。
参考URL