最高のUXを！iOSパスワードピッカーでiCloud KeyChainに保存している認証情報を自動でマッチングする

### 普段アプリを使う時、このような画面を見たことがあります。
<img width="400" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884143/e0acf699-db16-7947-85db-063e6a3b51b7.png">

##### どう実現しているのかをいろいろ調べて自分でも実現したかったですが、いくつ注意しないといけないところを見つかりました。
### 最初に怒られたのはこのエラーですね

```
Error: The operation couldn’t be completed. No credentials available for login.
ASAuthorizationController credential request failed with error: 
Error Domain=com.apple.AuthenticationServices.AuthorizationError Code=1001 "(null)"
```
### いろいろ調べてアプリだけの実装はできないことが分かりました。
#### まずは自分のサイトに以下のファイルをデプロイする。
```
.well-known/apple-app-site-association
```
apple-app-site-associationの中身
```
{
  "webcredentials": {
    "apps": ["2282XXXXXX.com.company.product" ]
  }
}
```
#### 次はアプリのCapabilitiesのAssociated domainsに以下を追加する。
```
webcredentials:www.company.com
```
##### 以上を設定してもすぐに使えなかった。その理由を探してみたら、Appleのドキュメントに記載してあります。
https://developer.apple.com/documentation/xcode/supporting-associated-domains
```
Important

Apple’s content delivery network requests the apple-app-site-association file for your domain within 24 hours. Devices check for updates approximately once per week after app installation.
```
```
import UIKit
import AuthenticationServices

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    // Don't forget to add a button in Storyboard
    @IBAction func passwordButtonPressed(_ sender: UIButton) {
        showPasswordPicker()
    }
    
    func showPasswordPicker() {
        let passwordProvider = ASAuthorizationPasswordProvider()
        let request = passwordProvider.createRequest()
        
        let authorizationController = ASAuthorizationController(authorizationRequests: [request])
        authorizationController.delegate = self
        authorizationController.presentationContextProvider = self
        authorizationController.performRequests()
    }
}

extension ViewController: ASAuthorizationControllerDelegate {
    func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
        if let passwordCredential = authorization.credential as? ASPasswordCredential {
            let username = passwordCredential.user
            let password = passwordCredential.password
            
            print("Username: \(username)")
            print("Password: \(password)")
        }
    }
    
    func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
        print("Error: \(error.localizedDescription)")
    }
}

extension ViewController: ASAuthorizationControllerPresentationContextProviding {
    func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
        return self.view.window!
    }
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884143/4c791bae-8c00-b7de-b80b-8b0a41be29e3.png)


### おまけに
1. 自分のサイトと言っても持っていないなら[Github Pages](https://docs.github.com/ja/pages/getting-started-with-github-pages/creating-a-github-pages-site) を利用すれば最速でサイトを作れる
1. アプリのバンドルIDなどを確認するには[ProvisionQL](https://github.com/ealeksandrov/ProvisionQL)がおすすめです


### 最後に
`.well-known/apple-app-site-association`が反映するまでのタイムラグを考慮して次の手順で実施していくといいでしょう。
1. 自分のサイトに`.well-known/apple-app-site-association`をデプロイする
1. 設定->パスワードに自分のサイトのパスワードを登録しておく
1. パスワードPicker対応のアプリをインストール