728x90
반응형
안녕하세요 욱승임다
이번 포스팅에서는 RxSwift와 MVVM패턴을 활용한 애플 로그인을 포스팅 해보겠읍니다 ㅋ
Capability
추가 해주지 않음 에러나요
컴파일 에러가 나는건 아니고 런타임 에러가 나더라구염
구현 결과
저저 userIdentifier값은 애플 아이디마다 고유한 값이라 바뀌지 않음!
그래서 로그인 할때마다 동일 값을 리턴받기 때문에 사용자를 식별할수 있음!
나머지 성, 이름, 이메일이 보이는걸 확인할 수 있당
두번째 캡쳐본에서 Hide My Email을 했다면 성, 이름, 이메일이 nil로 리턴됨 !
만약 Hide My Email을 막고 싶다면
예제코드(RxSwift + MVVM)
Model
//
// User.swift
// SwiftPractice
//
// Created by ukseung.dev on 2023/05/22.
//
import Foundation
struct AppleUser {
let userIdentifier: String?
let familyName: String?
let givenName: String?
let email: String?
}
View
//
// AppleLoginViewController.swift
// SwiftPractice
//
// Created by ukseung.dev on 2023/05/22.
//
import Foundation
import UIKit
import AuthenticationServices
import RxSwift
import RxCocoa
final class AppleLoginViewController: UIViewController, UIViewControllerAttribute {
private let disposeBag = DisposeBag()
private var viewModel = AppleLoginViewModel()
private var appleUser = AppleUser(userIdentifier: nil, familyName: nil, givenName: nil, email: nil)
// Apple 로그인 버튼 생성
lazy var appleLoginButton = UIButton(type: .system).then {
$0.setTitle("Sign In with Apple", for: .normal)
$0.setTitleColor(.white, for: .normal)
$0.layer.borderWidth = 1
$0.layer.cornerRadius = 5
$0.backgroundColor = .black
}
// Apple 로그인 성공 후 UILabel.text
lazy var userInfoLabel = UILabel().then {
$0.numberOfLines = 0 // 여러 줄
$0.sizeToFit()
}
var navTitle: String?
override func viewDidLoad() {
super.viewDidLoad()
setNavigationBar()
setUI()
setAttributes()
bindRx()
}
func setNavigationBar() {
self.navigationItem.title = navTitle ?? ""
}
func setUI() {
self.view.backgroundColor = .white
self.view.addSubview(appleLoginButton)
self.view.addSubview(userInfoLabel)
}
func setAttributes() {
appleLoginButton.snp.makeConstraints {
$0.width.equalTo(200)
$0.height.equalTo(50)
$0.top.equalTo(view.safeAreaLayoutGuide).offset(30)
$0.centerX.equalToSuperview()
}
userInfoLabel.snp.makeConstraints {
$0.left.equalTo(20)
$0.right.equalTo(-20)
$0.bottom.equalTo(self.view.safeAreaLayoutGuide)
$0.top.equalTo(appleLoginButton.snp.bottom).offset(40)
}
}
func bindRx() {
// 애플 로그인 버튼 Action
appleLoginButton.rx.tap
.bind(to: viewModel.signInButtonTapped)
.disposed(by: disposeBag)
// 성공시 userInfoLabel에 정보들 setText
viewModel.signInCompleted
.subscribe(onNext: { value in
self.appleUser = value
self.userInfoLabel.text = """
userIdentifier: \(self.appleUser.userIdentifier)
familyName: \(self.appleUser.familyName)
givenName: \(self.appleUser.givenName)
email: \(self.appleUser.email)
"""
})
.disposed(by: disposeBag)
}
}
ViewModel
//
// AppleLoginViewModel.swift
// SwiftPractice
//
// Created by ukseung.dev on 2023/05/22.
//
import Foundation
import RxSwift
import RxCocoa
import AuthenticationServices
final class AppleLoginViewModel: NSObject {
let signInButtonTapped = PublishRelay<Void>()
let signInCompleted = PublishRelay<AppleUser>()
private let disposeBag = DisposeBag()
override init() {
super.init()
signInButtonTapped
.subscribe(onNext: { [weak self] in
self?.performAppleSignIn()
})
.disposed(by: disposeBag)
}
//애플 로그인
func performAppleSignIn() {
let provider = ASAuthorizationAppleIDProvider()
let request = provider.createRequest()
request.requestedScopes = [.fullName, .email]
let controller = ASAuthorizationController(authorizationRequests: [request])
controller.delegate = self
controller.performRequests()
}
}
extension AppleLoginViewModel: ASAuthorizationControllerDelegate {
// 애플 로그인 성공
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential {
let userIdentifier = appleIDCredential.user
let familyName = appleIDCredential.fullName?.familyName
let givenName = appleIDCredential.fullName?.givenName
let email = appleIDCredential.email
let state = appleIDCredential.state
let user = AppleUser(
userIdentifier: userIdentifier,
familyName: familyName,
givenName: givenName,
email: email
)
signInCompleted.accept(user)
}
}
// 애플 로그인 실패
func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
print("Apple Sign In Error: \(error.localizedDescription)")
}
}
결론
참고로 다른 소셜 로그인도 기획 혹은 구현중이라면 애플 로그인을 반드시 구현 해야함 !
왜냐면 애플 심사지침에 있걸랑..
Reference
728x90
반응형
'iOS > Swift' 카테고리의 다른 글
[Swift] 화면이동시 SafeArea Background Color이 변경 되는 이슈 (2) | 2023.06.20 |
---|---|
[Swift] Hotspot Configuration, 핫스팟 연결 (1) | 2023.05.24 |
[Swift] UITableView Cell 밀어서 삭제 (0) | 2023.05.21 |
[Swift] ScrollView 스크롤 네비게이션바 hide On/Off (1) | 2023.05.19 |
[Swift] UITabbar, 하단 탭바 구현 (0) | 2023.04.30 |