appwrite/agent-skills/appwrite-swift

Claude Code and agent skill by appwrite/agent-skills

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Appwrite Swift SDK skill. Use when building native iOS, macOS, watchOS, or tvOS apps, or server-side Swift applications with Appwrite. Covers client-side auth (email, OAuth), database queries, file uploads, real-time subscriptions with async/await, and server-side admin via API keys for user management, database administration, storage, and functions.

Install

npx vskill@latest install appwrite/agent-skills/appwrite-swift

SKILL.md

Appwrite Swift SDK

Installation

swift
// Swift Package Manager — Package.swift
.package(url: "https://github.com/appwrite/sdk-for-swift", branch: "main")

Setting Up the Client

Client-side (Apple platforms)
swift
import Appwrite
let client = Client()
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1")
.setProject("[PROJECT_ID]")
Server-side (Swift)
swift
import Appwrite
let client = Client()
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1")
.setProject(ProcessInfo.processInfo.environment["APPWRITE_PROJECT_ID"]!)
.setKey(ProcessInfo.processInfo.environment["APPWRITE_API_KEY"]!)

Code Examples

Authentication (client-side)
swift
let account = Account(client)
// Signup
let user = try await account.create(userId: ID.unique(), email: "user@example.com", password: "password123", name: "User Name")
// Login
let session = try await account.createEmailPasswordSession(email: "user@example.com", password: "password123")
// OAuth
try await account.createOAuth2Session(provider: .google)
// Get current user
let me = try await account.get()
// Logout
try await account.deleteSession(sessionId: "current")
User Management (server-side)
swift
let users = Users(client)
// Create user
let user = try await users.create(userId: ID.unique(), email: "user@example.com", password: "password123", name: "User Name")
// List users
let list = try await users.list(queries: [Query.limit(25)])
// Get user
let fetched = try await users.get(userId: "[USER_ID]")
// Delete user
try await users.delete(userId: "[USER_ID]")
Database Operations
Note: Use TablesDB (not the deprecated Databases class) for all new code. Only use Databases if the existing codebase already relies on it or the user explicitly requests it.
Tip: Prefer named parameters (e.g., databaseId: "...") for all SDK method calls. Only use positional arguments if the existing codebase already uses them or the user explicitly requests it.
swift
let tablesDB = TablesDB(client)
// Create database (server-side only)
let db = try await tablesDB.create(databaseId: ID.unique(), name: "My Database")
// Create row
let doc = try await tablesDB.createRow(databaseId: "[DATABASE_ID]", tableId: "[TABLE_ID]", rowId: ID.unique(), data: [
"title": "Hello",
"done": false
])
// Query rows
let results = try await tablesDB.listRows(databaseId: "[DATABASE_ID]", tableId: "[TABLE_ID]", queries: [
Query.equal("done", value: false),
Query.limit(10)
])
// Get row
let row = try await tablesDB.getRow(databaseId: "[DATABASE_ID]", tableId: "[TABLE_ID]", rowId: "[ROW_ID]")
// Update row
try await tablesDB.updateRow(databaseId: "[DATABASE_ID]", tableId: "[TABLE_ID]", rowId: "[ROW_ID]", data: ["done": true])
// Delete row
try await tablesDB.deleteRow(databaseId: "[DATABASE_ID]", tableId: "[TABLE_ID]", rowId: "[ROW_ID]")
String Column Types
Note: The legacy string type is deprecated. Use explicit column types for all new columns.
TypeMax charactersIndexingStorage
varchar16,383Full index (if size ≤ 768)Inline in row
text16,383Prefix onlyOff-page
mediumtext4,194,303Prefix onlyOff-page
longtext1,073,741,823Prefix onlyOff-page
  • varchar is stored inline and counts towards the 64 KB row size limit. Prefer for short, indexed fields like names, slugs, or identifiers.
  • text, mediumtext, and longtext are stored off-page (only a 20-byte pointer lives in the row), so they don't consume the row size budget. size is not required for these types.
swift
// Create table with explicit string column types
try await tablesDB.createTable(
databaseId: "[DATABASE_ID]",
tableId: ID.unique(),
name: "articles",
columns: [
["key": "title", "type": "varchar", "size": 255, "required": true],
["key": "summary", "type": "text", "required": false],
["key": "body", "type": "mediumtext", "required": false],
["key": "raw_data", "type": "longtext", "required": false],
]
)
Query Methods
swift
// Filtering
Query.equal("field", value: "value") // == (or pass array for IN)
Query.notEqual("field", value: "value") // !=
Query.lessThan("field", value: 100) // <
Query.lessThanEqual("field", value: 100) // <=
Query.greaterThan("field", value: 100) // >
Query.greaterThanEqual("field", value: 100) // >=
Query.between("field", start: 1, end: 100) // 1 <= field <= 100
Query.isNull("field") // is null
Query.isNotNull("field") // is not null
Query.startsWith("field", value: "prefix") // starts with
Query.endsWith("field", value: "suffix") // ends with
Query.contains("field", value: "sub") // contains
Query.search("field", value: "keywords") // full-text search (requires index)
// Sorting
Query.orderAsc("field")
Query.orderDesc("field")
// Pagination
Query.limit(25) // max rows (default 25, max 100)
Query.offset(0) // skip N rows
Query.cursorAfter("[ROW_ID]") // cursor pagination (preferred)
Query.cursorBefore("[ROW_ID]")
// Selection & Logic
Query.select(["field1", "field2"])
Query.or([Query.equal("a", value: 1), Query.equal("b", value: 2)]) // OR
Query.and([Query.greaterThan("age", value: 18), Query.lessThan("age", value: 65)]) // AND (default)
Query.relationship("comments", queries: [Query.equal("approved", value: true), Query.limit(25)]) // related documents
// Aggregations (optional alias)
Query.count("*", alias: "total")
Query.sum("amount", alias: "revenue")
Query.avg("score", alias: "avgScore")
Query.min("price", alias: "minPrice")
Query.max("price", alias: "maxPrice")
// Grouping
Query.groupBy(["status", "year"])
Query.having([Query.greaterThan("total", value: 1)])
Query.distinct()
// Joins (table id, left key, right key, operator, alias)
Query.join("orders", left: "$id", right: "customerId")
Query.leftJoin("orders", left: "$id", right: "customerId", operator: "=", alias: "ord")
Query.leftJoin("orders", alias: "ord", on: [
Query.on("$id", "customerId"),
Query.equal("ord.status", value: "paid"),
])
// Fluent builder. Pass build() into list methods.
let queries = Query.builder()
.equal("status", value: "published")
.leftJoin("orders", left: "$id", right: "customerId", operator: "=", alias: "ord")
.count("*", alias: "total")
.groupBy(["status"])
.limit(25)
.build()
_ = try await tablesDB.listRows(databaseId: "[DATABASE_ID]", tableId: "[TABLE_ID]", queries: queries)
File Storage
swift
let storage = Storage(client)
// Upload file
let file = try await storage.createFile(bucketId: "[BUCKET_ID]", fileId: ID.unique(), file: InputFile.fromPath("/path/to/file.png"))
// List files
let files = try await storage.listFiles(bucketId: "[BUCKET_ID]")
// Delete file
try await storage.deleteFile(bucketId: "[BUCKET_ID]", fileId: "[FILE_ID]")
InputFile Factory Methods
swift
InputFile.fromPath("/path/to/file.png") // from filesystem path
InputFile.fromData(data, filename: "file.png", mimeType: "image/png") // from Data
Teams
swift
let teams = Teams(client)
// Create team
let team = try await teams.create(teamId: ID.unique(), name: "Engineering")
// List teams
let list = try await teams.list()
// Create membership (invite user by email)
let membership = try await teams.createMembership(
teamId: "[TEAM_ID]",
roles: ["editor"],
email: "user@example.com"
)
// List memberships
let members = try await teams.listMemberships(teamId: "[TEAM_ID]")
// Update membership roles
try await teams.updateMembership(teamId: "[TEAM_ID]", membershipId: "[MEMBERSHIP_ID]", roles: ["admin"])
// Delete team
try await teams.delete(teamId: "[TEAM_ID]")
Role-based access: Use Role.team("[TEAM_ID]") for all team members or Role.team("[TEAM_ID]", "editor") for a specific team role when setting permissions.
Real-time Subscriptions (client-side)
swift
let realtime = Realtime(client)
// Subscribe to row changes
let subscription = try await realtime.subscribe(channels: [
Channel.tablesdb("[DATABASE_ID]").table("[TABLE_ID]").row()
]) { response in
print(response.events) // e.g. ["tablesdb.*.tables.*.rows.*.create"]
print(response.payload) // the affected resource
}
// Subscribe to multiple channels
let multi = try await realtime.subscribe(channels: [
Channel.tablesdb("[DATABASE_ID]").table("[TABLE_ID]").row(),
Channel.files(),
]) { response in /* ... */ }
// Cleanup
try await subscription.close()

Available channels:

ChannelDescription
accountChanges to the authenticated user's account
tablesdb.[DB_ID].tables.[TABLE_ID].rowsAll rows in a table
tablesdb.[DB_ID].tables.[TABLE_ID].rows.[ROW_ID]A specific row
buckets.[BUCKET_ID].filesAll files in a bucket
buckets.[BUCKET_ID].files.[FILE_ID]A specific file
teamsChanges to teams the user belongs to
teams.[TEAM_ID]A specific team
membershipsThe user's team memberships
functions.[FUNCTION_ID].executionsFunction execution updates

Response fields: events (array), payload (resource), channels (matched), timestamp (ISO 8601).

Serverless Functions (server-side)
swift
let functions = Functions(client)
// Execute function
let execution = try await functions.createExecution(functionId: "[FUNCTION_ID]", body: "{\"key\": \"value\"}")
// List executions
let executions = try await functions.listExecutions(functionId: "[FUNCTION_ID]")
Writing a Function Handler (Swift runtime)
swift
// Sources/main.swift — Appwrite Function entry point
func main(context: RuntimeContext) async throws -> RuntimeOutput {
// context.req.body — raw body (String)
// context.req.bodyJson — parsed JSON ([String: Any]?)
// context.req.headers — headers ([String: String])
// context.req.method — HTTP method
// context.req.path — URL path
// context.req.query — query params ([String: String])
context.log("Processing: \(context.req.method) \(context.req.path)")
if context.req.method == "GET" {
return context.res.json(["message": "Hello from Appwrite Function!"])
}
return context.res.json(["success": true]) // JSON
// context.res.text("Hello") // plain text
// context.res.empty() // 204
// context.res.redirect("https://...") // 302
}
Server-Side Rendering (SSR) Authentication

SSR apps using server-side Swift (Vapor, Hummingbird, etc.) use the server SDK to handle auth. You need two clients:

  • Admin client — uses an API key, creates sessions, bypasses rate limits (reusable singleton)
  • Session client — uses a session cookie, acts on behalf of a user (create per-request, never share)
swift
import Appwrite
// Admin client (reusable)
let adminClient = Client()
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1")
.setProject("[PROJECT_ID]")
.setKey(Environment.get("APPWRITE_API_KEY")!)
// Session client (create per-request)
let sessionClient = Client()
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1")
.setProject("[PROJECT_ID]")
if let session = req.cookies["a_session_[PROJECT_ID]"]?.string {
sessionClient.setSession(session)
}
Email/Password Login (Vapor)

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
11
7-day trend score
12

Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 23 Mar 2026, 7 months ago.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/appwrite/agent-skills/appwrite-swift/badge)](https://verified-skill.com/skills/appwrite/agent-skills/appwrite-swift)

Something wrong with this skill or its page? Tell us.