Programming/Swift

[Swift] Touch-id, Face-id를 적용해봐요.

ilovecoffee 2020. 9. 4. 15:06

안녕하세요.

 

오늘은 touch-id와 face-id로 본인 인증(?) 이라고 해야할까요? 암튼 그 기능을 테스트 해보려고합니다.

 

앱을 만들기 위해, 준비중인데요.

 

보통 앱 구매할 때나, 본인인증이 필요할 때, 이 기능을 많이 사용하는 걸로 알고있어요.

 

앱스토어에서도 쓰잖아요 그쵸?

 

암튼 그걸 시작 한 번 해볼게요

 

일단 프로젝트를 준비 시켜 주시구요.

 

왼쪽 파일 네비게이터에서 젤 위에 프로젝트 클릭 하신 후

 

그짝에서 쪼금 더 오른쪽으로 오시면 Project와 targets가 보이실거에요.

 

여기서 Target을 클릭!

 

Frameworks, Libraries, and Embedded Content

 

란이 보이시면 +를 눌러주세용

 

그리고 Local을 검색하여 주시고,

 

아래 화면에 보이시는 LocalAuthentication.framework 를 Add하여 주세요.

 

보이시죠? 로컬어쩌고저쩌고?

추가하게되시믄 

 

아래와 같이 뜹니다.

 

 

자 이제 90%는 구현이 다 되신거에요. 코드 몇개만 집어느으시면 완성되는겁니다.

 

ViewDidload

에서 실행되면 좋지만, 그래도 앱스토어처럼 뭘 눌렀을 때 동작을 해야하는 것이 더 좋잖아요? (뷰가 열리자마자 로그인 해달라그러면, 신용카드 받으면서 사인하는 그런 너낌)

 

그래서 전 버튼을 집어넣었습니다.

 

import LocalAuthentication

임뽀뜨 를 해주시고요

 

    let authContext = LAContext()
    var message : String?

를 전역변수로 해줬어요.

 

그 다음에.

 

저는 RxSwift를 연습 중이라 UIKit을 래핑해서 써주는 RxCoCoa로 썼습니다.

참 Label도 써서 바꿔줄려구요.

 

 override func viewDidLoad() {
        super.viewDidLoad()
        loginBtn
            .rx
            .tap
            .subscribe(onNext : {
                self.requestLogin()
            })
            .disposed(by: rx.disposeBag)
        self.successStatusLabel.text = "본인 인증해주세요."
    }

 

 

생각보다 코드 줄이 길지않습니다.

 

 private func requestLogin(){
        
        if authContext.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) {
            
            switch authContext.biometryType {
            case .faceID:
                message = "Face ID 인증해주세요."
            case .touchID :
                message = "Touch ID로 인증해주세요."
            case .none :
                message = "둘 다 안되니 로그인하십시오 X를 눌러 Joy를 표하십시오."
                
            }
            
            authContext.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: message!) { (isSUccess, error) in
                if isSUccess {
                    print("인증성공")
                    DispatchQueue.main.async {
                        self.successStatusLabel.textColor = .red
                        self.successStatusLabel.text = "인증 성공"
                    }
                    
                }else {
                    if let error = error {
                        print(error.localizedDescription)
                    }
                }
            }
        }else {
            print("X를 눌러 Joy를 표하십시오.")
            let errorDescripiton = error?.userInfo["NSLocalizedDescription"] ?? ""
            print(errorDescripiton)
            
            let alert = UIAlertController(title: "Authentication Required", message: message, preferredStyle: .alert)
            weak var usernameTextField : UITextField!
            alert.addTextField(configurationHandler: { textField in
                textField.placeholder = "아이디 좀.."
                usernameTextField = textField
            })
            weak var passwordTextField : UITextField!
            alert.addTextField(configurationHandler: { textField in
                textField.placeholder = "비번도 좀 적어주시겠어요?"
                textField.isSecureTextEntry = true
                passwordTextField = textField
            })
            alert.addAction(UIAlertAction(title: "취소", style: .cancel, handler: nil))
            alert.addAction(UIAlertAction(title: "확인", style: .destructive, handler: { action in
//                print(usernameTextField.text! + " & " + passwordTextField.text!)
                
            }))
            DispatchQueue.main.async {
                self.present(alert, animated: true, completion: nil)
            }
        }
    }

 

아마 소스가 짧기도 하고, String값을 보면서 진행하면 무리 없이 진행 가능할 것 같습니다.