iOS SDK
Swift / iOS
Integrate Meridian chat completions into your native iOS app using URLSession and Codable models. Zero external dependencies — just Foundation.
Quickstart
import Foundation
// 1. Define request/response models
struct ChatMessage: Codable {
let role: String
let content: String
}
struct ChatRequest: Codable {
let model: String
let messages: [ChatMessage]
let stream: Bool
}
struct Choice: Codable {
let message: ChatMessage
}
struct ChatResponse: Codable {
let choices: [Choice]
}
// 2. Build and send the request
func complete(apiKey: String, prompt: String) async throws -> String {
let url = URL(string: "https://api.getnimbus.net/v1/chat/completions")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
let body = ChatRequest(
model: "meridian-1",
messages: [ChatMessage(role: "user", content: prompt)],
stream: false
)
request.httpBody = try JSONEncoder().encode(body)
let (data, _) = try await URLSession.shared.data(for: request)
let decoded = try JSONDecoder().decode(ChatResponse.self, from: data)
return decoded.choices.first?.message.content ?? ""
}Streaming
For real-time token delivery, set stream: true and consume the SSE response line-by-line with URLSession.bytes.
func streamComplete(apiKey: String, prompt: String) async throws {
let url = URL(string: "https://api.getnimbus.net/v1/chat/completions")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
let body = ChatRequest(
model: "meridian-1",
messages: [ChatMessage(role: "user", content: prompt)],
stream: true
)
request.httpBody = try JSONEncoder().encode(body)
let (bytes, _) = try await URLSession.shared.bytes(for: request)
for try await line in bytes.lines {
guard line.hasPrefix("data: ") else { continue }
let json = line.dropFirst(6)
if json == "[DONE]" { break }
if let data = json.data(using: .utf8),
let chunk = try? JSONDecoder().decode(ChatResponse.self, from: data),
let content = chunk.choices.first?.message.content {
print(content, terminator: "")
}
}
}Error Handling
struct APIError: Codable {
let error: ErrorDetail
struct ErrorDetail: Codable {
let message: String
let code: String
}
}
func safeComplete(apiKey: String, prompt: String) async -> Result<String, Error> {
do {
let result = try await complete(apiKey: apiKey, prompt: prompt)
return .success(result)
} catch {
// URLSession errors, decoding failures, and non-2xx
// responses all surface here. Inspect the status code
// from the HTTPURLResponse for rate-limit (429) or
// auth failures (401).
return .failure(error)
}
}