0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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

Posted at

普段アプリを使う時、このような画面を見たことがあります。

mojikyo45_640-2.gif
どう実現しているのかをいろいろ調べて自分でも実現したかったですが、いくつ注意しないといけないところを見つかりました。

最初に怒られたのはこのエラーですね

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のドキュメントに記載してあります。

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

おまけに

  1. 自分のサイトと言っても持っていないならGithub Pages を利用すれば最速でサイトを作れる
  2. アプリのバンドルIDなどを確認するにはProvisionQLがおすすめです

最後に

.well-known/apple-app-site-associationが反映するまでのタイムラグを考慮して次の手順で実施していくといいでしょう。

  1. 自分のサイトに.well-known/apple-app-site-associationをデプロイする
  2. 設定->パスワードに自分のサイトのパスワードを登録しておく
  3. パスワードPicker対応のアプリをインストール
0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?