# `useSignInWithApple()`

## Before you start

This hook is only available on iOS devices and requires a native build. It will not work with Expo Go.

The `useSignInWithApple()` hook provides native [Sign in with Apple⁠](https://developer.apple.com/sign-in-with-apple/) functionality for iOS devices. It handles the ID token exchange with Clerk's backend and automatically manages the transfer flow⁠ between sign-up and sign-in.

## [Installation](/content/docs/reference/expo/native-hooks/use-sign-in-with-apple#installation/index.html)

This hook requires the following peer dependencies:

```terminal
npx expo install expo-apple-authentication expo-crypto
```

## [Returns](/content/docs/reference/expo/native-hooks/use-sign-in-with-apple#returns/index.html)

The `useSignInWithApple()` hook returns the `startAppleAuthenticationFlow()` method, which you can use to initiate the native Apple authentication flow.

### [`startAppleAuthenticationFlow()`](/content/docs/reference/expo/native-hooks/use-sign-in-with-apple#start-apple-authentication-flow/index.html)

`startAppleAuthenticationFlow()` has the following function signature:

```javascript
function startAppleAuthenticationFlow(
  startAppleAuthenticationFlowParams?: StartAppleAuthenticationFlowParams,
): Promise<StartAppleAuthenticationFlowReturnType>
```

#### [Parameters](/content/docs/reference/expo/native-hooks/use-sign-in-with-apple#parameters/index.html)

`startAppleAuthenticationFlow()` accepts the following parameters (`StartAppleAuthenticationFlowParams`):

- **Name**: `unsafeMetadata?`
  - **Type**: [SignUpUnsafeMetadata](/content/docs/expo/reference/types/metadata#sign-up-unsafe-metadata/index.html)
  - **Description**: Metadata that can be read and set from the frontend and the backend. Once the authentication process is complete, the value of this field will be automatically copied to the created user's unsafe metadata (`User.unsafeMetadata`). One common use case is to collect custom information about the user during the authentication process and store it in this property. Read more about [unsafe metadata](/content/docs/guides/users/extending#unsafe-metadata/index.html).

#### [Returns](/content/docs/reference/expo/native-hooks/use-sign-in-with-apple#returns-2/index.html)

`startAppleAuthenticationFlow()` returns the following:

- **Name**: `createdSessionId`
  - **Type**: `string | null`
  - **Description**: The ID of the session that was created, if authentication is successful.
- **Name**: `setActive?`
  - **Type**: `(params: SetActiveParams) => Promise<void>`
  - **Description**: A method used to set the active session and/or Organization.
- **Name**: `signIn?`
  - **Type**: `SignIn | undefined`
  - **Description**: The [SignIn](/content/docs/expo/reference/objects/sign-in/index.html) object that was created, which holds the state of the current sign-in.
- **Name**: `signUp?`
  - **Type**: `SignUp | undefined`
  - **Description**: The [SignUp](/content/docs/expo/reference/objects/sign-up/index.html) object that was created, which holds the state of the current sign-up.

## [Examples](/content/docs/reference/expo/native-hooks/use-sign-in-with-apple#examples/index.html)

### [Reusable component](/content/docs/reference/expo/native-hooks/use-sign-in-with-apple#reusable-component/index.html)

The following example demonstrates how to use the [useSignInWithApple()](/content/docs/reference/expo/native-hooks/use-sign-in-with-apple/index.html) hook to manage the Apple authentication flow.

```javascript
import { useSignInWithApple } from '@clerk/expo/apple';
import { useRouter } from 'expo-router';
import { Alert, Platform, Pressable, StyleSheet, Text, View } from 'react-native';

export function AppleSignInButton({ onSignInComplete }) {
  const { startAppleAuthenticationFlow } = useSignInWithApple();
  const router = useRouter();

// Only show on iOS
  if (Platform.OS !== 'ios') return null;

const handleAppleSignIn = async () => {
    try {
      const { createdSessionId, setActive } = await startAppleAuthenticationFlow();

if (createdSessionId && setActive) {
        await setActive({ session: createdSessionId });
        onSignInComplete ? onSignInComplete() : router.replace('/');
      }
    } catch (err) {
      if (err.code === 'ERR_REQUEST_CANCELED') return;
      Alert.alert('Error', err.message || 'An error occurred during Apple sign-in');
    }
  };

return (
    <View style={styles.container}>
      <Pressable onPress={handleAppleSignIn}>
        <Text>Continue with Apple</Text>
      </Pressable>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { width: '100%', marginVertical: 8 },
});
```

### [With custom metadata](/content/docs/reference/expo/native-hooks/use-sign-in-with-apple#with-custom-metadata/index.html)

The following example demonstrates how to pass custom metadata that will be saved to the user's [unsafe metadata](/content/docs/guides/users/extending#unsafe-metadata/index.html) during sign-up.

```javascript
import { useRouter } from 'expo-router';
import { useSignInWithApple } from '@clerk/expo/apple';
import { Alert, Platform, TouchableOpacity, Text } from 'react-native';

export default function SignInPage() {
  const { startAppleAuthenticationFlow } = useSignInWithApple();
  const router = useRouter();
  
  if (Platform.OS !== 'ios') return null;

const onAppleSignInPress = async () => {
    try {
      const { createdSessionId, setActive } = await startAppleAuthenticationFlow({
        unsafeMetadata: {
          referralSource: 'ios-app',
          signupDate: new Date().toISOString(),
        },
      });

if (createdSessionId && setActive) {
        await setActive({ session: createdSessionId });
        router.replace('/');
      } 
    } catch (err) {
      if (err.code === 'ERR_REQUEST_CANCELED') return;
      Alert.alert('Error', err.message || 'An error occurred during Apple sign-in');
    }
  };

return <TouchableOpacity onPress={onAppleSignInPress}><Text>Sign in with Apple</Text></TouchableOpacity>;
}
```

## [Error handling](/content/docs/reference/expo/native-hooks/use-sign-in-with-apple#error-handling/index.html)

The `useSignInWithApple()` hook may throw errors in the following scenarios:

- **User cancellation**: The user cancels the authentication flow.
- **Platform error**: The hook is called on a non-iOS platform.
- **Missing package**: The `expo-apple-authentication` package is not installed.
- **Authentication failure**: Apple authentication fails or the returned ID token is invalid.

Always wrap calls to `startAppleAuthenticationFlow()` in a `try/catch` block, and handle the `ERR_REQUEST_CANCELED` error separately.
