Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.metabind.ai/llms.txt

Use this file to discover all available pages before exploring further.

The Metabind iOS SDK (metabind-apple) lets you render server-driven content in your Swift applications. Build dynamic experiences that update instantly without app store releases.

View on GitHub

metabind-apple — source code, issues, and releases.

Requirements

RequirementVersion
Xcode15.0 or later
iOS17.0 or later
macOS14.0 or later
Swift5.9 or later

Installation

Add the Metabind SDK to your project using Swift Package Manager.
  1. Open your project in Xcode
  2. Go to File → Add Package Dependencies
  3. Enter the repository URL:
https://github.com/metabindai/metabind-apple
  1. Select the version and add to your target

Quick start

1. Initialize the client

Create a MetabindClient with your API credentials from the Metabind dashboard:
import SwiftUI
import Metabind

@main
struct MyApp: App {

    @State var client = MetabindClient(
        url: URL(string: "https://api.metabind.ai/graphql")!,
        ws: URL(string: "wss://ws-api.metabind.ai")!,
        apiKey: "your-api-key",
        organizationId: "your-org-id",
        projectId: "your-project-id"
    )

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .environment(client)
    }
}

2. Display content

Use MetabindView to render content by its ID:
struct ContentView: View {

    var body: some View {
        MetabindView(contentId: "your-content-id")
    }
}
To receive live updates when the content changes in Metabind, opt in to the WebSocket subscription:
MetabindView(contentId: "your-content-id", enableSubscription: true)

3. Handle actions

Listen for actions triggered by user interactions:
MetabindView(contentId: "your-content-id")
    .onMetabindAction { action in
        switch action.name {
        case "metabind.content":
            // Navigate to another content page
            if let contentId = action.props["contentId"] as? String {
                navigateTo(contentId)
            }
        case "custom.action":
            // Handle your custom actions
            handleCustomAction(action.props)
        default:
            break
        }
    }

Core concepts

MetabindClient

The client manages the connection to Metabind’s API and handles:
  • Authentication — API key validation and request signing
  • Content fetching — GraphQL queries for content and components
  • Real-time updates — WebSocket subscriptions for live content changes
  • Caching — a local SQLite-backed cache of fetched content and components
Inject the client into the SwiftUI environment so all views can access it:
.environment(client)
For direct access, MetabindClient exposes async fetchers — fetchContent(id:), fetchContents(typeId:limit:) — along with streamContent(id:) and subscribeToContent(id:) for cache-then-network and real-time streams.

MetabindView

MetabindView is the primary way to display content. It automatically:
  • Fetches the content and its required components
  • Renders the UI based on your design system
  • Subscribes to real-time updates when enableSubscription is true
  • Handles loading and error states
MetabindView(contentId: "content-id", enableSubscription: false)

Actions

Actions are events triggered by user interactions with your content. Handle them with the onMetabindAction modifier, which delivers a MetabindContentAction (a name and a props dictionary):
ActionDescription
metabind.contentNavigate to another content page
metabind.urlOpen an external URL
metabind.dismissDismiss the current view
Custom actionsYour own defined actions

Real-time updates

For live content, either pass enableSubscription: true to MetabindView or subscribe directly. subscribeToContent(id:) opens a GraphQL WebSocket subscription and yields the content each time it changes in Metabind:
for await result in client.subscribeToContent(id: "your-content-id") {
    if case .success(let content) = result {
        // Re-render or update state with the new content
    }
}
The client pauses the subscription when the app enters the background and resumes it on return. For cache-then-network delivery without a live subscription, use streamContent(id:).

Direct GraphQL access

Beyond MetabindView, MetabindClient exposes the underlying GraphQL operations directly, all following the same shape:
  • fetch* — a single async request.
  • stream* — an AsyncStream that yields cached data first, then network updates.
  • subscribeTo* — a real-time WebSocket subscription (content only).
These cover content, components, content types, assets, tags, packages, and saved searches. For the full method catalog and parameters, see the client API reference; for the GraphQL API itself, see the GraphQL docs. For apps with multiple content pages, integrate with SwiftUI’s navigation system:
struct ContentView: View {

    @State private var path = NavigationPath()

    private enum Destination: Hashable {
        case content(id: String)
    }

    var body: some View {
        NavigationStack(path: $path) {
            MetabindView(contentId: "home")
                .onMetabindAction { action in
                    if action.name == "metabind.content",
                       let contentId = action.props["contentId"] as? String
                    {
                        path.append(Destination.content(id: contentId))
                    }
                }
                .navigationDestination(for: Destination.self) { destination in
                    switch destination {
                    case .content(let id):
                        MetabindView(contentId: id)
                    }
                }
        }
    }
}

Platform support

PlatformMinimum Version
iOS17.0
macOS14.0

Next steps

Sample app

See a complete example of the SDK in action.

Build components

Create custom components for your app.

BindJS reference

Learn the component authoring language.

Managing content

Understand how to structure content.