Installation
Add InsForge to your Swift Package Manager dependencies:
dependencies: [
.package(url: "https://github.com/insforge/insforge-swift.git", from: "0.0.9")
]
import InsForge
let insforge = InsForgeClient(
baseURL: URL(string: "https://your-app.insforge.app")!,
anonKey: "your-anon-key"
)
Enable Logging (Optional)
For debugging, you can configure the SDK log level and destination:
let options = InsForgeClientOptions(
global: .init(
logLevel: .debug,
logDestination: .osLog,
logSubsystem: "com.example.MyApp"
)
)
let insforge = InsForgeClient(
baseURL: URL(string: "https://your-app.insforge.app")!,
anonKey: "your-anon-key",
options: options
)
Log Levels:
| Level | Description |
|---|
.trace | Most verbose, includes all internal details |
.debug | Detailed information for debugging |
.info | General operational information (default) |
.warning | Warnings that don’t prevent operation |
.error | Errors that affect functionality |
.critical | Critical failures |
Log Destinations:
| Destination | Description |
|---|
.console | Standard output (print) |
.osLog | Apple’s unified logging system (recommended for iOS/macOS) |
.none | Disable logging |
.custom | Provide your own LogHandler factory |
Use .info or .error in production to avoid exposing sensitive data in logs.
connect()
Establish a WebSocket connection to the realtime server.
Example
do {
try await insforge.realtime.connect()
print("Connected to realtime server")
} catch {
print("Connection failed: \(error)")
}
subscribe()
Subscribe to a channel to receive messages.
Parameters
to (String) - Channel name (e.g., “orders:123”, “chat:room-1”)
onMessage (Closure) - Callback for receiving messages
Example
await insforge.realtime.subscribe(to: "chat:lobby") { message in
print("Event: \(message.eventName ?? "")")
print("Channel: \(message.channelName ?? "")")
if let payload = message.payload {
print("Data: \(payload)")
}
if let senderId = message.senderId {
print("From: \(senderId)")
}
}
unsubscribe()
Unsubscribe from a channel.
Example
await insforge.realtime.unsubscribe(from: "chat:lobby")
publish()
Publish a message to a channel.
Parameters
to (String) - Channel name
event (String) - Event name
payload ([String: Any]) - Message payload as dictionary
Example
try await insforge.realtime.publish(
to: "chat:lobby",
event: "message.new",
payload: [
"text": "Hello everyone!",
"author": currentUser.name,
"timestamp": Date().timeIntervalSince1970
]
)
disconnect()
Disconnect from the realtime server.
Example
await insforge.realtime.disconnect()
Channel API
The high-level Channel API provides a more structured way to work with realtime features including broadcast messages and Postgres changes.
channel()
Get or create a channel instance.
let channel = await insforge.realtime.channel("chat:lobby")
removeChannel()
Remove a channel.
await insforge.realtime.removeChannel("chat:lobby")
RealtimeChannel
subscribe()
Subscribe to the channel. Must be called before receiving messages.
let channel = await insforge.realtime.channel("chat:lobby")
try await channel.subscribe()
unsubscribe()
Unsubscribe from the channel.
await channel.unsubscribe()
Broadcast Messages
Listening for Broadcasts
Use broadcast(event:) to receive broadcast messages as an AsyncStream.
let channel = await insforge.realtime.channel("chat:lobby")
try await channel.subscribe()
// Listen for specific event
for await message in await channel.broadcast(event: "new_message") {
print("Event: \(message.event)")
print("Payload: \(message.payload)")
// Decode to typed struct
if let chatMessage = try? message.decode(ChatMessage.self) {
print("Message: \(chatMessage.text)")
}
}
// Listen for all events (wildcard)
for await message in await channel.broadcast(event: "*") {
print("Received: \(message.event)")
}
Sending Broadcasts
Send broadcast messages with typed or dictionary payloads.
// With Encodable struct
struct ChatMessage: Codable {
let text: String
let author: String
}
try await channel.broadcast(
event: "new_message",
message: ChatMessage(text: "Hello!", author: "John")
)
// With dictionary
try await channel.broadcast(
event: "typing",
message: ["userId": userId, "isTyping": true]
)
Postgres Changes
Listen for real-time database changes using typed actions.
Action Types
InsertAction<T> - New record inserted
UpdateAction<T> - Record updated (includes record and oldRecord)
DeleteAction<T> - Record deleted (includes oldRecord)
SelectAction<T> - Record selected
AnyAction<T> - Any of the above
Listening for Changes
struct Todo: Codable, Sendable {
let id: String
let title: String
let completed: Bool
}
let channel = await insforge.realtime.channel("db-changes")
try await channel.subscribe()
// Listen for inserts only
for await action in await channel.postgresChange(
InsertAction<Todo>.self,
schema: "public",
table: "todos"
) {
print("New todo: \(action.record.title)")
}
// Listen for any change
for await action in await channel.postgresChange(
AnyAction<Todo>.self,
schema: "public",
table: "todos"
) {
switch action {
case .insert(let insert):
print("Inserted: \(insert.record.title)")
case .update(let update):
print("Updated: \(update.record.title)")
case .delete(let delete):
print("Deleted: \(delete.oldRecord.title)")
case .select(let select):
print("Selected: \(select.record.title)")
}
}