[iOS] 애플 로그인 사용해보기(Sign in with Apple)

728x90
반응형

Sign in with Apple은 iOS 13이상 부터 사용가능한 새로운 인증 방법입니다.

단계별로 Sign in with Apple 사용법에 대해 알아 보도록 하겠습니다.

 

AppleIDButton 설정

먼저 AuthenticationServices를 import 해야 됩니다.

ASAuthorizationAppleIDButton를 이용해서 type 및 style을 지정해줍니다.

import UIKit
import AuthenticationServices

class ViewController: UIViewController {

    @IBOutlet weak var loginStackView: UIStackView!

    override func viewDidLoad() {
        super.viewDidLoad()

        setupProviderLoginView()
    }

    func setupProviderLoginView() {
        let button = ASAuthorizationAppleIDButton(type: .signIn, style: .black)
        button.addTarget(self, action: #selector(handleAuthorizationAppleIDButtonPress), for: .touchUpInside)
        self.loginStackView.addArrangedSubview(button)
    }

    @objc
    func handleAuthorizationAppleIDButtonPress() {
        print(123)
    }

}

 

💡
view위에 addSubView를 하면 전체 크기에 맞게 쉽게 적용이 되지 않는다.
StackView를 이용하면 원하는 크기에 맞게 쉽게 적용이 됩니다.

 

왼쪽: UIView, 오른쪽: UIStackView

 

Type

@available(iOS 13.0, *)
public enum ButtonType : Int {

    
    case signIn

    case `continue`

    
    @available(iOS 13.2, *)
    case signUp

    
    public static var `default`: ASAuthorizationAppleIDButton.ButtonType { get }
}

 

Style

@available(iOS 13.0, *)
public enum Style : Int {

    
    case white

    case whiteOutline

    case black
}

 

Request

@objc
func handleAuthorizationAppleIDButtonPress() {
    let request = ASAuthorizationAppleIDProvider().createRequest()
    request.requestedScopes = [.fullName, .email]
    
    let controller = ASAuthorizationController(authorizationRequests: [request])
    controller.delegate = self
    controller.presentationContextProvider = self
    controller.performRequests()
}

request scope는 fullNameemail 두 가지 종류 뿐.

delegate에 에러가 표시될텐데 delegate를 설정해줘야된다.

  1. ASAuthorizationControllerDelegate
    • didCompleteWithAuthorization은 인증 handle이 성공 했을때 호출되며, fullName(성, 이름), Email, UserIdentifier을 얻을 수 있습니다.
    • didCompletedWithError는 인증 handle이 실패했을때 호출됩니다.
  2. ASAuthorizationControllerPresentationContextProviding
    • presentationAnchor는 presentation context UI를 어디에 띄울지 적합한 뷰 앵커를 반환하는데, 보통 view의 window를 반환합니다.
extension ViewController: ASAuthorizationControllerDelegate {

	// 성공시 인증 정보를 반환 받는다.
    func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
        
        switch authorization.credential {
        case let appleIDCredential as ASAuthorizationAppleIDCredential:
            let userIdentifier = appleIDCredential.user
            let fullName = appleIDCredential.fullName
            let email = appleIDCredential.email
            
            print("#1", userIdentifier)
            print("#2", fullName)
            print("#3", email)
            
        case let passwordCredential as ASPasswordCredential:
            let userName = passwordCredential.user
            let password = passwordCredential.password
            
            print("#4", userName)
            print("#5", password)
            
        default:
            break
        }
    }
    
    // 인증 에러
    func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
        
        print("#6", error)
    }
    
}

extension ViewController: ASAuthorizationControllerPresentationContextProviding {
    
  // presentation context UI를 어디에 띄울지 가장 적합한 뷰 앵커를 반환한다.
  func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
      return self.view.window!
  }
}

 

여기까지는 기능은 모두 구현을 했지만 실행해보면 아무 동작도 하지 않습니다.

 

capability 추가

capability에서 sign in with apple을 추가해주는 작업이 남아있습니다.

capability를 추가해주면 AppleLogin.entitlements파일이 하나 생깁니다.

 

이제 실행해보면 아래와 같이 성공적으로 context 화면이 보입니다.

밑이 name과 email이 보이는건 fullName과 email을 요청했기 때문입니다.

request.requestedScopes = [.fullName, .email]

continue with password선택 후 비밀번호를 입력하면, full name, email, user identifier가 잘 받아지는걸 볼 수 있습니다.

💡사용자가 다시 로그인하면 사용자의 ID만 반환된다.

 

 

사용자의 Credentials State 확인

마지막으로 인증 상태를 확인하는 방법을 통해 앱의 경로를 설정 할 수 있습니다.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
    let appleIDProvider = ASAuthorizationAppleIDProvider()
    appleIDProvider.getCredentialState(
    	forUserID: "TESTUSERID_00.a2i2ii222"
    ) { (credentialState, error) in
		
	switch credentialState {
	case .authorized:
		// 로그인이 성공했으니 메인화면으로 이동
		break
	case .revoked, .notFound:
		// Apple ID 인증이 취소되었거나 찾을 수 없음
		// sign-in 화면으로 이동
		break
	default:
		break
	}
    }
        
	return true
}

 

 

 

반응형