supabase를 사용하는 react native cli프로젝트에서 Sign In with Apple을 구현하는 과정을 기록했다.
Sign In with Apple 체크박스 활성화 하거나 활성화하면서 새로 만들기 , 키는 다운로드하기XCode에서 프로젝트 열기 <프로젝트이름>.xcodeproj를 열어서 열 수 있다.Signing & Capabilities 탭에서 Sign In with Apple추가ios/AppleSignInModule.m#import <React/RCTBridgeModule.h>
@interface RCT_EXTERN_MODULE(AppleSignInModule, NSObject)
RCT_EXTERN_METHOD(signInWithApple:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
@end
ios/AppleSignInModule.swift
import Foundation
import AuthenticationServices
@objc(AppleSignInModule)
class AppleSignInModule: NSObject, ASAuthorizationControllerDelegate {
private var resolve: RCTPromiseResolveBlock?
private var reject: RCTPromiseRejectBlock?
@objc(signInWithApple:rejecter:)
func signInWithApple(resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
self.resolve = resolve
self.reject = reject
let request = ASAuthorizationAppleIDProvider().createRequest()
request.requestedScopes = [.email, .fullName]
let controller = ASAuthorizationController(authorizationRequests: [request])
controller.delegate = self
controller.performRequests()
}
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential,
let identityToken = appleIDCredential.identityToken,
let tokenString = String(data: identityToken, encoding: .utf8) {
resolve?(["idToken": tokenString])
} else {
reject?("NO_TOKEN", "Unable to fetch identity token", nil)
}
}
func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
reject?("APPLE_SIGNIN_ERROR", error.localizedDescription, error)
}
}
[프로젝트 명]-Bridging-Header.h를 프로젝트 폴더안에 생성한다. (위 파일들 만든 곳에)//
// [프로젝트 명]-Bridging-Header.h
// [프로젝트 명]
//
// Created by 이름 on MM/DD/YY.
//
#ifndef [프로젝트 명]_Bridging_Header_h
#define [프로젝트 명]_Bridging_Header_h
#endif /* [프로젝트 명]_Bridging_Header_h */
이런게 생성될텐데 여기에 아래 코드를 추가한다.
#import <React/RCTBridgeModule.h>
#import <React/RCTViewManager.h>
#import <React/RCTConvert.h>
그리고 파란색 루트를 선택, 타겟을 앱으로 선택하고
Build Settings에서 All 로 선택 후 오른쪽 검색에서 bridging을 검색
Objective-C Bridging Header에 아까만든 헤더파일 경로([프로젝트명]/[프로젝트명]-Bridging-Header.h) 입력
파일 경로가
[프로젝트명]/ios/[프로젝트명]/[프로젝트명]-Bridging-Header.h
가 되어야함
그리고 클린 빌드를 한다.
handleAppleLogin: async () => {
set({ isLoading: true });
try {
// 네이티브 모듈에서 idToken 받아오기
const { signInWithAppleNative } = await import('../libs/native/AppleSignIn');
const idToken = await signInWithAppleNative();
// console.log('Apple idToken:',idToken)
if (!idToken) {
Alert.alert('Apple 로그인 오류', 'idToken을 받아오지 못했습니다.');
set({ isLoggedIn: false });
return;
}
const { data, error } = await supabase.auth.signInWithIdToken({
provider: 'apple',
token: idToken,
});
// console.log('data: ',data)
if (error) {
Alert.alert('Apple 로그인 오류', error.message || '로그인 중 오류가 발생했습니다.');
set({ isLoggedIn: false });
} else if (data.session) {
set({
isLoggedIn: true,
userId: data.user.id,
});
if (__DEV__) {
console.log('[AuthStore] isLoggedIn set to true in handleAppleLogin()');
}
}
} catch (error: any) {
Alert.alert('Apple 로그인 오류', error.message || '알 수 없는 오류가 발생했습니다.');
set({ isLoggedIn: false });
} finally {
set({ isLoading: false });
}
},
ios 파일은 직접 작성하신건가용?
현재 라이브러리를 쓸지 코드 그래도 써볼지 싶어서요