티스토리 뷰
애플에서는 앱에서 소셜 로그인을 지원하는 경우 무조건 애플 로그인도 같이 지원을 해야한다고 한다.
만약 애플 로그인 지원하지 않으면 앱 심사에서 떨어질 수 있다는 점,,
1️⃣ Apple Developer에서 App ID 설정
애플 로그인을 지원하기 위해서는 애플 개발자 계정이 필수로 필요하다 ㅎㅎ
로그인 - Apple
idmsa.apple.com
애플 개발자 계정으로 로그인한 후 Certificates, Identifiers & Profiles에서 Identifiers를 생성해준다.
Description과 Bundle ID 적어주고, Capabilities에서 Sign In with Apple을 추가해준다.
여기까지하면 identifier 등록은 끝났다!!
2️⃣ 프로젝트에 Capabilities 추가
[Target -> Signing & Capabliities]에서 +Capability를 클릭해서 Sign In with Apple을 추가해준다.
그럼 아래와 같이 Sign In with Apple이 추가된 걸 확인할 수 있다.
3️⃣ 애플 로그인 로직 구현
🟡 OAuthUserData 구조체 생성
OAuthUser의 정보를 관리하기 위해 구조체를 만들어준다.
struct OAuthUserData {
var oauthId: String = ""
var idToken: String = ""
}
🟡 AppleOAuthViewModel
- 애플 로그인 실행
func signIn() {
let appleIDProvider = ASAuthorizationAppleIDProvider()//Apple ID 제공자를 생성
let request = appleIDProvider.createRequest()//인증 요청을 생성
request.requestedScopes = [.fullName, .email]//사용자로부터 전체 이름과 이메일을 요청
//인증 요청을 처리할 컨트롤러를 생성
let authorizationController = ASAuthorizationController(authorizationRequests: [request])
authorizationController.delegate = self//이 뷰 모델을 인증 컨트롤러의 delegate로 설정
authorizationController.presentationContextProvider = self//이 뷰 모델을 인증 컨트롤러의 프레젠테이션 컨텍스트 제공자로 설정
authorizationController.performRequests()//인증 요청을 수행
}
- 유저 정보 확인
extension AppleOAtuthViewModel: ASAuthorizationControllerPresentationContextProviding, ASAuthorizationControllerDelegate {
/// Apple ID 연동 성공 시
func authorizationController(controller _: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
switch authorization.credential {//인증 정보에 따라 다르게 처리
case let appleIDCredential as ASAuthorizationAppleIDCredential://Apple ID 자격 증명을 처리
let userIdentifier = appleIDCredential.user//사용자 식별자
let fullName = appleIDCredential.fullName//전체 이름
let idToken = appleIDCredential.identityToken!//idToken
oauthUserData.oauthId = userIdentifier
oauthUserData.idToken = String(data: idToken, encoding: .utf8) ?? ""
}
default:
break
}
}
}
- presentationAnchor() 메서드 구현
presentationAnchor(for: ) 메서드는 ASAuthorizationControllerPresentationContextProviding 프로토콜의 필수 메서드로 apple 로그인 UI를 어느 뷰에 표시할지 지정할 수 있다.
apple 로그인 UI는 모달 형식으로 표시되어서 presentationAnchor를 사용해 어디에 표시할지 정할 수 있고, UIWindow 객체는 apple로그인 UI가 표시될 윈도우이다.
func presentationAnchor(for _: ASAuthorizationController) -> ASPresentationAnchor {
guard let window = UIApplication.shared.windows.first else {//현재 애플리케이션에서 활성화된 첫 번째 윈도우
fatalError("No window found")
}
return window
}
- 최종코드
import AuthenticationServices
import SwiftUI
// MARK: - AppleOAtuthViewModel
class AppleOAtuthViewModel: NSObject, ObservableObject {
@Published var givenName: String = ""
@Published var errorMessage: String = ""
@Published var oauthUserData = OOAuthUserData()
func signIn() {
let appleIDProvider = ASAuthorizationAppleIDProvider()
let request = appleIDProvider.createRequest()
request.requestedScopes = [.fullName, .email]
let authorizationController = ASAuthorizationController(authorizationRequests: [request])
authorizationController.delegate = self
authorizationController.presentationContextProvider = self
authorizationController.performRequests()
}
func signOut() {
// 로그아웃 로직 (필요에 따라 구현)
}
}
// MARK: ASAuthorizationControllerPresentationContextProviding, ASAuthorizationControllerDelegate
extension AppleOAtuthViewModel: ASAuthorizationControllerPresentationContextProviding, ASAuthorizationControllerDelegate {
/// Apple ID 연동 성공 시
func authorizationController(controller _: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
switch authorization.credential {
case let appleIDCredential as ASAuthorizationAppleIDCredential:
let userIdentifier = appleIDCredential.user
let fullName = appleIDCredential.fullName
let idToken = appleIDCredential.identityToken!
oauthUserData.oauthId = userIdentifier
oauthUserData.idToken = String(data: idToken, encoding: .utf8) ?? ""
if let givenName = fullName?.givenName, let familyName = fullName?.familyName {
self.givenName = "\(givenName) \(familyName)"
}
default:
break
}
}
func presentationAnchor(for _: ASAuthorizationController) -> ASPresentationAnchor {
guard let window = UIApplication.shared.windows.first else {
fatalError("No window found")
}
return window
}
func authorizationController(controller _: ASAuthorizationController, didCompleteWithError error: Error) {
errorMessage = "Authorization failed: \(error.localizedDescription)"
}
}
🟡 간단한 버튼 View
import SwiftUI
struct ContentView: View {
@StateObject private var appleViewModel = AppleOAtuthViewModel()
var body: some View {
VStack {
Button(action: {//버튼 클릭시 애플 로그인 로직 실행
appleViewModel.signIn()
}) {
Text("Sign In with Apple")
.frame(width: 280, height: 45)
.cornerRadius(8)
}
.padding()
if !appleViewModel.givenName.isEmpty {
Text("Welcome, \(appleViewModel.givenName)")
.padding()
} else {
Text("Not Logged In")
.padding()
}
if !appleViewModel.errorMessage.isEmpty {
Text("Error: \(appleViewModel.errorMessage)")
.foregroundColor(.red)
.padding()
}
}
.padding()
}
}
✋ 최종 결과물 !!
아래와 같이 버튼을 누르면 애플 로그인 UI가 모달으로 나오고 로그인 완료 후 유저 정보를 가져오는 걸 확인할 수 있다.
주의할 점!
Apple 로그인은 사용자가 처음 로그인할 때만 fullName과 email 정보를 요청할 수 있다.
이후 로그인 시에는 이러한 정보가 자동으로 제공되지 않기 때문에 사용자 정보가 필요한 경우 첫 로그인 시 정보를 백엔드 서버에 저장해야 한다고 한다,,,
'스위프트 > SwiftUI' 카테고리의 다른 글
[SwiftUI] - Navigation bar 제외한 background Color 설정 (0) | 2024.02.11 |
---|---|
[SwiftUI] - Todo List 구현 (0) | 2024.02.07 |
[SwiftUI] - ImagePicker 사용 (1) | 2024.02.01 |
[Swift] SwiftUI StopWatch 구현 (0) | 2024.01.22 |
[SwiftUI] - 구글 로그인 구현 (0) | 2023.12.09 |