Skip to main content

Installation

Swift Package Manager

Add Supabase Swift to your Package.swift:
dependencies: [
  .package(
    url: "https://github.com/supabase/supabase-swift",
    from: "2.0.0"
  )
]

Xcode

  1. In Xcode, go to File → Add Package Dependencies
  2. Enter the repository URL: https://github.com/supabase/supabase-swift
  3. Select the version and add to your target

Initializing

Create a Supabase client to interact with your database.
import Supabase

let supabase = SupabaseClient(
  supabaseURL: URL(string: "YOUR_SUPABASE_URL")!,
  supabaseKey: "YOUR_SUPABASE_ANON_KEY"
)
supabaseURL
URL
required
The unique Supabase URL for your project.
supabaseKey
String
required
The Supabase anon key for your project.
options
SupabaseClientOptions
Optional configuration parameters.

Database Operations

Select Data

Query data from your tables.
let response: [Country] = try await supabase
  .from("countries")
  .select()
  .execute()
  .value
value
[T]
The returned rows from the query, decoded to your model type.

Define Models

struct Country: Codable {
  let id: Int
  let name: String
  let code: String
  let capital: String?
}

Select with Filters

let country: Country = try await supabase
  .from("countries")
  .select()
  .eq("id", value: 1)
  .single()
  .execute()
  .value

Select Specific Columns

let response = try await supabase
  .from("countries")
  .select(columns: "name, capital")
  .execute()
  .value

Common Filters

// Equal to
let data = try await supabase
  .from("countries")
  .select()
  .eq("name", value: "Albania")
  .execute()
  .value

// Not equal to
let data = try await supabase
  .from("countries")
  .select()
  .neq("name", value: "Albania")
  .execute()
  .value

// Greater than
let data = try await supabase
  .from("countries")
  .select()
  .gt("population", value: 1000000)
  .execute()
  .value

// Less than
let data = try await supabase
  .from("countries")
  .select()
  .lt("population", value: 1000000)
  .execute()
  .value

// Like (pattern matching)
let data = try await supabase
  .from("countries")
  .select()
  .like("name", pattern: "%Alba%")
  .execute()
  .value

// In list
let data = try await supabase
  .from("countries")
  .select()
  .in("name", values: ["Albania", "Algeria"])
  .execute()
  .value

Insert Data

Insert rows into your tables.
struct NewCountry: Encodable {
  let name: String
  let code: String
}

let newCountry = NewCountry(name: "Denmark", code: "DK")

let response: [Country] = try await supabase
  .from("countries")
  .insert(newCountry)
  .select()
  .execute()
  .value
values
Encodable | [Encodable]
required
The values to insert. Can be a single object or an array of objects.

Insert Multiple Rows

let countries = [
  NewCountry(name: "Denmark", code: "DK"),
  NewCountry(name: "Norway", code: "NO")
]

let response: [Country] = try await supabase
  .from("countries")
  .insert(countries)
  .select()
  .execute()
  .value

Update Data

Update existing rows in your tables.
struct CountryUpdate: Encodable {
  let name: String
}

let update = CountryUpdate(name: "Australia")

let response: [Country] = try await supabase
  .from("countries")
  .update(update)
  .eq("id", value: 1)
  .select()
  .execute()
  .value
values
Encodable
required
The values to update.

Upsert Data

Insert or update rows based on unique constraints.
let country = Country(id: 1, name: "Australia", code: "AU", capital: "Canberra")

let response: [Country] = try await supabase
  .from("countries")
  .upsert(country)
  .select()
  .execute()
  .value

Delete Data

Delete rows from your tables.
try await supabase
  .from("countries")
  .delete()
  .eq("id", value: 1)
  .execute()

Authentication

Sign Up

Create a new user account.
let response = try await supabase.auth.signUp(
  email: "example@email.com",
  password: "example-password"
)
email
String
required
The user’s email address.
password
String
required
The user’s password.
data
[String: AnyJSON]
Additional user metadata.
redirectTo
URL
A URL to redirect to after signup.
response
AuthResponse

Sign In

Sign in an existing user.
let session = try await supabase.auth.signIn(
  email: "example@email.com",
  password: "example-password"
)

Sign Out

Sign out the current user.
try await supabase.auth.signOut()

Get Session

Get the current session.
let session = try await supabase.auth.session
session
Session
The current session object.

Get User

Get the current user.
let user = try await supabase.auth.user()
user
User
The current user object.

Auth State Changes

Listen to authentication state changes.
for await state in await supabase.auth.authStateChanges {
  switch state.event {
  case .signedIn:
    print("User signed in: \(state.session?.user.email ?? "")")
  case .signedOut:
    print("User signed out")
  default:
    break
  }
}

Storage

Upload File

Upload a file to a storage bucket.
import Foundation

let fileData = Data(contentsOf: fileURL)

let response = try await supabase.storage
  .from("avatars")
  .upload(
    path: "public/avatar1.png",
    file: fileData,
    options: FileOptions(
      contentType: "image/png"
    )
  )
path
String
required
The file path including the file name.
file
Data
required
The file data to upload.
options
FileOptions
Upload options.

Download File

Download a file from storage.
let data = try await supabase.storage
  .from("avatars")
  .download(path: "public/avatar1.png")
path
String
required
The file path to download.
data
Data
The file data.

List Files

List all files in a bucket.
let files = try await supabase.storage
  .from("avatars")
  .list(
    path: "public",
    options: SearchOptions(
      limit: 100,
      offset: 0,
      sortBy: SortBy(column: "name", order: "asc")
    )
  )

Delete Files

Delete files from storage.
let response = try await supabase.storage
  .from("avatars")
  .remove(paths: ["public/avatar1.png", "public/avatar2.png"])

Get Public URL

Get the public URL for a file.
let url = try supabase.storage
  .from("avatars")
  .getPublicURL(path: "public/avatar1.png")

print(url)

Realtime

Subscribe to Changes

Listen to database changes in realtime.
let channel = await supabase.channel("db-changes")

let insertions = await channel.onPostgresChange(
  InsertAction.self,
  schema: "public",
  table: "countries"
) { insert in
  print("New country: \(insert.record)")
}

await channel.subscribe()
action
PostgresAction.Type
required
The database action to listen for: InsertAction, UpdateAction, DeleteAction, or AnyAction.
schema
String
required
The database schema to listen to.
table
String
required
The table to listen to.
callback
(T) -> Void
required
Function to call when an event occurs.

Unsubscribe

Stop listening to changes.
await supabase.removeChannel(channel)

Edge Functions

Invoke Function

Invoke a Supabase Edge Function.
struct FunctionPayload: Encodable {
  let name: String
}

struct FunctionResponse: Decodable {
  let message: String
}

let response: FunctionResponse = try await supabase.functions
  .invoke(
    "hello-world",
    options: FunctionInvokeOptions(
      body: FunctionPayload(name: "Functions")
    )
  )
functionName
String
required
The name of the Edge Function to invoke.
options
FunctionInvokeOptions
Function invocation options.
response
T
The response data from the function, decoded to your model type.

Error Handling

Handle errors using do-catch blocks:
do {
  let countries: [Country] = try await supabase
    .from("countries")
    .select()
    .execute()
    .value
  print("Countries: \(countries)")
} catch let error as PostgrestError {
  print("Database error: \(error.message)")
} catch {
  print("Unexpected error: \(error)")
}

SwiftUI Integration

Use Supabase with SwiftUI’s async/await:
import SwiftUI
import Supabase

struct CountriesView: View {
  @State private var countries: [Country] = []
  
  var body: some View {
    List(countries, id: \.id) { country in
      Text(country.name)
    }
    .task {
      await loadCountries()
    }
  }
  
  func loadCountries() async {
    do {
      countries = try await supabase
        .from("countries")
        .select()
        .execute()
        .value
    } catch {
      print("Error loading countries: \(error)")
    }
  }
}

Additional Resources

GitHub Repository

View the source code and contribute

Swift Package Index

View package details and documentation