Skip to main content
Swift SDK / MossSession

MossSession

An on-device index handle for a single index, returned by MossClient.session(_:options:). All embedding runs locally with the bundled model; queries don’t hit the network. A session can be persisted to disk (save / loadFromDisk) or synced to the cloud (pushIndex / loadIndex). The class is thread-safe. close() (also called on deinit) blocks until in-flight calls return before freeing the native handle.

Example

let session = try await client.session("notes")
defer { session.close() }

_ = try await session.addDocs([
  .init(id: "1", text: "first note"),
  .init(id: "2", text: "second note"),
])

let result = try await session.query("first")
result.docs.forEach { print($0.score, $0.id) }

Properties

name

var name: String
The index name this session was opened against.

docCount

var docCount: Int
Current document count in the index.

Methods

close()

func close()
Frees the native handle. Idempotent; also called on deinit.

addDocs(_:upsert:)

func addDocs(_ docs: [DocumentInfo], upsert: Bool = true) async throws -> (added: Int, updated: Int)
Adds or upserts documents, embedding them on-device. Returns the counts of rows added (new ids) and updated (existing ids). Takes [DocumentInfo].

deleteDocs(_:)

func deleteDocs(_ docIds: [String]) async throws -> Int
Deletes documents by id. Returns the number actually deleted (missing ids are ignored).

getDocs(_:)

func getDocs(_ docIds: [String]? = nil) async throws -> [DocumentInfo]
Returns documents by id, or all documents when docIds is nil. An empty array returns nothing. Returns [DocumentInfo].

query(_:options:)

func query(_ q: String, options: QueryOptions = QueryOptions()) async throws -> SearchResult
Embeds q on-device and runs a local similarity search. Tune with QueryOptions - hybrid alpha and metadata filtering are covered in the Querying guide. Returns a SearchResult.

query(_:embedding:options:)

func query(_ q: String, embedding: [Float]?, options: QueryOptions = QueryOptions()) async throws -> SearchResult
Search variant that takes a caller-provided embedding, bypassing the on-device model forward pass.

save(toCachePath:)

func save(toCachePath cachePath: String) async throws
Persists the session’s index to disk under cachePath so it can be reopened on the next launch without re-embedding.

loadFromDisk(cachePath:)

func loadFromDisk(cachePath: String) async throws -> Int
Restores a session previously written with save(toCachePath:). Returns the document count restored. The session’s name must match the one used at save time.
try await session.save(toCachePath: NSTemporaryDirectory())
session.close()

let restored = try await client.session("notes")
try await restored.loadFromDisk(cachePath: NSTemporaryDirectory())

pushIndex()

func pushIndex() async throws -> PushIndexResult
Pushes the in-memory session to the cloud as a server-side index. Returns a PushIndexResult with a jobId; poll MossClient.getJobStatus until the status is ready.

loadIndex(_:)

func loadIndex(_ indexName: String) async throws -> Int
Pulls a server-side index into this session as a one-time hydration (returns the doc count loaded, 0 if no such cloud index). The session then behaves as a local one - subsequent add/delete/query don’t hit the network.
let push = try await session.pushIndex()
while try await client.getJobStatus(push.jobId).status != "ready" {
  try await Task.sleep(nanoseconds: 1_000_000_000)
}

let restored = try await client.session(push.indexName)
_ = try await restored.loadIndex(push.indexName)
let hits = try await restored.query("how do transformers work", options: .init(topK: 3))