iOS (Swift)
Build and query a ZXCV database from a SwiftUI app, then ship it to the edge. You’ll end with a view that reads live data.
Create a project
In the dashboard click Start building, or run zxcv
from your terminal. Open Settings → API and copy your project ref and
anon key — the anon key is public and safe to ship, because access is enforced
server-side by your authorization rules.
Create a table
In the SQL editor, create a todos table with a couple of rows:
create table todos (
id bigint generated always as identity primary key,
title text not null,
is_complete boolean not null default false
);
insert into todos (title) values ('Read the docs'), ('Ship an app');Install the SDK
Add the ZXCV Swift package in Xcode via File → Add Package Dependencies,
using the repository URL:
https://github.com/zxcv-labs/zxcv-swiftOr add it to a Package.swift:
dependencies: [
.package(url: "https://github.com/zxcv-labs/zxcv-swift", from: "1.0.0"),
],Initialize the client
Create the client once in your @main App entry point and pass it down through
the SwiftUI environment. The anon key is safe to ship in client code:
import SwiftUI
import ZXCV
let zxcv = ZXCVClient(project: "acme-store", anonKey: "your-anon-key")
@main
struct TodosApp: App {
var body: some Scene {
WindowGroup {
TodosView()
}
}
}For real projects, keep your keys out of source — store the anon key in your
build configuration (.xcconfig) or Info.plist and read it at launch rather
than hard-coding it.
Fetch and render
Model a Todo, then load the rows in an async .task and render them with a
SwiftUI List:
import SwiftUI
import ZXCV
struct Todo: Decodable, Identifiable {
let id: Int
let title: String
let isComplete: Bool
}
struct TodosView: View {
@State private var todos: [Todo] = []
@State private var errorMessage: String?
var body: some View {
NavigationStack {
List(todos) { todo in
Text(todo.title)
}
.navigationTitle("Todos")
.overlay {
if let errorMessage {
Text(errorMessage)
}
}
.task {
do {
todos = try await zxcv
.from("todos")
.select("id, title, is_complete")
.order("id")
} catch {
errorMessage = error.localizedDescription
}
}
}
}
}Deploy
Ship your project to the global edge from your terminal:
npm i -g zxcv
zxcv link acme-store
zxcv deploy --prodEvery push gets a preview URL; --prod promotes to your domain. See
Deploy for custom domains and canaries.
Next steps
- Auth — add sign-in and row-level security
- Realtime — live updates as rows change
- SDK reference · Database