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 Type | Format |
|---|---|
image/jpeg | JPEG |
image/png | PNG |
image/heic | HEIC (Apple High Efficiency) |
image/heif | HEIF |
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)"
}
}
}
}
}
}