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.
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.
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 ClerkSDK
.
Add a new variable clerk
marked with the @ObservedObject
property wrapper.
Replace ContentView()
with the below ZStack
.
Attach a .task
modifier to the new ZStack
. In the body of the task, configure clerk
with your publishable key, and then load clerk
. You can get your publishable key from the API Keys page of the Clerk Dashboard.
ClerkQuickstartApp.swift import SwiftUI
import ClerkSDK
@main
struct ClerkQuickstartApp : App {
@ObservedObject private var clerk = Clerk.shared
var body: some Scene {
WindowGroup {
ZStack {
if clerk.loadingState == .notLoaded {
ProgressView ()
} else {
ContentView ()
}
}
. task {
clerk. configure ( publishableKey : " YOUR_PUBLISHABLE_KEY " )
try? await clerk. load ()
}
}
}
}
To render content based on whether a user is authenticated or not:
Open your ContentView
file.
Import ClerkSDK
.
Add a new variable clerk
marked with the @ObservedObject
property wrapper.
Replace the content of the view body with a conditional that checks for a clerk.user
.
ContentView.swift import SwiftUI
import ClerkSDK
struct ContentView : View {
@ObservedObject private var clerk = Clerk.shared
var body: some View {
VStack {
if let user = clerk.user {
Text ( "Hello, \(user.id) " )
} else {
Text ( "You are signed out" )
}
}
}
}
The following example creates a SignUpView
that 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 ClerkSDK
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 )
}
}
}
The following example creates a SignInView
that allows users to sign in using their email address and password.
SignInView.swift import SwiftUI
import ClerkSDK
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 )
}
}
}
Finally, 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 ()
}
}
}
Go back to your ContentView
and render your newly created SignUpOrSignInView
when the user isn't signed in.
ContentView.swift import SwiftUI
import ClerkSDK
struct ContentView : View {
@ObservedObject private var clerk = Clerk.shared
var body: some View {
VStack {
if let user = clerk.user {
Text ( "Hello, \(user.id) " )
} else {
SignUpOrSignInView ()
}
}
}
}
Finally, provide users with a way to sign out of your app:
Open your ContentView
.
Add a button that ends a user's session.
ContentView.swift import SwiftUI
import ClerkSDK
struct ContentView : View {
@ObservedObject private var clerk = Clerk.shared
var body: some View {
VStack {
if let user = clerk.user {
Text ( "Hello, \(user.id) " )
Button ( "Sign Out" ) {
Task { try? await clerk. signOut () }
}
} else {
SignUpOrSignInView ()
}
}
}
}