SwiftPM

Swift local retrieval guide

Install RetrievalKit with SwiftPM, build a local corpus, choose a query path, and persist native state on Apple platforms.

macOS 14+ arm64 and iOS 15+ arm64View the v0.1.0 source guide →
On this page

Install

Add the signed v0.1.0 package once, then select the smallest product your app needs.

.package(
  url: "https://github.com/gungorbasa/RetrievalKit.git",
  from: "0.1.0"
)
  • RetrievalKit provides flat retrieval.
  • RetrievalKitGraph provides graph-only and graph-scoped retrieval.
  • EmbeddingKit is an independent local embedding provider.
  • RetrievalKitPipeline composes chunking, embedding, and indexing.

The published preview is qualified for macOS 14+ arm64 and iOS 15+ arm64 on physical devices and Apple-silicon simulators. Intel macOS and x86_64 iOS simulators are not claimed.

Build a retrieval database

The application owns document IDs, text, metadata, and embeddings. The first non-empty embedding fixes the database dimension.

import RetrievalKit

let builder = try RetrievalDatabase.Builder(
  corpusID: "project-notes",
  encoding: .f32
)

try await builder.upsert(
  Document(
    id: "decision-swift",
    text: "Apollo chose Swift for its Apple platform client.",
    metadata: [
      "project": .string("apollo"),
      "status": .string("approved"),
    ]
  ),
  embedding: [1, 0]
)

let database = try await builder.build()

Empty embeddings and dimension drift fail before the mutation is committed. Every document and query embedding in one database must come from the same model.

One method covers exact vector, BM25, and hybrid retrieval. The provided arguments choose the mode.

let vectorHits = try await database.search(
  embedding: queryEmbedding,
  limit: 10
)

let textHits = try await database.search(
  text: "private search",
  limit: 10
)

let hybridHits = try await database.search(
  text: "Why did we choose Swift?",
  embedding: queryEmbedding,
  alpha: 0.6,
  limit: 10,
  filter: .equals("project", .string("apollo"))
)

alpha is the vector weight. Use 1 for vector-only, 0 for BM25-only, or a value between them for hybrid ranking. Metadata filters are hard constraints.

Scope with relationships

Use GraphDatabase when traversal is the result and no retrieval is needed. Use GraphRetrievalDatabase when relationships should select candidates before the same exact ranker runs.

let selection = try await graphRetrievalDatabase.query(
  from: [GraphNodeID(nodeType: "Project", recordID: "apollo")],
  traversing: [GraphTraversal(relationship: "contains")]
)

let hits = try await graphRetrievalDatabase.search(
  text: "Why did we choose Swift?",
  embedding: queryEmbedding,
  alpha: 0.6,
  within: selection,
  limit: 1,
  filter: .equals("status", .string("approved"))
)

The graph chooses the eligible neighborhood. It does not add a hidden score.

Persist and reload

Native persistence publishes a complete, checksummed database generation.

let snapshot = URL(fileURLWithPath: "project-notes.rk")
try await database.save(to: snapshot)
try RetrievalDatabase.validate(at: snapshot)
let reloaded = try RetrievalDatabase.load(from: snapshot)

Use the corresponding static methods on GraphDatabase or GraphRetrievalDatabase for graph-capable snapshots.

Run the source quickstart

From the RetrievalKit repository root:

scripts/build-xcframework.sh --macos-only
scripts/run-swift-quickstart.sh base-retrieval

The expected first document ID is decision-swift.

Choose the database boundary

Three query paths

Compare the same job in Swift. These are separate APIs, not modes hidden behind one query.

01

Hybrid vector + BM25

RetrievalDatabase

Rank the whole corpus with exact vector similarity and BM25.

Swift
let hits = try await retrievalDatabase.search(
  text: "What did we decide about offline sync?",
  embedding: queryEmbedding,
  alpha: 0.6,
  limit: 5
)
02

Graph query alone

GraphDatabase

Select records by relationship. No embedding or retrieval ranker is involved.

Swift
let selection = try await graphDatabase.query(
  from: [GraphNodeID(
    nodeType: "Notebook",
    recordID: "product-research"
  )],
  traversing: [GraphTraversal(
    relationship: "references"
  )]
)
03

Graph + vector + BM25

GraphRetrievalDatabase

Select candidates with the graph, then rank only that scope with vector + BM25.

Swift
let selection = try await graphRetrievalDatabase.query(
  from: [GraphNodeID(
    nodeType: "Project",
    recordID: "mobile-app"
  )],
  traversing: [GraphTraversal(
    relationship: "contains"
  )]
)

let hits = try await graphRetrievalDatabase.search(
  text: "Why is cold start slow on Android?",
  embedding: queryEmbedding,
  alpha: 0.6,
  within: selection,
  limit: 5
)