Skip to main content

Image Ingest

BioSDK supports uploading images to the AnyBio platform alongside biosignal data. Images are associated with users and optionally with active sessions, enabling multimodal data capture — for example, photographing a skin condition while simultaneously recording EDA, or capturing wound images during a monitoring session.

Uploading Images

From a UIImage (iOS)

The simplest way to upload an image on iOS:

let image: UIImage = // from camera, photo picker, etc.
let userId: UUID = // the authenticated xUser ID

try await sdk.uploadImage(image, userId: userId)

This uses JPEG compression at 0.8 quality and automatically derives the device ID from the current device.

From Raw Data (Cross-Platform)

For more control, or when working with non-UIImage sources:

let imageData: Data = // PNG, JPEG, or HEIC bytes
let userId: UUID = // the authenticated xUser ID

try await sdk.uploadImageData(
imageData,
mimeType: "image/jpeg",
userId: userId,
deviceId: "optional-device-id" // nil = auto-generated
)

Supported Formats

MIME TypeFormat
image/jpegJPEG
image/pngPNG
image/heicHEIC (Apple High Efficiency)
image/heifHEIF

Querying Images

Retrieve previously uploaded images using ImageQueryClient:

let queryClient = ImageQueryClient(
baseURL: sdk.state.resolvedIngestBaseURL,
apiKey: sdk.state.organizationKey ?? ""
)

List Images

let filter = ImageQueryClient.ImageQueryFilter(
xuserId: "user-id",
sessionId: "session-id", // optional: scope to a session
dateRange: .last7Days, // optional: today, last7Days, last30Days, last90Days
limit: 50, // optional: pagination
offset: 0 // optional: pagination
)

let images: [BioImage] = try await queryClient.listImages(filter: filter)

for image in images {
print("\(image.id): \(image.mimeType), \(image.sizeBytes) bytes")
print(" Uploaded: \(image.uploadedAt)")

if let classifications = image.classifications {
for c in classifications {
print(" Classification: \(c.classification) (\(c.confidence))")
}
}
}

Get Image Metadata

let image: BioImage = try await queryClient.getImage(id: "image-id")

Download Image File

let data: Data = try await queryClient.downloadImage(id: "image-id")
let uiImage = UIImage(data: data)

The BioImage Model

public struct BioImage: Codable, Identifiable {
public let id: String
public let xuserId: String
public let sessionId: String?
public let deviceId: String?
public let capturedAt: Date?
public let uploadedAt: Date
public let mimeType: String
public let sizeBytes: Int
public let width: Int?
public let height: Int?
public let imageUrl: String?
public let thumbnailUrl: String?
public let classifications: [BioImageClassification]?
}

Image Classifications

When ML models are deployed on the AnyBio platform (via the Model Registry), uploaded images can be automatically classified. Results are attached to the BioImage:

public struct BioImageClassification: Codable {
public let id: String
public let imageId: String
public let classification: String // e.g., "rash", "healthy", "wound_stage_2"
public let confidence: Double // 0.0 – 1.0
public let processingEngine: String?
public let createdAt: Date
}

Session Association

Images uploaded during an active streaming session are automatically associated with that session via the sessionId field. This allows you to correlate images with the biosignal data captured at the same time — for example, viewing what ECG waveform was recording when a particular photo was taken.

Error Handling

do {
try await sdk.uploadImage(image, userId: userId)
} catch ImageError.compressionFailed {
// UIImage could not be compressed to the target format
} catch ImageError.uploadFailed {
// Upload request failed
} catch ImageError.server(let status, let body) {
// Server returned an error (e.g., 400, 413, 500)
} catch ImageError.network(let underlying) {
// Network connectivity issue
} catch {
print("Unexpected error: \(error)")
}

Example: Photo Capture with Session Context

A typical pattern — capture a photo while biosignal streaming is active:

import SwiftUI
import BioSDK

struct CaptureView: View {
let sdk: BioSDKClient
let userId: UUID
@State private var showCamera = false
@State private var uploadStatus: String?

var body: some View {
VStack {
Button("Capture Image") {
showCamera = true
}

if let status = uploadStatus {
Text(status)
.font(.caption)
.foregroundStyle(.secondary)
}
}
.sheet(isPresented: $showCamera) {
ImagePicker { image in
Task {
do {
try await sdk.uploadImage(image, userId: userId)
uploadStatus = "Uploaded successfully"
} catch {
uploadStatus = "Upload failed: \(error.localizedDescription)"
}
}
}
}
}
}