Skip to content

API Reference

Latisha edited this page Jan 10, 2026 · 2 revisions

API Reference

Core APIs and classes in LibDC-Swift.

Core Classes

CoreBluetoothManager

Central manager for BLE operations.

public class CoreBluetoothManager: ObservableObject

Properties

@Published public var discoveredPeripherals: [CBPeripheral]
@Published public var isScanning: Bool
@Published public var isRetrievingLogs: Bool
@Published public var connectedDevice: CBPeripheral?

Methods

// Start scanning for BLE devices
func startScanning(omitUnsupportedPeripherals: Bool = true)

// Stop scanning
func stopScanning()

// Connect to device
func connectToDevice(_ address: String) -> Bool

// Disconnect and cleanup
func close(clearDevicePtr: Bool = false)

DiveLogRetriever

Handles dive log download from connected devices.

public class DiveLogRetriever

Main Method

static func retrieveDiveLogs(
    from devicePtr: UnsafeMutablePointer<device_data_t>,
    device: CBPeripheral,
    viewModel: DiveDataViewModel,
    bluetoothManager: CoreBluetoothManager,
    onProgress: @escaping (Int, Int) -> Void,
    completion: @escaping (Bool) -> Void
)

Parameters:

  • devicePtr - Pointer to libdivecomputer device
  • device - Connected CBPeripheral
  • viewModel - View model to store dive data
  • bluetoothManager - BLE manager instance
  • onProgress - Callback for progress (current, total)
  • completion - Callback when done (success)

DiveDataViewModel

View model for managing dive data.

public class DiveDataViewModel: ObservableObject

Properties

@Published public var dives: [DiveData]
@Published public var progress: DownloadProgress
@Published public var status: String

Methods

// Get stored fingerprint for device
func getFingerprint(forDeviceType: String, serial: String) -> Data?

// Save fingerprint after successful download
func saveFingerprint(_ fingerprint: Data, deviceType: String, serial: String)

// Get last sync timestamp
func getFingerprintInfo(forDeviceType: String, serial: String) -> Date?

// Update progress
func updateProgress(_ progress: DownloadProgress)
func updateProgress(count: Int)

Data Models

DiveData

Complete dive information.

public struct DiveData: Identifiable {
    public let id: UUID
    public let number: Int
    public let datetime: Date

    // Depth data
    public var maxDepth: Double      // Maximum depth (meters)
    public var avgDepth: Double      // Time-weighted average depth
    public var divetime: TimeInterval // Total dive time (seconds)

    // Temperature data
    public var temperature: Double           // Minimum temperature
    public var surfaceTemperature: Double?
    public var minTemperature: Double?
    public var maxTemperature: Double?

    // Profile and tanks
    public var profile: [DiveProfilePoint]
    public var tankPressure: [Double]
    public var tanks: [Tank]?

    // Gas and deco
    public var gasMix: Int?
    public var gasMixCount: Int?
    public var diveMode: DiveMode?
    public var decoModel: DecoModel?
    public var decoStop: DecoStop?

    // Environment
    public var salinity: Double?
    public var atmospheric: Double?
    public var location: Location?

    // Sensors
    public var rbt: UInt32?              // Remaining bottom time
    public var heartbeat: UInt32?        // Heart rate
    public var bearing: UInt32?          // Compass heading
    public var setpoint: Double?         // CCR setpoint
    public var ppo2Readings: [(sensor: UInt32, value: Double)]
    public var cns: Double?              // CNS percentage
}

DiveProfilePoint

Single point in dive profile.

public struct DiveProfilePoint {
    public let time: TimeInterval    // Seconds since dive start
    public let depth: Double         // Depth in meters
    public let temperature: Double?  // Temperature in Celsius
    public let pressure: Double?     // Tank pressure in bar
    public let po2: Double?         // Partial pressure O2
    public let events: [DiveEvent]  // Events at this point
}

DiveEvent

Events during dive.

public enum DiveEvent {
    case ascent              // Ascent rate warning
    case violation           // Deco violation
    case decoStop           // Deco stop required
    case gasChange          // Gas change
    case bookmark           // User bookmark/marker
    case safetyStop(Bool)   // Safety stop (mandatory?)
    case ceiling            // Ceiling violation
    case po2                // PPO2 warning
    case deepStop           // Deep stop
}

DeviceConfiguration

Device-specific configuration.

public class DeviceConfiguration

Methods

// Open BLE device connection
static func openBLEDevice(name: String, deviceAddress: String) -> Bool

// Get device display name
static func getDeviceDisplayName(from name: String) -> String

// Check if device is supported
static func fromName(_ name: String) -> DeviceConfiguration?

Supported Models

static let supportedModels: [DeviceConfiguration]

Parser

GenericParser

Parses raw dive data.

public class GenericParser

Main Method

static func parse(
    family: dc_family_t,
    model: UInt32,
    diveNumber: Int,
    diveData: UnsafePointer<UInt8>,
    dataSize: Int
) throws -> DiveData

Returns: Parsed DiveData with all fields populated

Throws: ParserError if parsing fails

Fingerprint Storage

DeviceFingerprintStorage

Manages fingerprint persistence.

public class DeviceFingerprintStorage

Methods

// Get fingerprint for device
func getFingerprint(forDeviceType: String, serial: String) -> DeviceFingerprint?

// Save new fingerprint
func saveFingerprint(_ fingerprint: Data, deviceType: String, serial: String)

// Get all stored fingerprints
func loadFingerprints() -> [DeviceFingerprint]

DeviceFingerprint

Fingerprint data structure.

public struct DeviceFingerprint: Codable {
    public let id: UUID
    public let deviceType: String
    public let serial: String
    public let fingerprint: Data
    public let timestamp: Date
}

Constants

Dive Modes

DC_DIVEMODE_FREEDIVE    // Freediving mode
DC_DIVEMODE_GAUGE       // Gauge mode (no deco)
DC_DIVEMODE_OC          // Open circuit
DC_DIVEMODE_CCR         // Closed circuit rebreather
DC_DIVEMODE_SCR         // Semi-closed rebreather

Deco Models

DC_DECOMODEL_NONE       // No deco tracking
DC_DECOMODEL_BUHLMANN   // Bühlmann algorithm
DC_DECOMODEL_VPM        // VPM-B
DC_DECOMODEL_RGBM       // RGBM
DC_DECOMODEL_DCIEM      // DCIEM

Error Handling

Common Status Codes

DC_STATUS_SUCCESS       // Operation successful
DC_STATUS_DONE          // Enumeration complete
DC_STATUS_UNSUPPORTED   // Feature not supported
DC_STATUS_INVALIDARGS   // Invalid arguments
DC_STATUS_NOMEMORY      // Out of memory
DC_STATUS_PROTOCOL      // Protocol error
DC_STATUS_TIMEOUT       // Operation timed out
DC_STATUS_IO            // I/O error

Usage Examples

Full Download Flow

// 1. Initialize
let bleManager = CoreBluetoothManager.shared
let viewModel = DiveDataViewModel()

// 2. Scan and connect
bleManager.startScanning()
// ... user selects device ...
let connected = DeviceConfiguration.openBLEDevice(
    name: deviceName,
    deviceAddress: deviceUUID
)

// 3. Download with progress
guard let devicePtr = bleManager.openedDeviceDataPtr else { return }

DiveLogRetriever.retrieveDiveLogs(
    from: devicePtr,
    device: peripheral,
    viewModel: viewModel,
    bluetoothManager: bleManager,
    onProgress: { current, total in
        print("Progress: \(current+1)/\(total)")
    },
    completion: { success in
        if success {
            for dive in viewModel.dives {
                print("Dive \(dive.number): \(dive.maxDepth)m")
            }
        }
    }
)

Check for New Dives

// Check fingerprint before download
if let lastFingerprint = viewModel.getFingerprint(
    forDeviceType: "Peregrine TX",
    serial: "12345"
) {
    print("Last synced: \(viewModel.getFingerprintInfo(...))")
    // Will only download new dives
}

Access Profile Data

for dive in viewModel.dives {
    for point in dive.profile {
        print("\(point.time)s: \(point.depth)m @ \(point.temperature ?? 0)°C")

        // Check events at this point
        for event in point.events {
            switch event {
            case .bookmark:
                print("  📌 Bookmark")
            case .gasChange:
                print("  🫁 Gas change")
            case .decoStop:
                print("  ⚠️ Deco stop")
            default:
                break
            }
        }
    }
}