Ramble-FE / hooks / useOAuth / appleLogin.ios.ts
appleLogin.ios.ts
Raw
import { AuthService } from "@/services/auth";
import * as AppleAuthentication from "expo-apple-authentication";
import { useCallback } from "react";
import { UseAppleLoginProps } from "./types";

export function useAppleLogin({
    onSuccess,
    onError,
    isLoading,
    setIsLoading,
}: UseAppleLoginProps) {
    const startAppleLogin = useCallback(async () => {
        if (isLoading) return;

        setIsLoading(true);

        try {
            const isAvailable = await AppleAuthentication.isAvailableAsync();

            if (!isAvailable) {
                onError?.("Apple Sign In은 이 기기에서 지원되지 않습니다");
                return;
            }

            const credential = await AppleAuthentication.signInAsync({
                requestedScopes: [
                    AppleAuthentication.AppleAuthenticationScope.FULL_NAME,
                    AppleAuthentication.AppleAuthenticationScope.EMAIL,
                ],
            });

            if (!credential.authorizationCode || !credential.identityToken) {
                onError?.("Apple 인증 정보가 유효하지 않습니다");
                return;
            }

            const result = await AuthService.loginWithNativeApple({
                authorizationCode: credential.authorizationCode!,
                identityToken: credential.identityToken!,
                email: credential.email,
                name: [credential.fullName?.givenName, credential.fullName?.familyName]
                    .filter(Boolean)
                    .join(' ') || null,
            });

            if (result.success) onSuccess?.(result.success);
            else if (result.error) onError?.(result.error);
        } catch (error: any) {
            if (error.code !== "ERR_CANCELED") {
                onError?.(error.message ?? "Apple 로그인에 실패했습니다");
            }
        } finally {
            setIsLoading(false);
        }
    }, [isLoading, onSuccess, onError, setIsLoading]);

    return { startAppleLogin };
}