Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/code-examples/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import { customizationExamples } from './customization';
import { paymentsExamples } from './payments';
import { selfHostExamples } from './self-host';
import { setupExamples } from './setup';
import { swiftExamples } from './swift';
import { viteExamples } from './vite-example';

const allExamples: Record<string, Record<string, Record<string, CodeExample[]>>> = {
'setup': setupExamples,
'apps': {...apiKeysExamples, ...paymentsExamples },
'getting-started': viteExamples,
'getting-started': {...viteExamples, ...swiftExamples},
'others': selfHostExamples,
'customization': customizationExamples,
};
Expand Down
190 changes: 190 additions & 0 deletions docs/code-examples/swift.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
import { CodeExample } from '../lib/code-examples';

export const swiftExamples = {
'swift': {
'installation': [
{
language: 'Swift',
framework: 'Swift',
variant: 'package',
code: `dependencies: [
.package(url: "https://github.com/stack-auth/swift-sdk-prerelease", from: "0.1.0")
]`,
highlightLanguage: 'swift',
filename: 'Package.swift'
}
] as CodeExample[],

'init-sdk': [
{
language: 'Swift',
framework: 'Swift',
code: `import StackAuth

let stack = StackClientApp(
projectId: "your-project-id",
publishableClientKey: "pck_your-publishable-key"
)`,
highlightLanguage: 'swift',
filename: 'App.swift'
}
] as CodeExample[],

'sign-up-sign-in': [
{
language: 'Swift',
framework: 'Swift',
code: `// Sign up with email/password
try await stack.signUpWithCredential(
email: "user@example.com",
password: "securepassword123"
)

// Sign in with email/password
try await stack.signInWithCredential(
email: "user@example.com",
password: "securepassword123"
)

// OAuth sign-in (opens system browser)
try await stack.signInWithOAuth(provider: "google")`,
highlightLanguage: 'swift',
filename: 'AuthView.swift'
}
] as CodeExample[],

'get-user': [
{
language: 'Swift',
framework: 'Swift',
code: `if let user = try await stack.getUser() {
print("Signed in as \\(user.displayName ?? "Unknown")")
print("Email: \\(user.primaryEmail ?? "No email")")
}`,
highlightLanguage: 'swift',
filename: 'UserView.swift'
}
] as CodeExample[],

'sign-out': [
{
language: 'Swift',
framework: 'Swift',
code: `try await stack.signOut()`,
highlightLanguage: 'swift',
filename: 'AuthView.swift'
}
] as CodeExample[],

'token-storage': [
{
language: 'Swift',
framework: 'Swift',
code: `// Default: Keychain (secure, persists across app launches)
let stack = StackClientApp(
projectId: "...",
publishableClientKey: "..."
)

// Memory storage (for testing or ephemeral sessions)
let stack = StackClientApp(
projectId: "...",
publishableClientKey: "...",
tokenStore: .memory
)

// Explicit tokens (for server-side scenarios)
let stack = StackClientApp(
projectId: "...",
publishableClientKey: "...",
tokenStore: .explicit(accessToken: "...", refreshToken: "...")
)`,
highlightLanguage: 'swift',
filename: 'App.swift'
}
] as CodeExample[],

'error-handling': [
{
language: 'Swift',
framework: 'Swift',
code: `do {
try await stack.signInWithCredential(email: email, password: password)
} catch let error as StackAuthError {
switch error.code {
case "EMAIL_PASSWORD_MISMATCH":
print("Invalid email or password")
case "USER_NOT_FOUND":
print("No account found with this email")
default:
print("Error: \\(error.message)")
}
}`,
highlightLanguage: 'swift',
filename: 'AuthView.swift'
}
] as CodeExample[],

'oauth': [
{
language: 'Swift',
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Citation: Updated OAuth code examples based on PR #1130. The new API signatures are documented in sdks/implementations/swift/README.md and the spec at sdks/spec/src/apps/client-app.spec.md.
View source

framework: 'Swift',
variant: 'simple',
code: `// Opens system browser, handles callback automatically
// Uses the fixed callback scheme: stack-auth://
try await stack.signInWithOAuth(provider: "google")`,
highlightLanguage: 'swift',
filename: 'AuthView.swift'
},
{
language: 'Swift',
framework: 'Swift',
variant: 'custom',
code: `// Get OAuth URL for manual handling
// Must provide full URLs with scheme
let oauth = try await stack.getOAuthUrl(
provider: "google",
redirectUrl: "stack-auth://oauth-callback",
errorRedirectUrl: "stack-auth://error"
)

// Open oauth.url in your own browser/webview
// Store oauth.state, oauth.codeVerifier, and oauth.redirectUrl

// When callback is received:
try await stack.callOAuthCallback(
url: callbackUrl,
codeVerifier: oauth.codeVerifier,
redirectUrl: oauth.redirectUrl
)`,
highlightLanguage: 'swift',
filename: 'OAuthHandler.swift'
}
] as CodeExample[],

'server-side': [
{
language: 'Swift',
framework: 'Swift',
code: `let serverApp = StackServerApp(
projectId: "your-project-id",
secretServerKey: "ssk_your-secret-key"
)

// List all users
let users = try await serverApp.listUsers()

// Get a specific user
let user = try await serverApp.getUser(userId: "user-id")

// Create a user
let newUser = try await serverApp.createUser(
primaryEmail: "new@example.com",
password: "securepassword"
)`,
highlightLanguage: 'swift',
filename: 'Server.swift'
}
] as CodeExample[],
}
};
3 changes: 2 additions & 1 deletion docs/content/docs/(guides)/getting-started/setup.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ Before getting started, make sure you have a project set up for your chosen plat
- **React**: A [React project](https://react.dev/learn/creating-a-react-app) (we show examples with Vite)
- **JavaScript**: A Node.js project with Express
- **Python**: A Python environment with your chosen framework (Django, FastAPI, or Flask)
- **Swift (Preview)**: An iOS, macOS, watchOS, tvOS, or visionOS project using Swift 5.9+ — see our [Swift SDK guide](./swift.mdx)

We recommend using our **setup wizard** for JavaScript frameworks for a seamless installation experience. For Python, we recommend using the REST API approach.
We recommend using our **setup wizard** for JavaScript frameworks for a seamless installation experience. For Python, we recommend using the REST API approach. For Swift, see the dedicated [Swift SDK documentation](./swift.mdx).

### Setup Wizard / Manual Installation
<Tabs defaultValue="wizard">
Expand Down
131 changes: 131 additions & 0 deletions docs/content/docs/(guides)/getting-started/swift.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
---
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Citation: Based on the Swift SDK implementation in sdks/implementations/swift/ and the SDK README (sdks/implementations/swift/README.md) which documents installation, quick start, token storage options, error handling, OAuth flows, and server-side usage patterns. Marked as preview since it publishes to stack-auth/swift-sdk-prerelease.
View source

title: Swift SDK (Preview)
lastModified: "2026-01-22"
---

<Info type="warning">
The Swift SDK is currently in preview. APIs may change before the stable release. We'd love your feedback—join our [Discord](https://discord.stack-auth.com) to share your thoughts.
</Info>

The Swift SDK provides native authentication for iOS, macOS, watchOS, tvOS, and visionOS apps. It uses async/await, Keychain storage, and system OAuth flows.

## Requirements

- Swift 5.9 or later
- iOS 15+ / macOS 12+ / watchOS 8+ / tvOS 15+ / visionOS 1+

## Installation

Add the SDK to your project using Swift Package Manager. In your `Package.swift`:

<PlatformCodeblock
document="getting-started/swift"
examples={["installation"]}
/>

Or in Xcode:
1. Go to File → Add Package Dependencies
2. Enter `https://github.com/stack-auth/swift-sdk-prerelease`
3. Select your desired version and add to your target

## Quick Start

### Initialize the SDK

<PlatformCodeblock
document="getting-started/swift"
examples={["init-sdk"]}
/>

Get your project ID and publishable key from the [Stack Auth dashboard](https://app.stack-auth.com).

### Sign Up and Sign In

<PlatformCodeblock
document="getting-started/swift"
examples={["sign-up-sign-in"]}
/>

### Get the Current User

<PlatformCodeblock
document="getting-started/swift"
examples={["get-user"]}
/>

### Sign Out

<PlatformCodeblock
document="getting-started/swift"
examples={["sign-out"]}
/>

## Token Storage

By default, tokens are stored securely in the system Keychain. You can configure alternative storage:

<PlatformCodeblock
document="getting-started/swift"
examples={["token-storage"]}
/>

## Error Handling

SDK methods use Swift's native `throws` mechanism. Errors conform to `StackAuthError`:

<PlatformCodeblock
document="getting-started/swift"
examples={["error-handling"]}
/>

## OAuth Authentication

The Swift SDK uses `ASWebAuthenticationSession` for OAuth, providing a secure system browser experience.

### Simple OAuth (Recommended)

For most apps, simply use `signInWithOAuth()` — it handles the entire OAuth flow automatically. It uses the `stack-auth://` callback scheme, which works without any additional configuration:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Citation: OAuth API changes from PR #1130: signInWithOAuth() now uses fixed stack-auth:// callback scheme, getOAuthUrl() requires explicit redirectUrl and errorRedirectUrl parameters, and callOAuthCallback() requires the redirectUrl parameter. See changes in sdks/spec/src/apps/client-app.spec.md for the spec and sdks/implementations/swift/Sources/StackAuth/StackClientApp.swift for the implementation.
View source


<PlatformCodeblock
document="getting-started/swift"
examples={["oauth"]}
/>

### Manual OAuth Flow

If you need more control, use `getOAuthUrl()` to get the authorization URL and handle the callback yourself. You'll need to provide redirect URLs:

- **`redirectUrl`**: Where the provider redirects on success (e.g., `stack-auth://oauth-callback`)
- **`errorRedirectUrl`**: Where the provider redirects on error (e.g., `stack-auth://error`)

<Info>
The `stack-auth://` scheme works out of the box. If you want to use a custom scheme (like `myapp://`), you'll need to add it as a trusted domain in your Stack Auth project settings.
</Info>

## Server-Side Usage

For server-side operations, use `StackServerApp`:

<PlatformCodeblock
document="getting-started/swift"
examples={["server-side"]}
/>

<Info type="warning">
Never include your secret server key in client-side code. `StackServerApp` should only be used in secure server environments.
</Info>

## Key Differences from JavaScript SDK

| Feature | JavaScript SDK | Swift SDK |
|---------|---------------|-----------|
| Token Storage | Cookies | Keychain |
| OAuth Flow | Browser redirect | ASWebAuthenticationSession |
| Redirect Methods | Available | Not available (browser-only) |
| React Hooks | `useUser()`, etc. | Not applicable |

## Next Steps

- Check out the [REST API documentation](/api/overview) for all available endpoints
- Join our [Discord community](https://discord.stack-auth.com) to share feedback on the Swift SDK preview
- See the [example apps](https://github.com/stack-auth/stack-auth/tree/main/sdks/implementations/swift/Examples) for more usage examples
1 change: 1 addition & 0 deletions docs/content/docs/(guides)/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"getting-started/users",
"getting-started/production",
"getting-started/vite-example",
"getting-started/swift",
"---Apps---",
"apps/api-keys",
"apps/emails",
Expand Down
Loading