Skip to main content

Get Device Details

Read the information currently available on an AIBuds device. Device details are exposed as properties on the device object; there is no single getDeviceDetails request or DeviceDetails result model.

Use DeviceConvertible for identity, firmware, connection, and advertisement information. If the device also conforms to DeviceInfoAPI, you can read its battery status, reported capabilities, hardware configuration, language setting, call status, storage information, and media counts.

Prerequisites

Before reading device details:

  • Obtain a DeviceConvertible instance from your scan, stored-device, or connection flow.
  • Wait until the device is connected and ready when you need the latest device-reported values.
  • Treat optional properties as unavailable until the SDK or device has supplied them.

:::info Current snapshot Reading these properties does not send a Bluetooth command. The values represent the SDK's current snapshot and may come from discovery data, persisted device data, or information received during the active connection. :::

API Reference

Framework

AIBuds.xcframework

Import

In the files where you want to use the SDK, import the main framework:

Swift
import AIBuds

Protocol

Device details are exposed by two protocols. DeviceConvertible provides the base device snapshot. DeviceInfoAPI provides additional device-information properties when the connected device supports that protocol.

Swift
/// Defines the persistent identity and capabilities of an AIBuds device.
protocol DeviceConvertible: NSObjectProtocol, NSSecureCoding

/// The protocol for device information related API.
protocol DeviceInfoAPI: DeviceAPI

Properties

Base device properties

These properties are available through DeviceConvertible.

CategoryPropertiesNotes
Identityname, uuid, bluetoothName, macAddress, productThe device name and identifiers currently known to the SDK.
HardwaredeviceModel, deviceSerialNum, formatedProjNumberOptional values reported by supported devices.
FirmwarefirmwareVersion, formatedFirmwareVersion, coProcessorFirmwareVersionformatedFirmwareVersion is the display-oriented main firmware string used by the Demo.
ConnectionconnectionState, deviceState, isConnectedAndReady, isBusy, lastConnectTimeUse isConnectedAndReady before relying on live device state.
BindingbindUserId, userBindTime, isAlreadyUnbind, shouldAutoReconnectWhenAppLaunchBinding and reconnection state maintained by the SDK.
AdvertisementadvertisementDataString, advertisementRawData, manufacturerData, manufacturerHexDataString, timestampOfAdvertisementDataValues derived from the most recently received advertisement data.
Presentationthumbnail, screenName, customContentOptional values that can be used by the host application UI.

Device information properties

After confirming conformance to DeviceInfoAPI, the following additional snapshot values are available.

PropertyTypeDescription
batteryStatusInfoBatteryStatusModel?Real-time information for the device's battery components.
deviceCapabilitiesDeviceCapabilities?Normalized feature flags reported by the device, or nil until valid capability information is received.
hardwareConfigurationDeviceHardwareConfigurationPhysical input hardware and on-device guidance requirements reported for the device.
languageSettingDeviceLanguageThe current device language.
supportedLanguages[NSNumber]Raw DeviceLanguage values supported by the device.
callStatusCallStatusThe current call status.
storageInfoStorageInfoModel?Used and free storage values, in MB.
mediaCountInfoMediaCountInfoModel?Photo, video, and audio file counts.
isSupportAdjustRecordDurationBoolWhether maximum recording duration can be configured.
aiSolutionCapabilitiesAIBudsAISolutionCapabilitiesAI capabilities reported for the device.
coprocessorModelCoprocessorModelThe device's co-processor model.
imageEnhancementPostProcessingAlgorithmImageEnhancementPostProcessingAlgorithmImage-enhancement algorithm currently reported by the device; defaults to .general.
recommendedMaxVideoRecordingDurationOptions[NSNumber]Device-recommended maximum video-recording duration options in minutes; defaults to [1, 3, 9, 12].
recommendedMaxAudioRecordingDurationOptions[NSNumber]Device-recommended maximum audio-recording duration options in minutes; defaults to [30, 60, 120].
minimumBatteryLevelForMediaOperationsIntMinimum battery percentage for photo, video, audio, and file-transfer operations; defaults to 30. OTA uses separate rules.

Common status values

batteryStatusInfo may contain any component supported by the product:

BatteryComponentMeaning
.glassGlasses body
.leftEarbud / .rightEarbudLeft or right earbud
.chargingCaseCharging case
.mainSpeaker / .sideSpeakerMain or side speaker
.headphonesOver-ear headphones
.unknownComponent is unavailable or unrecognized

Use the fields on deviceCapabilities to decide whether to expose TWS, spatial audio, multipoint, ANC, the on-device voice assistant, bass engine, live streaming, Ximalaya, or the factory-test chirp. Do not infer these features from product alone. A nil value means that the SDK has not received valid capability information; it does not mean that every feature is unsupported.

hardwareConfiguration describes how the product can be operated:

PropertyMeaning
hasTouchInputThe device has a touch input surface.
hasPhysicalButtonInputThe device has physical button input.
requiresOnDeviceVoiceAssistantGuidanceThe host app should provide guidance for using the on-device voice assistant.

callStatus uses CallStatus:

ValueMeaning
.notInCallNo call is active.
.ringingAn incoming call is ringing.
.inCallA call is active.
.threeWayRingingA three-way call is ringing, when supported.
.aiChatThe device reports an AI conversation as its current call-channel activity.
.unknownCall state is unavailable or unrecognized.

Usage Examples

Read Device Details

The following examples follow the same approach as the SDK Demo's DeviceInfoDetailsController: read the base device properties first, then conditionally include DeviceInfoAPI properties.

Swift
import AIBuds

typealias DeviceDetail = (label: String, value: String)

func formattedDate(_ date: Date?, unavailable: String) -> String {
    guard let date else { return unavailable }

    let formatter = DateFormatter()
    formatter.dateStyle = .medium
    formatter.timeStyle = .medium
    return formatter.string(from: date)
}

func deviceDetails(for device: DeviceConvertible) -> [DeviceDetail] {
    let unavailable = "N/A"
    var details: [DeviceDetail] = [
        ("Device Name", device.name),
        ("UUID", device.uuid.uuidString),
        ("Bluetooth Name", device.bluetoothName ?? unavailable),
        ("MAC Address", device.macAddress ?? unavailable),
        ("Product", String(describing: device.product)),
        ("Device Model", device.deviceModel ?? unavailable),
        ("Serial Number", device.deviceSerialNum ?? unavailable),
        ("Firmware Version", device.formatedFirmwareVersion ?? unavailable),
        ("Co-processor Firmware", device.coProcessorFirmwareVersion ?? unavailable),
        ("Project Number", device.formatedProjNumber ?? unavailable),
        ("Last Connection", formattedDate(device.lastConnectTime, unavailable: unavailable)),
        ("Auto Reconnect", device.shouldAutoReconnectWhenAppLaunch ? "Yes" : "No"),
        ("Advertisement Data", device.advertisementDataString ?? unavailable),
        ("Manufacturer Data", device.manufacturerHexDataString ?? unavailable),
        (
            "Advertisement Timestamp",
            formattedDate(device.timestampOfAdvertisementData, unavailable: unavailable)
        ),
        ("Screen Name", device.screenName ?? unavailable),
        ("Custom Content", device.customContent ?? unavailable),
    ]

    guard let info = device as? DeviceInfoAPI else {
        return details
    }

    let supportedLanguages = info.supportedLanguages
        .compactMap { DeviceLanguage(rawValue: $0.intValue) }
        .map { String(describing: $0) }
        .joined(separator: ", ")

    details.append(contentsOf: [
        ("Battery Status", info.batteryStatusInfo?.description ?? unavailable),
        ("Device Capabilities", info.deviceCapabilities?.description ?? unavailable),
        ("Hardware Configuration", info.hardwareConfiguration.description),
        ("Language", String(describing: info.languageSetting)),
        ("Supported Languages", supportedLanguages.isEmpty ? unavailable : supportedLanguages),
        ("Call Status", String(describing: info.callStatus)),
        ("Storage", info.storageInfo?.description ?? unavailable),
        ("Media Count", info.mediaCountInfo?.description ?? unavailable),
        ("Adjustable Recording Duration", info.isSupportAdjustRecordDuration ? "Yes" : "No"),
        ("AI Capabilities", String(describing: info.aiSolutionCapabilities)),
        ("Co-processor Model", String(describing: info.coprocessorModel)),
        (
            "Image Enhancement",
            String(describing: info.imageEnhancementPostProcessingAlgorithm)
        ),
        ("Recommended Video Duration Options", info.recommendedMaxVideoRecordingDurationOptions.description),
        ("Recommended Audio Duration Options", info.recommendedMaxAudioRecordingDurationOptions.description),
        ("Minimum Media Battery", "\(info.minimumBatteryLevelForMediaOperations)%"),
    ])

    return details
}

Render the returned rows using your application's own view model and localization. The Demo uses a table view and converts enum values into localized display strings.

Refresh Storage or Media Information

storageInfo and mediaCountInfo are snapshot properties. If your screen requires a fresh value, request an update first and then read the corresponding property after the operation succeeds.

Swift
guard let info = device as? DeviceInfoAPI else { return }

info.requestQueryStorageInfo { success, error in
    guard success else {
        print(error?.localizedDescription ?? "Storage query failed")
        return
    }

    print(info.storageInfo?.description ?? "Storage information is unavailable")
}

Use requestQueryMediaCountInfo(_:) in Swift or requestQueryMediaCountInfoWithCompletion: in Objective-C when you need to refresh mediaCountInfo.

Error Handling

Property access itself does not return an asynchronous error. Explicit refresh operations report failures through their completion handlers. Handle unavailable information by:

  1. Checking device.isConnectedAndReady when live values are required.
  2. Confirming protocol conformance before reading DeviceInfoAPI properties.
  3. Handling optional properties without assuming every device model reports every value; treat a nil deviceCapabilities value as unknown rather than unsupported.
  4. Treating advertisement fields as the latest received advertisement snapshot.
  5. Handling success and error for explicit refresh operations such as storage or media-count queries.

Best Practices

  1. Check Protocol Conformance: Confirm DeviceInfoAPI support before reading its extended properties.

  2. Gate Features by Reported Values: Prefer the normalized flags in deviceCapabilities, the recommended recording-duration arrays, and minimumBatteryLevelForMediaOperations over product-name checks or hard-coded limits.

  3. Treat Values as a Snapshot: Do not assume every property was refreshed at the same time.

  4. Handle Optional Values: Display an unavailable state instead of inventing fallback device data.

  5. Refresh Only When Needed: Use the storage and media-count query methods when the screen requires current values.

  6. Localize Display Values: Convert products, languages, call status, and other enums into user-facing localized text.

Notes

  • Device capabilities and available fields vary by product and firmware. DeviceProduct.headphones identifies over-ear headphones, while BatteryComponent.headphones identifies their battery entry.
  • supportedLanguages contains NSNumber values that map to DeviceLanguage.rawValue.
  • StorageInfoModel reports usedSpaceInMB and freeSpaceInMB.
  • MediaCountInfoModel reports photoCount, videoCount, and audioCount.
  • Prefer model properties over parsing description when your UI needs individual values.