iOS Study

Apple login(Sign In Apple)

85chong 2021. 5. 12. 18:26
728x90
반응형
SMALL

* 2021.04 월 부터 app에 자체 로그인 기능만 있다면, 선택적으로 Apple Login 버튼을 적용 시킬 수 있고,

app에 카카오톡 같은 sns 로그인이 붙었을때에는 무조건 Apple Login 버튼을 적용 시켜야만 심사를 받을 수 있게 됨

 

* Apple Login 기능관련 함수 및 클래스 등은 ios 13 버전 부터 사용 가능 하여, 분기 처리가 있어야만 코드 적용 가능함

* 아직까지는 다른 사례로 보았을때, ios 13 미만의 처리는 따로 하지 않아도 , 심사가 가능함

 

* 전체과정 : 

(bundleIdentifier 과정이 적용 되었다고 가정함)

  1. AppleLogin 버튼 제작
  2. 이벤트 연결
  3. 콜백함수로 결과 값 전달받기

 

1. AppleLogin 버튼 제작

//프레임워크 추가
import AuthenticationServices
...


class TestAppleLogin: UIVIew{

  //버튼 전역변수 준비  
  var appleSignInButton: UIStackView

  ...

  override init(frame: CGRect) {
      super.init(frame: frame)
      setupUI()
  }

  ...

  func setupUI(){
    //버튼에 AppleLogin UI 입히기
    if #available(iOS 13.0, *) {
        let authorizationButton = ASAuthorizationAppleIDButton(type: .signIn, style: .whiteOutline)
        authorizationButton.addTarget(self, action: #selector(appleSignInButtonPress), for: .touchUpInside)

        frameRect = CGRect(x: 32, y: 340, width: 321, height: 50)
        appleSignInButton = UIStackView(frame: frameRect)

        self.appleSignInButton.addArrangedSubview(authorizationButton)
        self.addSubview(appleSignInButton)
    } else {
         //ios 13 미만일때
    }
  }

  ...

}

* 설명 :

   (* 위의 코드는 기본적으로 storyboar에 ui 를 그리는 방식이 아니고, 모든 ui는 코드로 그려서 적용하는 방식을 바탕으로 하고있음)

 

- appleSignInButton : AppleLogin 버튼으로 만들어 넣을 uiview

- let authorizationButton : AppleLogin 버튼 이벤트 및 버튼 스타일, 기능 셋팅

    - .signIn : Apple ID 로 로그인

    - .signUp : Apple ID 로 등록하기

    - .continue : Apple ID 로 계속하기

- frameRect : 버튼 붙일 레이아웃 틀 생성

- self.appleSignInButton.addArrangedSubview(authorizationButton) : AppleLogin 버튼 이벤트 및 버튼 스타일, 기능 셋팅을, 버튼에 연결시키기

- self.addSubview(appleSignInButton) : 바탕에  준비된 appleSignInButton 붙이기

 

 

 

2. 이벤트 연결

//프레임 워크 설정
import AuthenticationServices

...
//Controller
class TestAppleLoginController: UIViewController,ASAuthorizationControllerPresentationContextProviding{

    //필수 함수
    @available(iOS 13.0, *)
    func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
        return self.view.window!
    }

...

}

...

//이벤트
extension TestAppleLoginController: Delegate_View_Login {

    //AppleLogin 클릭
    func appleSignInTapped() {
        if #available(iOS 13.0, *) {
             let provider = ASAuthorizationAppleIDProvider()
             let request = provider.createRequest()
             request.requestedScopes = [.fullName, .email]
             let authorizationController = ASAuthorizationController(authorizationRequests: [request])
             authorizationController.delegate = self
             authorizationController.presentationContextProvider = self
             authorizationController.performRequests()
        } else {
            //ios 13 미만
        }
    }
...

}




* 설명 :

- presentationAnchor : AppleLogin 버튼 클릭시, 띄울 팝업 윈도우

- applSignInTapped() :  실제 AppleLogin 액션 함수

 

 

 

3. 콜백 함수로 결과값 전달 받기

//(위 코드와 동일한 파일 안에서 작성됨)
...

//콜백받을 클래스
extension TestAppleLoginController: ASAuthorizationControllerDelegate {

...

      @available(iOS 13.0, *)
      func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
        if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential {
            // Create an account in your system.
            let userIdentifier = appleIDCredential.user
            let userFirstName = appleIDCredential.fullName?.givenName
            let userLastName = appleIDCredential.fullName?.familyName
            let userEmail = appleIDCredential.email

            print("userIdentifier : \(userIdentifier)")
            print("userFirstName : \(userFirstName)")
            print("userIdentifier : \(userIdentifier)")
            print("userLastName : \(userLastName)")
            print("userEmail : \(userEmail)")

            //Navigate to other view controller
        } else if let passwordCredential = authorization.credential as? ASPasswordCredential {
            // Sign in using an existing iCloud Keychain credential.
            let username = passwordCredential.user
            let password = passwordCredential.password
            //Navigate to other view controller
            print("## username : \(username)")
            print("## password : \(password)")
        }
    }
    
    @available(iOS 13.0, *)
    func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
       print("## handle Error.")
    }
    
...   
    
}

* 설명 :

- authorizationControllerI() : AppleLogin 액션 이후 호출되는 콜백 함수( 이곳에서 사용자 정보를 받아옴, userIidentifier , email 등

 

 

(! 주의 ! : AppleLogin 에서는 사용자의 email의 노출을. 사용자의 선택에 따라 받지 못할 수도 있어서(identifie는 무조건 받을 수 있음) 사용자가 email 숨김을 선택 했거나, 임의로 아무 이메일을 적게 되면 정상 적인 email 받지 못 할 수도 있다. 이때 , apple 에서는 사용자의 email을 직접 가져갈 순 없지만, 원한다면 간접적으로 apple email을 만들어 내려주고 있기 때문에, email 을 사용 해야 한다면. 이 간접email을 받아서 처리해야 한다.(email relay)

 

 

 

- 끝 -