207 lines
5.8 KiB
Markdown
207 lines
5.8 KiB
Markdown
# DuooomiBleSDK (iOS)
|
||
|
||
纯原生 Swift BLE SDK,零第三方依赖。
|
||
|
||
## 集成
|
||
|
||
### CocoaPods
|
||
|
||
```ruby
|
||
pod 'DuooomiBleSDK', :git => 'https://gitea.bowong.cc/comi-logic/duooomi-ios-sdk.git', :branch => 'main'
|
||
```
|
||
|
||
然后执行 `pod install`。
|
||
|
||
### Swift Package Manager
|
||
|
||
```swift
|
||
// Package.swift
|
||
dependencies: [
|
||
.package(url: "https://gitea.bowong.cc/comi-logic/duooomi-ios-sdk.git", branch: "main")
|
||
]
|
||
```
|
||
|
||
## 初始化
|
||
|
||
```swift
|
||
let sdk = DuooomiBleSDK(config: .init(
|
||
apiKey: "your-api-key" // 必填
|
||
// apiHost: URL(...)!, // 默认 https://api.duooomi.com
|
||
// cdnHost: "https://cdn.bowong.cc/", // 默认
|
||
// firmwareIdentifier: "duomi", // 默认
|
||
// firmwareStatus: "DRAFT" // 默认
|
||
// aniWidth: 360, // ANI 转换宽度,默认 360
|
||
// aniHeight: 360, // ANI 转换高度,默认 360
|
||
// aniFps: "24", // ANI 转换帧率,默认 24
|
||
))
|
||
|
||
// 设置代理接收状态变化
|
||
sdk.delegate = self
|
||
```
|
||
|
||
## 代理(Delegate)
|
||
|
||
通过 `DuooomiBleSDKDelegate` 接收状态变化,所有方法在主线程调用,均有默认空实现:
|
||
|
||
```swift
|
||
extension ViewController: DuooomiBleSDKDelegate {
|
||
func sdk(_ sdk: DuooomiBleSDK, didChangeState state: ConnectionState) { }
|
||
func sdk(_ sdk: DuooomiBleSDK, didUpdateDevices devices: [DiscoveredDevice]) { }
|
||
func sdk(_ sdk: DuooomiBleSDK, didConnectDevice device: DiscoveredDevice?) { }
|
||
func sdk(_ sdk: DuooomiBleSDK, didUpdateDeviceInfo info: DeviceInfo?) { }
|
||
func sdk(_ sdk: DuooomiBleSDK, didUpdateVersion version: String) { }
|
||
func sdk(_ sdk: DuooomiBleSDK, didChangeActivation isActivated: Bool) { }
|
||
func sdk(_ sdk: DuooomiBleSDK, didUpdateProgress progress: Int) { }
|
||
func sdk(_ sdk: DuooomiBleSDK, didEncounterError error: String?) { }
|
||
}
|
||
```
|
||
|
||
## API
|
||
|
||
所有异步方法使用 `completion` 回调,返回 `Result<T, Error>`。
|
||
|
||
### 扫描
|
||
|
||
| 方法 | 说明 |
|
||
|------|------|
|
||
| `scan()` | 开始扫描,结果通过 delegate `didUpdateDevices` 回调 |
|
||
| `stopScan()` | 停止扫描 |
|
||
|
||
### 连接
|
||
|
||
```swift
|
||
sdk.connect(deviceId: deviceId) { result in
|
||
switch result {
|
||
case .success(let device): print("Connected: \(device.name ?? device.id)")
|
||
case .failure(let error): print("Failed: \(error)")
|
||
}
|
||
}
|
||
|
||
sdk.disconnect { result in
|
||
// ...
|
||
}
|
||
```
|
||
|
||
### 设备命令
|
||
|
||
```swift
|
||
sdk.getDeviceInfo { result in
|
||
if case .success(let info) = result {
|
||
print("Brand: \(info.brand), Power: \(info.powerlevel)%")
|
||
}
|
||
}
|
||
|
||
sdk.getVersion { result in
|
||
if case .success(let info) = result {
|
||
print("Version: \(info.version)")
|
||
}
|
||
}
|
||
|
||
sdk.bind(userId: "user-id") { result in
|
||
if case .success(let resp) = result {
|
||
print("SN: \(resp.sn), Files: \(resp.contents.count)")
|
||
}
|
||
}
|
||
|
||
sdk.unbind(userId: "user-id") { result in /* ... */ }
|
||
sdk.deleteFile(key: "file-key") { result in /* ... */ }
|
||
```
|
||
|
||
### 文件传输
|
||
|
||
```swift
|
||
// 一步完成:格式校验 → ANI 转换 → prepare → transfer
|
||
sdk.transferMedia(fileUrl: "https://example.com/video.mp4") { result in
|
||
switch result {
|
||
case .success: print("Transfer complete")
|
||
case .failure(let error): print("Transfer failed: \(error)")
|
||
}
|
||
}
|
||
// 进度通过 delegate didUpdateProgress 回调
|
||
```
|
||
|
||
**支持的媒体格式:** JPEG、PNG、GIF、MP4、WebM、WebP
|
||
|
||
格式校验规则:
|
||
- 优先从 URL path 提取扩展名(自动忽略查询参数)
|
||
- 无扩展名时通过 HEAD 请求检查 `Content-Type`
|
||
- 不支持的格式返回 `DuooomiBleError.unsupportedFormat`
|
||
|
||
### 固件升级
|
||
|
||
```swift
|
||
// 1. 查询最新固件
|
||
sdk.fetchLatestFirmware { result in
|
||
guard case .success(let info?) = result else { return }
|
||
|
||
// 2. 检查是否有新版本
|
||
let needUpdate = sdk.hasNewerFirmware(
|
||
deviceVersion: sdk.version,
|
||
serverVersion: info.version
|
||
)
|
||
|
||
// 3. OTA 升级
|
||
if needUpdate {
|
||
sdk.upgradeFirmware(fileUrl: info.fileUrl) { result in /* ... */ }
|
||
}
|
||
}
|
||
```
|
||
|
||
### 可读取状态
|
||
|
||
| 属性 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `btState` | `ConnectionState` | idle / scanning / connecting / connected / disconnecting / disconnected |
|
||
| `discoveredDevices` | `[DiscoveredDevice]` | 扫描到的设备列表 |
|
||
| `connectedDevice` | `DiscoveredDevice?` | 当前连接设备 |
|
||
| `deviceInfo` | `DeviceInfo?` | 设备信息 |
|
||
| `version` | `String` | 固件版本 |
|
||
| `isActivated` | `Bool` | 是否已绑定 |
|
||
| `transferProgress` | `Int` | 传输进度 0-100 |
|
||
| `error` | `String?` | 最近错误 |
|
||
|
||
### 数据类型
|
||
|
||
```swift
|
||
// FirmwareInfo — fetchLatestFirmware 返回
|
||
public struct FirmwareInfo {
|
||
let version: String // 版本号
|
||
let fileUrl: String // 固件下载地址
|
||
let description: String? // 描述
|
||
let fileSize: String? // 文件大小(字节字符串)
|
||
let fileMd5: String? // MD5 校验
|
||
let identifier: String? // 设备标识
|
||
let status: String? // DRAFT / PUBLISHED
|
||
}
|
||
|
||
// DeviceInfo — getDeviceInfo 返回
|
||
public struct DeviceInfo {
|
||
let name: String // 设备名
|
||
let brand: String // 品牌
|
||
let size: String // 屏幕尺寸
|
||
let powerlevel: Int // 电量百分比
|
||
let allspace: UInt64 // 总存储(字节)
|
||
let freespace: UInt64 // 可用存储(字节)
|
||
}
|
||
|
||
// BindingResponse — bind 返回
|
||
public struct BindingResponse {
|
||
let success: Int // 1=成功
|
||
let sn: String // 设备序列号
|
||
let contents: [String] // 设备文件 key 列表
|
||
}
|
||
```
|
||
|
||
## Info.plist
|
||
|
||
```xml
|
||
<key>NSBluetoothAlwaysUsageDescription</key>
|
||
<string>This app needs Bluetooth to communicate with your device</string>
|
||
```
|
||
|
||
## 技术规格
|
||
|
||
- iOS 12.2+ / Swift 5.0+ / 零依赖
|
||
- Delegate 回调模式,所有状态变化在主线程通知
|
||
- BLE 操作专用串行队列
|