CactusBrain Vision for iOS

Add the package, configure a project key, prepare a model, and run detection or OCR locally. Version 0.1.0.

iOS

Requirements

  • iOS 17 or later
  • Xcode 26 or later
  • An Apple-silicon Mac for development. The engine ships arm64 device and arm64 simulator slices; there is no x86_64 simulator slice.
iOS

1. Install

In Xcode, choose File → Add Package Dependencies and enter the package URL, or add it to Package.swift:

// Package.swift
dependencies: [
  .package(url: "https://github.com/cactusbrain/cactusbrain-swift", from: "0.1.0")
]

// Then add the product to your target:
.product(name: "CactusBrainVisionSDK", package: "cactusbrain-swift")

The inference engine is a dependency of the package. You do not download, link or version it separately.

iOS

2. Configure

import CactusBrainVisionSDK

let session = try await CactusBrainVisionSDK.configure(
  projectKey: projectKey
)

Keep the key out of source control. An .xcconfig that is gitignored, with a committed example file, works well and lets you rotate the key without touching code.

Where to get a key

Dashboard → your project → Quickstart. A live key begins cb_live_. It is displayed once.

iOS

3. Prepare a model

prepare resolves, downloads, verifies and installs the model your project is entitled to. It reports progress as it goes, and is a no-op once the model is installed.

let preparation = await session.prepare(.detect)

for try await event in preparation.events {
  // .checking, .downloading(received:total:), .installing
  update(event)
}

try await preparation.value  // throws if preparation failed

Call it before your first inference — typically at launch, or when the user first opens the feature that needs it, so a large download is tied to an action the user took.

iOS

4. Detect objects

let image = VisionImage(data: jpegData)
let output = try await session.detect(image)

for object in output.objects {
  print(object.label, object.confidence, object.boundingBox)
}

VisionImage takes encoded image bytes, so your app controls the conversion. Bake in EXIF orientation before encoding: if you do not, returned coordinates will be correct for the stored buffer but will not line up with the image as the user sees it.

iOS

5. Read text

let result = try await session.ocr(image)
print(result.text)

// Or read with a specific model:
let premium = try await session.ocr(image, using: .premium)

Two OCR models are available: a small fast English model, and a larger multilingual one. Selecting a model does not download it — it arrives when you prepare or run it, so a picker cannot start a large transfer nobody asked for.

iOS

Handling errors

do {
  try await preparation.value
} catch let error as ModelDeliveryError {
  switch error {
  case .notEntitled:
    // Retrying will not help. Check entitlements in the dashboard.
    showUpgradePath()
  case .network:
    showRetry()
  case .integrityCheckFailed:
    // The artifact was discarded rather than installed.
    showIntegrityFailure()
  case .missingCapability, .runtimeTooOld, .installedModelIncompatible:
    showUnsupportedDevice()
  default:
    showGenericFailure()
  }
} catch is CancellationError {
  // Your own cancellation, not a delivery failure.
}

Distinguish "not entitled" from "network failed". The first is a permanent answer and retrying is pointless; the second is worth a retry. Showing one message for both is the most common integration mistake.

iOS

Offline

// Models already on the device work with no network.
let installed = await session.installedModels()
let hasDetector = installed.contains { $0.family == .detect }

Inference needs no network. Check what is installed if you want to show an offline-ready state before any preparation runs.

iOS

Complete example

iOS sample application →

Back to the Vision overview →