# 전체 추가
pod 'KakaoSDK'
# or
# 카카오 로그인 시 필요 모듈
pod 'KakaoSDKCommon' # 필수 요소를 담은 공통 모듈
pod 'KakaoSDKAuth' # 카카오 로그인
pod 'KakaoSDKUser' # 사용자 관리
# 필요한 모듈 추가
pod 'KakaoSDKTalk' # 친구, 메시지(카카오톡)
pod 'KakaoSDKStory' # 카카오스토리
pod 'KakaoSDKLink' # 메시지(카카오링크)
pod 'KakaoSDKTemplate' # 메시지 템플릿
pod 'KakaoSDKNavi' # 카카오내비
URL Schemes에 항목에 네이티브 앱 키(Native App Key)를 ‘kakao{NATIVE_APP_KEY}’ 형식으로 등록
import KakaoSDKAuth
func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
sleep(2)
// Override point for customization after application launch.
KakaoSDKCommon.KakaoSDK.initSDK(appKey: "NATIVE_APP_KEY")
return true
}
import KakaoSDKAuth
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
if let url = URLContexts.first?.url {
if (AuthApi.isKakaoTalkLoginUrl(url)) {
_ = AuthController.handleOpenUrl(url: url)
}
}
}
함수가 길어 분리가 필요하지만 사실 내용은 간단합니다
func kakaoSignin() -> Single<Result<AuthModel, APIError>> {
return Single.create { single in
if AuthApi.hasToken() { // 기존 access token 토큰 존재 여부 체크
UserApi.shared.accessTokenInfo { _, error in // access token 토큰 요청
if error != nil { // access token 토큰 만료 시
if UserApi.isKakaoTalkLoginAvailable() { // 앱 로그인: 카톡 어플 O
UserApi.shared.loginWithKakaoTalk { _, error in
if error != nil { // 로그인 실패
single(.success(.failure(APIError(statusCode: -1, description: error.debugDescription))))
} else { // 로그인 성공, userId 발급
UserApi.shared.me(completion: { user, error in
guard let user = user,
let id = user.id
else {
single(.success(.failure(APIError(statusCode: -1, description: error.debugDescription))))
return
}
let auth = AuthModel(type: .kakao,
identyfier: String(id),
email: user.kakaoAccount?.email,
name: user.kakaoAccount?.name)
single(.success(.success(auth)))
})
}
}
} else { // 웹 로그인: 카톡 어플 X
UserApi.shared.loginWithKakaoAccount { _, error in
if error != nil { // 로그인 실패
single(.success(.failure(APIError(statusCode: -1, description: error.debugDescription))))
} else { // 로그인 성공, userId 발급
UserApi.shared.me(completion: { user, error in
guard let user = user,
let id = user.id
else {
single(.success(.failure(APIError(statusCode: -1, description: error.debugDescription))))
return
}
let auth = AuthModel(type: .kakao,
identyfier: String(id),
email: user.kakaoAccount?.email,
name: user.kakaoAccount?.name)
single(.success(.success(auth)))
})
}
}
}
} else { // 토큰 유효 시, userId 발급
UserApi.shared.me(completion: { user, error in
guard let user = user,
let id = user.id
else {
single(.success(.failure(APIError(statusCode: -1, description: error.debugDescription))))
return
}
let auth = AuthModel(type: .kakao,
identyfier: String(id),
email: user.kakaoAccount?.email,
name: user.kakaoAccount?.name)
single(.success(.success(auth)))
})
}
}
} else { // 토큰 없을 시
if UserApi.isKakaoTalkLoginAvailable() { // 간편 로그인: 카톡 어플 있을 시
UserApi.shared.loginWithKakaoTalk { _, error in
if error != nil { // 로그인 실패
single(.success(.failure(APIError(statusCode: -1, description: error.debugDescription))))
} else { // 로그인 성공, userId 발급
UserApi.shared.me(completion: { user, error in
guard let user = user,
let id = user.id
else {
single(.success(.failure(APIError(statusCode: -1, description: error.debugDescription))))
return
}
let auth = AuthModel(type: .kakao,
identyfier: String(id),
email: user.kakaoAccount?.email,
name: user.kakaoAccount?.name)
single(.success(.success(auth)))
})
}
}
} else { // 카톡 어플 없을 시
UserApi.shared.loginWithKakaoAccount { _, error in
if error != nil {
single(.success(.failure(APIError(statusCode: -1, description: error.debugDescription))))
} else { // 로그인 성공, userId 발급
UserApi.shared.me(completion: { user, error in
guard let user = user,
let id = user.id
else {
single(.success(.failure(APIError(statusCode: -1, description: error.debugDescription))))
return
}
let auth = AuthModel(type: .kakao,
identyfier: String(id),
email: user.kakaoAccount?.email,
name: user.kakaoAccount?.name)
single(.success(.success(auth)))
})
}
}
}
}
return Disposables.create()
}
}