Skip to main content
Docs

iOS Quickstart (beta)

You will learn the following:

  • Create a new Xcode project
  • Install the Clerk iOS SDK
  • Configure Clerk with your Publishable Key
  • Use Clerk to enable users to sign in and out of your application

Note

Ensure that the Native API is enabled to integrate Clerk in your native application. In the Clerk Dashboard, navigate to the Native Applications page.

Create an iOS Project

To get started using Clerk with iOS, create a new project in Xcode. Select SwiftUI as your interface and Swift as your language. See the Xcode documentation for more information.

Install the Clerk iOS SDK

Follow the Swift Package Manager instructions to install Clerk as a dependency. When prompted for the package URL, enter https://github.com/clerk/clerk-ios. Be sure to add the package to your target.

Load Clerk

To use Clerk in your app, you must first configure and load Clerk.

  • Inside your new project in Xcode, open your @main app file.
  • Import Clerk.
  • Create a reference to the shared Clerk instance.
  • Replace ContentView() with the ZStack in the following example. It injects your reference to the shared clerk instance into the environment, and attaches a .task modifier to the new ZStack. Then, in the body of the task, it configures clerk with your Publishable Key, and then loads clerk.
ClerkQuickstartApp.swift
import SwiftUI
import Clerk

@main
struct ClerkQuickstartApp: App {
  @State private var clerk = Clerk.shared

  var body: some Scene {
    WindowGroup {
      ZStack {
        if clerk.isLoaded {
          ContentView()
        } else {
          ProgressView()
        }
      }
      .environment(clerk)
      .task {
        clerk.configure(publishableKey: "YOUR_PUBLISHABLE_KEY")
        try? await clerk.load()
      }
    }
  }
}

Conditionally render content

To render content based on whether a user is authenticated or not:

  1. Open your ContentView file.
  2. Import Clerk and access the shared Clerk instance that you injected into the environment in the previous step.
  3. Replace the content of the view body with a conditional that checks for a clerk.user.
ContentView.swift
import SwiftUI
import Clerk

struct ContentView: View {
  @Environment(Clerk.self) private var clerk

  var body: some View {
    VStack {
      if let user = clerk.user {
        Text("Hello, \(user.id)")
      } else {
        Text("You are signed out")
      }
    }
  }
}

Create sign-up and sign-in views

SignUpView

Create a SignUpView with the following code. It allows users to sign up using their email address and password, and sends an email verification code to confirm their email address.

SignUpView.swift
import SwiftUI
import Clerk

struct SignUpView: View {
  @State private var email = ""
  @State private var password = ""
  @State private var code = ""
  @State private var isVerifying = false

  var body: some View {
    VStack {
      Text("Sign Up")
      if isVerifying {
        TextField("Code", text: $code)
        Button("Verify") {
          Task { await verify(code: code) }
        }
      } else {
        TextField("Email", text: $email)
        SecureField("Password", text: $password)
        Button("Continue") {
          Task { await signUp(email: email, password: password) }
        }
      }
    }
    .padding()
  }
}

extension SignUpView {

  func signUp(email: String, password: String) async {
    do {
      let signUp = try await SignUp.create(
        strategy: .standard(emailAddress: email, password: password)
      )

      try await signUp.prepareVerification(strategy: .emailCode)

      isVerifying = true
    } catch {
      dump(error)
    }
  }

  func verify(code: String) async {
    do {
      guard let signUp = Clerk.shared.client?.signUp else {
        isVerifying = false
        return
      }

      try await signUp.attemptVerification(.emailCode(code: code))
    } catch {
      dump(error)
    }
  }

}

SignInView

Create a SignInView with the following code. It allows users to sign in using their email address and password.

SignInView.swift
import SwiftUI
import Clerk

struct SignInView: View {
  @State private var email = ""
  @State private var password = ""

  var body: some View {
    VStack {
      Text("Sign In")
      TextField("Email", text: $email)
      SecureField("Password", text: $password)
      Button("Continue") {
        Task { await submit(email: email, password: password) }
      }
    }
    .padding()
  }
}

extension SignInView {

  func submit(email: String, password: String) async {
    do {
      try await SignIn.create(
        strategy: .identifier(email, password: password)
      )
    } catch {
      dump(error)
    }
  }

}

SignUpOrSignInView

Create a SignUpOrSignInView container view that allows users to switch between sign up and sign in.

SignUpOrSignInView.swift
import SwiftUI

struct SignUpOrSignInView: View {
  @State private var isSignUp = true

  var body: some View {
    ScrollView {
      if isSignUp {
        SignUpView()
      } else {
        SignInView()
      }

      Button {
        isSignUp.toggle()
      } label: {
        if isSignUp {
          Text("Already have an account? Sign in")
        } else {
          Text("Don't have an account? Sign up")
        }
      }
      .padding()
    }
  }
}

Render the sign-up/sign-in view

Go back to your ContentView and render your newly created SignUpOrSignInView when the user isn't signed in.

ContentView.swift
import SwiftUI
import Clerk

struct ContentView: View {
  @Environment(Clerk.self) private var clerk

  var body: some View {
    VStack {
      if let user = clerk.user {
        Text("Hello, \(user.id)")
      } else {
        SignUpOrSignInView()
      }
    }
  }
}

Allow users to sign out

Finally, provide users with a way to sign out of your app. In your ContentView, add the following code. It adds a button that calls Clerk's signOut() method in order to end a user's session.

ContentView.swift
import SwiftUI
import Clerk

struct ContentView: View {
  @Environment(Clerk.self) private var clerk

  var body: some View {
    VStack {
      if let user = clerk.user {
        Text("Hello, \(user.id)")
        Button("Sign Out") {
          Task { try? await clerk.signOut() }
        }
      } else {
        SignUpOrSignInView()
      }
    }
  }
}

Create your first user

Run your project. To sign up and create your first user, enter your email and password and select "Continue".

Feedback

What did you think of this content?

Last updated on