A comprehensive SwiftUI application demonstrating all features of the Supabase Swift SDK with best-in-class UX and extensive inline code examples.
This example app serves as both a functional demonstration and an educational resource for developers learning the Supabase Swift SDK. Each feature includes:
- 🎯 Interactive Examples: Try every SDK feature with real data
- 📝 Inline Code Snippets: See exact API usage within each screen
- 📚 Educational Content: Detailed explanations and use cases
- ✨ Modern UX: Polished interface following iOS design patterns
- 🔄 Live Updates: Real-time feedback and state management
Comprehensive authentication examples with multiple sign-in methods:
- Email & Password: Traditional sign-up and sign-in with email confirmation
- Magic Link: Passwordless authentication via email
- Phone OTP: SMS-based authentication with verification codes
- OAuth Providers:
- Sign in with Apple (native integration)
- Sign in with Google (using Google Sign-In SDK)
- Sign in with Facebook
- Generic OAuth flow for other providers
- Anonymous Sign-In: Temporary guest access with account conversion
- Multi-Factor Authentication (MFA):
- TOTP enrollment with QR codes
- Authenticator app support
- Factor management and verification
Each auth method includes:
- Step-by-step guidance
- Loading states and error handling
- Success confirmations
- Code examples showing exact API usage
Full-featured database operations with a todo list example:
- CRUD Operations: Create, read, update, and delete todos
- Filtering & Ordering: Advanced query filters and sorting options
- RPC Functions: Call custom PostgreSQL functions
- Aggregations: Count and aggregate data operations
- Relationships: Query related data across tables with joins
Features:
- Real-time todo list with instant updates
- Inline SQL examples
- Filter builder with multiple conditions
- Relationship demonstrations with profiles
Live data synchronization across multiple channels:
- Postgres Changes: Listen to database INSERT, UPDATE, DELETE events
- Broadcast: Send and receive real-time messages between clients
- Presence: Track online users with metadata
- Live Todo Updates: See changes from other users instantly
Features:
- Connection status indicators
- Message history
- Online user count
- Automatic reconnection
Complete file and bucket management system:
-
Bucket Operations:
- Create, update, delete buckets
- Configure public/private access
- Set file size limits
- Empty buckets
-
File Upload:
- Photo library integration
- Document picker
- Multiple upload methods
- Progress tracking
- Upsert support
-
File Download:
- Download with preview
- Image display
- Text file viewing
- Metadata inspection
-
Image Transformations:
- Resize (width/height)
- Quality adjustment
- Format conversion (WebP)
- Multiple resize modes (cover, contain, fill)
- Side-by-side comparison
-
Signed URLs:
- Temporary download links
- Signed upload URLs
- Public URL generation
- Expiration control
-
File Management:
- Move files between paths
- Copy files
- Delete single/multiple files
- Batch operations
-
Search & Metadata:
- Advanced file search
- Sort by name, date, size
- Filter by type
- Detailed metadata view
All storage examples include inline code snippets showing the exact API calls.
Serverless function invocation:
- Invoke Edge Functions
- Pass parameters
- Handle responses
- Error management
Comprehensive user account management:
-
Profile Overview:
- View account information
- Email, phone, user ID
- Account creation date
- MFA status indicator
-
Update Profile:
- Change email (with verification)
- Update phone number (with OTP)
- Change password
- Multi-field updates
-
Password Management:
- Password reset via email
- Secure reset links
- Step-by-step recovery flow
-
Linked Identities:
- View all linked OAuth accounts
- Link new social providers
- Unlink identities
- Provider icons and metadata
- Swipe-to-delete gesture
-
Security:
- MFA enrollment and management
- Reauthentication
- Session management
- Sign out (global/local)
Features:
- Pull-to-refresh
- Loading states
- Success/error feedback
- Inline code examples
- Educational tooltips
- Xcode 15.0 or later
- iOS 17.0+ / macOS 14.0+ or later
- Supabase CLI installed
The Examples app is configured to use a local Supabase instance from the /supabase directory.
# Navigate to the root directory
cd /path/to/supabase-swift
# Start Supabase local development
supabase startThis will start the local Supabase services:
- API: http://127.0.0.1:54321
- Studio: http://127.0.0.1:54323
- Inbucket (email testing): http://127.0.0.1:54324
The database schema is automatically created from migrations in /supabase/migrations/:
20240327182636_init_key_value_storage_schema.sql- Key-value storage20251009000000_examples_schema.sql- Examples app tables and RLS policies
These migrations are applied automatically when you run supabase start.
Optional: Seed sample data:
# Load seed data into the database
supabase db resetThe app is pre-configured to use the local instance:
Supabase.plist:
<dict>
<key>SUPABASE_URL</key>
<string>http://127.0.0.1:54321</string>
<key>SUPABASE_ANON_KEY</key>
<string>eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0</string>
</dict>This is the default anon key for local Supabase development.
- Open
Examples.xcodeprojin Xcode - Ensure local Supabase is running (
supabase start) - Select your target device or simulator
- Build and run (⌘R)
-
Sign Up: Create an account using any authentication method
- Try email/password for the full experience
- Or use "Sign in Anonymously" for quick testing
-
Explore the Tabs:
Database Tab:
- Create your first todo
- Try filtering and ordering
- Test RPC functions
- View aggregations
Realtime Tab:
- Watch database changes live
- Send broadcast messages
- Join presence channels
- See other users online (open app in multiple simulators!)
Storage Tab:
- Create a bucket
- Upload images from Photos
- Try image transformations
- Generate signed URLs
- Search and manage files
Functions Tab:
- Invoke sample Edge Functions
- Test with different parameters
Profile Tab:
- View your account details
- Update email/phone/password
- Link social accounts
- Enable MFA for extra security
- Manage linked identities
For the best real-time experience:
- Open the app on multiple devices/simulators
- Sign in with different accounts
- Navigate to the Realtime tab
- Watch updates appear instantly across all devices
Use Inbucket to view test emails:
- Open http://127.0.0.1:54324
- Sign up with any email (e.g., test@example.com)
- Check Inbucket for confirmation emails
- Click magic links or copy verification codes
To test OAuth authentication, you'll need to configure providers:
- Create a project in Google Cloud Console
- Enable Google Sign-In API
- Create OAuth 2.0 credentials for iOS
- Update
Info.plist:- Replace
{{ YOUR_IOS_CLIENT_ID }} - Replace
{{ YOUR_SERVER_CLIENT_ID }} - Replace
{{ DOT_REVERSED_IOS_CLIENT_ID }}
- Replace
- Create an app in Facebook Developers Console
- Add iOS platform
- Update
Info.plist:- Replace
{{ FACEBOOK APP ID }} - Replace
{{ FACEBOOK CLIENT TOKEN }}
- Replace
Apple Sign-In should work out of the box on iOS devices. Ensure:
- Sign in with Apple capability is enabled in Xcode
- Proper bundle identifier is configured
Examples/
├── Examples/
│ ├── Auth/ # Authentication examples
│ │ ├── AuthExamplesView.swift # Main auth navigation
│ │ ├── AuthWithEmailAndPassword.swift # Email/password auth
│ │ ├── AuthWithMagicLink.swift # Magic link auth
│ │ ├── SignInWithPhone.swift # Phone OTP auth
│ │ ├── SignInAnonymously.swift # Anonymous auth
│ │ ├── SignInWithApple.swift # Apple Sign In
│ │ ├── SignInWithFacebook.swift # Facebook auth
│ │ ├── SignInWithOAuth.swift # Generic OAuth
│ │ └── GoogleSignInSDKFlow.swift # Google Sign-In SDK
│ │
│ ├── Database/ # PostgREST database examples
│ │ ├── DatabaseExamplesView.swift # Main database navigation
│ │ ├── TodoListView.swift # CRUD operations
│ │ ├── FilteringView.swift # Query filtering
│ │ ├── RPCExamplesView.swift # RPC functions
│ │ ├── AggregationsView.swift # Aggregations
│ │ └── RelationshipsView.swift # Joins and relations
│ │
│ ├── Realtime/ # Realtime subscriptions
│ │ ├── RealtimeExamplesView.swift # Main realtime navigation
│ │ ├── PostgresChangesView.swift # Database changes
│ │ ├── TodoRealtimeView.swift # Live todo updates
│ │ ├── BroadcastView.swift # Broadcast messages
│ │ └── PresenceView.swift # Online presence
│ │
│ ├── Storage/ # File storage examples
│ │ ├── StorageExamplesView.swift # Main storage navigation
│ │ ├── BucketOperationsView.swift # Bucket CRUD
│ │ ├── FileUploadView.swift # File uploads
│ │ ├── FileDownloadView.swift # File downloads
│ │ ├── ImageTransformView.swift # Image transformations
│ │ ├── SignedURLsView.swift # URL generation
│ │ ├── FileManagementView.swift # Move/copy/delete
│ │ └── FileSearchView.swift # Search and metadata
│ │
│ ├── Functions/ # Edge Functions examples
│ │ └── FunctionsExamplesView.swift # Function invocation
│ │
│ ├── Profile/ # User profile management
│ │ ├── ProfileView.swift # Profile overview
│ │ ├── UpdateProfileView.swift # Update credentials
│ │ ├── ResetPasswordView.swift # Password reset
│ │ └── UserIdentityList.swift # Linked accounts
│ │
│ ├── MFAFlow.swift # Multi-factor authentication
│ ├── HomeView.swift # Main tab navigation
│ ├── RootView.swift # App root (auth check)
│ └── Shared/ # Shared utilities
│ ├── Components/ # Reusable UI components
│ └── Helpers/ # Helper functions
│
└── supabase/ # Local Supabase configuration
├── config.toml # Supabase configuration
├── migrations/ # Database migrations
│ ├── 20240327182636_init_key_value_storage_schema.sql
│ └── 20251009000000_examples_schema.sql
├── seed.sql # Seed data
└── functions/ # Edge Functions
The app uses the following tables with Row Level Security enabled:
CREATE TABLE todos (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
description text NOT NULL,
is_complete boolean DEFAULT false,
created_at timestamptz DEFAULT now(),
owner_id uuid REFERENCES auth.users(id) ON DELETE CASCADE
);RLS Policies:
- Users can only view/modify their own todos
- Authenticated users can create todos
CREATE TABLE profiles (
id uuid PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE,
username text UNIQUE,
full_name text,
avatar_url text,
website text,
updated_at timestamptz DEFAULT now()
);RLS Policies:
- All users can view profiles
- Users can only update their own profile
CREATE TABLE messages (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
content text NOT NULL,
user_id uuid REFERENCES auth.users(id) ON DELETE CASCADE,
channel_id text NOT NULL,
created_at timestamptz DEFAULT now()
);RLS Policies:
- All authenticated users can view messages
- Users can only insert/delete their own messages
increment_todo_count()
CREATE FUNCTION increment_todo_count(user_id uuid)
RETURNS integer;Demonstrates RPC functionality with return values.
Every screen includes CodeExample components showing the exact API calls:
CodeExample(
code: """
// Create a todo
try await supabase
.from("todos")
.insert(Todo(description: "Learn Supabase"))
.execute()
"""
)Each feature includes an "About" section explaining:
- What the feature does
- When to use it
- Best practices
- Security considerations
- Pull-to-refresh for data updates
- Swipe actions for delete/unlink
- Loading states with descriptive messages
- Error handling with clear feedback
- Success confirmations with helpful next steps
- Empty states with guidance
- Disclosure groups for advanced details
Consistent use of ActionState enum for async operations:
enum ActionState<Success, Failure: Error> {
case idle
case inFlight
case result(Result<Success, Failure>)
}ExampleRow: Navigation items with icons and descriptionsCodeExample: Syntax-highlighted code snippetsErrorText: Consistent error displayDetailRow: Key-value information display
# Check status
supabase status
# Restart services
supabase stop
supabase start- Ensure local Supabase is running on port 54321
- Check firewall settings
- Verify
Supabase.plisthas correct URL - Try accessing Studio at http://127.0.0.1:54323
- Ensure custom URL scheme is configured:
com.supabase.swift-examples:// - Check Info.plist for proper URL types configuration
- Verify redirect URL matches in Supabase config
- Run migrations:
supabase db reset - Check Studio at http://127.0.0.1:54323
- Verify RLS policies are correct
- Check user permissions
- Ensure bucket exists before uploading
- Check bucket permissions (public vs private)
- Verify file size limits
- Test with Storage browser in Studio
- Check connection status in the app
- Verify Realtime is enabled in Studio
- Check RLS policies allow access
- Try reconnecting from the UI
To connect to a remote Supabase project:
Update Supabase.plist:
<key>SUPABASE_URL</key>
<string>https://your-project.supabase.co</string>
<key>SUPABASE_ANON_KEY</key>
<string>your-anon-key</string># Link to your project
supabase link --project-ref your-project-ref
# Push migrations to remote
supabase db push
# Optional: Load seed data
supabase db reset --db-url "your-database-url"In your Supabase project settings:
- Navigate to Authentication → Providers
- Enable and configure OAuth providers
- Add redirect URLs for your app
- Create buckets in Studio
- Set up RLS policies
- Configure CORS if needed
- Code Examples: Every screen has inline code showing API usage
- About Sections: Detailed explanations of each feature
- Interactive Testing: Try features with live data
- Error Messages: Learn from mistakes with clear feedback
- Start Simple: Begin with email/password auth and basic CRUD
- Use Code Examples: Copy-paste examples directly into your app
- Test Locally First: Use local Supabase for development
- Check RLS Policies: Security is enabled by default
- Use Studio: Visual tools help understand database state
- Enable Realtime: More engaging user experience
- Add MFA: Extra security for sensitive operations
- Test Edge Cases: Try errors, empty states, slow connections
This example app is part of the Supabase Swift SDK. Contributions are welcome!
This example app is part of the Supabase Swift SDK and follows the same MIT License.