跳到主要内容

iOS API 接口参考

SDK Version: 1.0.0
Platform: iOS

所有带 @MainActor 的类型、属性和方法都应在 MainActor 上使用。默认参数以下列签名为准。

XTalkBleClient

@MainActor public final class XTalkBleClient: NSObject, ObservableObject
public override init()

每个 client 管理一个 BLE 生命周期和一条串行 AT/RF 通道。teardown() 后不可复用。

公开状态

属性类型含义
connectionStateXTalkConnectionState当前扫描/连接状态;只读、可通过 $connectionState 观察
scanResults[XTalkScanResult]当前扫描会话的设备列表
connectedNameString?已选/已连接设备名称
connectedAddressString?地址(平台不提供时为空)
connectedPeripheralIdUUID?当前 peripheral 标识
atReadyBoolpassthrough 写和通知是否已就绪
deviceControlReadyBool设备控制查询是否已就绪
atEncodingXTalkAtEncoding当前 AT 编码;默认 .xor
eventsAsyncStream<XTalkBleEvent>有界事件流;teardown() 时结束
onEvent(@MainActor (XTalkBleEvent) -> Void)?可选单一事件回调

连接与生命周期方法

方法前置条件结果/注意事项
startScan()client 未 teardown清空并持续更新扫描结果;失败发布 .failed
stopScan()停止扫描;扫描态回到 .idle
connect(id:)蓝牙可用,id 来自当前结果停止扫描并异步连接;结果由状态/事件发布
disconnect()取消连接和待处理事务,可再次扫描连接
teardown()终止扫描、连接、事务和事件流;幂等、不可逆

AT 与 RF 方法

public func setAtEncoding(_ encoding: XTalkAtEncoding)
public func runAtCommand(
_ plain: String,
timeoutMs: Int = 3_000,
log: Bool = true,
responseMode: XTalkAtResponseMode = .automatic
) async throws -> [String]
public func sendAtCommandNoWait(_ plain: String) throws
public func withExclusiveAtSession<T>(
_ operation: @MainActor (XTalkBleClient) async throws -> T
) async throws -> T
public func sendRfPayload(_ rawPayload: Data, timeoutMs: Int = 5_000) async throws
public func sendRfPayloadNoWait(_ rawPayload: Data) throws
方法输入返回/错误
setAtEncoding.plain.xor清理当前文本解码缓冲;不要在事务中途切换
runAtCommand不含业务外 framing 的 AT 字符串、正超时、响应模式返回响应行;可能抛连接、就绪、忙、超时、写入或取消错误
sendAtCommandNoWaitAT 字符串只启动写入;响应走事件/observer,通道隔离期间可抛 .busy
withExclusiveAtSession串行 async 闭包返回闭包结果;保证一组 AT 操作不被其他调用插入
sendRfPayload原始业务 payload等待完整发送结束;超时或断链时抛错
sendRfPayloadNoWait原始业务 payload只启动发送;完成走事件,隔离期间可抛 .busy

设备信息查询

public func fetchBatteryLevel(timeoutMs: Int = 2_000) async -> Int?
public func fetchBleFirmwareVersion(timeoutMs: Int = 2_000) async -> String?
public func fetchHardwareVersion(timeoutMs: Int = 2_000) async -> String?

这些便捷查询不抛错,失败返回 nil。调用前检查 deviceControlReady。电量是设备返回的整数;SDK 不承诺客户 UI 的范围或格式策略。版本字符串已去除首尾空白。

细粒度 observer

public func observeAtLines(_ handler: @escaping @MainActor (String) -> Void) -> UUID
public func removeAtLineObserver(_ id: UUID)
public func observeSendFinishLines(_ handler: @escaping @MainActor (String) -> Void) -> UUID
public func removeSendFinishLineObserver(_ id: UUID)
public func observePassthroughRaw(_ handler: @escaping @MainActor (Data) -> Void) -> UUID
public func removePassthroughRawObserver(_ id: UUID)

注册方法返回 token,移除方法只接受对应 token。observer 在 MainActor 回调;客户不要在回调中执行长时间阻塞工作。

扫描与连接模型

XTalkScanResult

public init(id: UUID, name: String, address: String?, rssi: Int)
public var displayName: String { get }

displayName 在地址存在时组合名称和地址,否则返回名称。id 用于 connect(id:)

XTalkConnectionState

.idle.scanning.connecting.connected.disconnected.failed(XTalkBleError)

XTalkBleError

.bluetoothUnavailable.permissionDenied.scanFailed(String).deviceNotFound(UUID).deviceMismatch(String).connectionFailed(String).serviceMissing.characteristicMissing.notConnected.notReady.busy.timeout.writeFailed(String).cancelled.malformedResponse(String).deviceControlFailed(String)

处理建议见错误与常见问题

AT、RF 与事件模型

  • XTalkAtEncoding.plain.xor
  • XTalkAtResponseMode.automatic 按命令策略结束;.collectUntilTimeout 收集完整超时窗口。
  • XTalkDiMeta:可选的 diCntlenslotsnrrssilocalSnrlocalRssiremoteSnrremoteRssitxp,初始化器所有参数默认 nil
  • XTalkBleEvent.connectionStateChanged(XTalkConnectionState):状态变化。
  • XTalkBleEvent.atLine(String):解析后的 AT 行。
  • XTalkBleEvent.sendFinished:发送完成。
  • XTalkBleEvent.diPayload(Data, XTalkDiMeta):业务 payload 与无线元数据。
  • XTalkBleEvent.crcError(XTalkDiMeta, String):CRC 错误元数据和原始行。
  • XTalkBleEvent.passthroughRaw(Data):未归类的原始透传数据。

DeviceAuthTransport

@MainActor public protocol DeviceAuthTransport: AnyObject {
var label: String { get }
var atEncoding: DeviceAuthAtEncoding { get }
func setAtEncoding(_ encoding: DeviceAuthAtEncoding)
func runAtCommand(
_ command: String,
timeoutMs: Int,
log: Bool,
responseMode: DeviceAuthResponseMode
) async throws -> [String]
}

DeviceAuthAtEncoding.plain.xorDeviceAuthResponseMode.automatic.collectFullWindow.recoverableEncodingProbe。后两种必须保留完整窗口语义;.recoverableEncodingProbe 在编码探测不确定时还要求下一个命令开始前通道已恢复干净。

完整 BLE adapter 见设备认证 SDK

XTalkDeviceAuthenticator

@MainActor public final class XTalkDeviceAuthenticator: ObservableObject {
@Published public private(set) var state: XTalkDeviceAuthState
public init(transport: any DeviceAuthTransport)
public func authenticate(
configuration: XTalkDeviceAuthConfiguration = XTalkDeviceAuthConfiguration()
) async throws -> XTalkDeviceAuthResult
public func cancel()
}

authenticate 自动探测编码、按需要执行 Challenge、读取身份并返回结果。同一实例只允许一个活动会话;失败会更新 .failed(error) 并抛出同一公开错误。cancel() 请求取消当前会话,没有活动会话时无操作。

认证配置、结果与状态

XTalkDeviceAuthConfiguration

public init(
probeTimeoutMs: Int = 800,
strictProbeTimeoutMs: Int = 1_200,
challengeTimeoutMs: Int = 4_000,
identityTimeoutMs: Int = 4_000,
maxChallengeAttempts: Int = 3
)

所有值必须大于 0,否则认证抛 .invalidConfiguration

XTalkDeviceAuthResult

identity: XTalkDeviceIdentityencoding: DeviceAuthAtEncodingdidRequireChallenge: Bool;公开初始化器接受相同三个参数。

XTalkDeviceAuthState

.idle.probing.challenging(attempt:maxAttempts:).readingIdentity.authenticated(XTalkDeviceIdentity).failed(XTalkDeviceAuthError).cancelled

XTalkDeviceAuthError

.busy.invalidConfiguration.transportUnavailable.commandTimedOut(String).secureRandomUnavailable.invalidChallenge.challengeMissing.malformedChallengeReply.invalidSignatureLength(Int).signatureVerificationFailed.challengeRetryExhausted.invalidDeviceIdentity.cancelled

设备身份与 DID 工具

XTalkDeviceIdentity

public init(
deviceID: UInt32,
did: String,
serial: String,
source: XTalkDeviceIdentitySource
)

source.efuseSn.sn。认证正常使用时直接消费返回的 identity,不要自行构造。

XTalkDeviceIDCodec

方法作用
canonicalize(_ raw: UInt32) -> UInt32规范化历史设备标识编码
fromSn(year: Int, week: Int, serial: UInt32) -> UInt32按协议位宽从 SN 字段构建设备标识
parse(_ raw: String) -> UInt32?解析十进制或 0x 十六进制文本并规范化
format(_ raw: UInt32) -> String输出规范的 0x 加 8 位大写十六进制文本

查看 API 覆盖矩阵