新增文件传输接口
authorliangzhenying <867174124@qq.com>
Fri, 7 Jun 2024 06:40:56 +0000 (14:40 +0800)
committerliangzhenying <867174124@qq.com>
Fri, 7 Jun 2024 06:40:56 +0000 (14:40 +0800)
16 files changed:
Doc/galaxy.lzma [new file with mode: 0644]
IOTBluetooth/IOTBluetooth/Example/AbilityViewController.swift
IOTBluetooth/IOTBluetooth/Example/Datas.swift
IOTBluetooth/IOTBluetooth/IOTBluetooth.xcodeproj/project.pbxproj
IOTBluetooth/IOTBluetooth/IOTBluetooth.xcodeproj/project.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate
IOTBluetooth/IOTBluetooth/IOTBluetooth/IBAbility.swift
IOTBluetooth/IOTBluetooth/IOTBluetooth/IBChecker.swift
IOTBluetooth/IOTBluetooth/IOTBluetooth/IBFileSender.swift [new file with mode: 0644]
IOTBluetooth/IOTBluetooth/IOTBluetooth/IBManager.swift
IOTBluetooth/IOTBluetooth/IOTBluetooth/IBParameter.swift
IOTBluetooth/IOTBluetooth/IOTBluetooth/Models/IBClock.swift
IOTBluetooth/IOTBluetooth/IOTBluetooth/Models/IBDeleteFile.swift [new file with mode: 0644]
IOTBluetooth/IOTBluetooth/IOTBluetooth/Models/IBDial.swift [new file with mode: 0644]
IOTBluetooth/IOTBluetooth/IOTBluetooth/Models/IBEpo.swift [new file with mode: 0644]
IOTBluetooth/IOTBluetooth/IOTBluetooth/Models/IBMp3.swift [new file with mode: 0644]
IOTBluetooth/IOTBluetooth/IOTBluetooth/Models/IBOta.swift [new file with mode: 0644]

diff --git a/Doc/galaxy.lzma b/Doc/galaxy.lzma
new file mode 100644 (file)
index 0000000..fb481b9
Binary files /dev/null and b/Doc/galaxy.lzma differ
index f390f9d..86a693c 100644 (file)
@@ -9,9 +9,9 @@ import UIKit
 import IOTBluetooth
 
 class AbilityViewController: BaseViewController {
-
+    
     @IBOutlet weak var listView: UITableView!
-       
+    
     override func viewDidLoad() {
         super.viewDidLoad()
         title = "已连接" + IBManager.currentConnected!.name
@@ -37,21 +37,28 @@ extension AbilityViewController: UITableViewDelegate, UITableViewDataSource {
     }
     
     func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
-        activityIndicatorView.startAnimating()
+        
         let data = datas[indexPath.row]
-        IBSender()
-            .ability(data.ability)
-            .parameters(data.parameters)
-            .response {[weak self]  result in
-                guard let self = self else {return}
-                if result.isSuccess{
-                    //请求成功
+        if data.label.isEqual("mp3"){
+//            IBFileSender().sendMp3(URL(fileURLWithPath: ""))
+        }
+        else{
+            activityIndicatorView.startAnimating()
+            IBSender()
+                .ability(data.ability)
+                .parameters(data.parameters)
+                .response {[weak self]  result in
+                    guard let self = self else {return}
+                    if result.isSuccess{
+                        //请求成功
+                    }
+                    else{
+                        //请求失败
+                    }
+                    print(result)
+                    activityIndicatorView.stopAnimating()
                 }
-                else{
-                    //请求失败
-                }
-                print(result)
-                activityIndicatorView.stopAnimating()
-            }
+        }
     }
+    
 }
index 566d552..429ff48 100644 (file)
@@ -41,7 +41,7 @@ let datas: [(ability: IBAbility, label: String, parameters: [IBParameter])] = [
     (.auxiliary, "设置手表辅助功能参数", [.auxiliary(.bloodOxygen)]),
     (.unit, "设置手表公英制单位", [.value(1)]),
     
-    (.sendWeather, "发送天气数据", [.weather(IBWeather())]),
+    
     (.disk, "获取SD卡剩余空间", []),
     (.unpair, "发送解除配对消息", []),
     (.sendUnpair, "发送取消解除配对消息", []),
@@ -86,8 +86,19 @@ let datas: [(ability: IBAbility, label: String, parameters: [IBParameter])] = [
     (.syncGPS, "同步路径坐标集历史数据", [.value(1654012800)]),
     (.sendSyncEnd, "发送同步数据结束消息", []),
     (.addressBook, "发送通讯录", [.addressBook([IBAddressBook()])]),
-
-//        (.revokeFileSend, "撤销当前文件传输", [.file(.mp3)]),
-//        (.fetchFiles, "获取指定类型所有文件", [.file(.mp3)]),
-//        (.deleteFiles, "删除指定类型所有文件", [.file(.mp3)]),
+    
+    (.epo, "发送EPO文件信息", [.epo(IBEpo())]),
+    (.ota, "发送OTA文件信息", [.ota(IBOta())]),
+    (.mp3, "发送MP3文件信息", [.MP3(IBMp3())]),
+    (.customDial, "发送自定义表盘文件汇总信息", [.customDial(IBCustomDial())]),
+    (.marketDial, "发送市场表盘文件汇总信息", [.marketDial(IBMarketDial())]),
+    (.dialInfo, "发送单个表盘文件信息", [.dialInfo(IBDialInfo())]),
+    (.fileCheckCode, "发送文件校验码", [.value(10)]),
+    
+    (.revokeFileSend, "撤销当前文件传输", [.file(.mp3)]),
+    (.deleteFile, "删除指定文件", [.deleteFile(IBDeleteFile())]),
+    (.deleteFiles, "删除指定类型所有文件", [.file(.mp3)]),
+    
+    
+    (.sendWeather, "发送天气数据", [.weather(IBWeather())]),
 ]
index 5ffed27..76bc46c 100644 (file)
                180B01982BFC831300524729 /* IBHistoryHeartRate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 180B01972BFC831300524729 /* IBHistoryHeartRate.swift */; };
                180B019E2BFC9CF400524729 /* IBHistoryBaseTraining.swift in Sources */ = {isa = PBXBuildFile; fileRef = 180B019D2BFC9CF400524729 /* IBHistoryBaseTraining.swift */; };
                180CE2652C0D728F00A7006E /* IBAddressBook.swift in Sources */ = {isa = PBXBuildFile; fileRef = 180CE2642C0D728F00A7006E /* IBAddressBook.swift */; };
+               181441CF2C11571400CCDD46 /* IBMp3.swift in Sources */ = {isa = PBXBuildFile; fileRef = 181441CE2C11571400CCDD46 /* IBMp3.swift */; };
+               181441D12C11575D00CCDD46 /* IBOta.swift in Sources */ = {isa = PBXBuildFile; fileRef = 181441D02C11575D00CCDD46 /* IBOta.swift */; };
+               181441D32C115AC500CCDD46 /* IBFileSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = 181441D22C115AC500CCDD46 /* IBFileSender.swift */; };
+               181441D52C116AE500CCDD46 /* IBDial.swift in Sources */ = {isa = PBXBuildFile; fileRef = 181441D42C116AE500CCDD46 /* IBDial.swift */; };
                184431322BF3720E00546E4E /* IBOtherTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 184431312BF3720E00546E4E /* IBOtherTarget.swift */; };
                1849DC8F2BEC8007002C2D2D /* IBVibrateSound.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1849DC8E2BEC8007002C2D2D /* IBVibrateSound.swift */; };
                1849DC912BECD131002C2D2D /* IBCode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1849DC902BECD131002C2D2D /* IBCode.swift */; };
                184B94CB2BF606CC0042BEB3 /* IBTrainTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 184B94CA2BF606CC0042BEB3 /* IBTrainTarget.swift */; };
                1859DFA02BFF5A2700112E8C /* IBSendTime.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1859DF9F2BFF5A2700112E8C /* IBSendTime.swift */; };
+               18884C442C11DBA300E01458 /* IBDeleteFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18884C432C11DBA300E01458 /* IBDeleteFile.swift */; };
+               18884C462C12A4EA00E01458 /* IBEpo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18884C452C12A4EA00E01458 /* IBEpo.swift */; };
                18993AA22C073FED006742D2 /* IBBloodOxygen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18993AA12C073FED006742D2 /* IBBloodOxygen.swift */; };
                189C15892C05E0CD00676A80 /* IBTarinState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 189C15882C05E0CD00676A80 /* IBTarinState.swift */; };
                189C158B2C05F27C00676A80 /* IBAbout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 189C158A2C05F27C00676A80 /* IBAbout.swift */; };
                180B01972BFC831300524729 /* IBHistoryHeartRate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IBHistoryHeartRate.swift; sourceTree = "<group>"; };
                180B019D2BFC9CF400524729 /* IBHistoryBaseTraining.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IBHistoryBaseTraining.swift; sourceTree = "<group>"; };
                180CE2642C0D728F00A7006E /* IBAddressBook.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IBAddressBook.swift; sourceTree = "<group>"; };
+               181441CE2C11571400CCDD46 /* IBMp3.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IBMp3.swift; sourceTree = "<group>"; };
+               181441D02C11575D00CCDD46 /* IBOta.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IBOta.swift; sourceTree = "<group>"; };
+               181441D22C115AC500CCDD46 /* IBFileSender.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IBFileSender.swift; sourceTree = "<group>"; };
+               181441D42C116AE500CCDD46 /* IBDial.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IBDial.swift; sourceTree = "<group>"; };
                184431312BF3720E00546E4E /* IBOtherTarget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IBOtherTarget.swift; sourceTree = "<group>"; };
                1849DC8E2BEC8007002C2D2D /* IBVibrateSound.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IBVibrateSound.swift; sourceTree = "<group>"; };
                1849DC902BECD131002C2D2D /* IBCode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IBCode.swift; sourceTree = "<group>"; };
                184B94CA2BF606CC0042BEB3 /* IBTrainTarget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IBTrainTarget.swift; sourceTree = "<group>"; };
                1859DF9F2BFF5A2700112E8C /* IBSendTime.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IBSendTime.swift; sourceTree = "<group>"; };
+               18884C432C11DBA300E01458 /* IBDeleteFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IBDeleteFile.swift; sourceTree = "<group>"; };
+               18884C452C12A4EA00E01458 /* IBEpo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IBEpo.swift; sourceTree = "<group>"; };
                18993AA12C073FED006742D2 /* IBBloodOxygen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IBBloodOxygen.swift; sourceTree = "<group>"; };
                189C15882C05E0CD00676A80 /* IBTarinState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IBTarinState.swift; sourceTree = "<group>"; };
                189C158A2C05F27C00676A80 /* IBAbout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IBAbout.swift; sourceTree = "<group>"; };
                                8A65F9602BAC0810005C1EA4 /* IBSimulateParser.swift */,
                                8A878FE12BA9444C008C7F26 /* IBParameter.swift */,
                                8A79D2242BA4278E0096A98C /* IBSender.swift */,
+                               181441D22C115AC500CCDD46 /* IBFileSender.swift */,
                                8A79D2262BA433330096A98C /* IBNotify.swift */,
                                8A9F6AC02BA04BE100DA520F /* IBManager.swift */,
                                8A0A39BE2B980BEF006A3B18 /* IOTBluetooth.h */,
                                18EFF59A2C080F14001B1E0E /* IBUserInfo.swift */,
                                18C9589A2C082FA7006A5DE8 /* IBWeather.swift */,
                                180CE2642C0D728F00A7006E /* IBAddressBook.swift */,
+                               181441CE2C11571400CCDD46 /* IBMp3.swift */,
+                               181441D02C11575D00CCDD46 /* IBOta.swift */,
+                               181441D42C116AE500CCDD46 /* IBDial.swift */,
+                               18884C452C12A4EA00E01458 /* IBEpo.swift */,
+                               18884C432C11DBA300E01458 /* IBDeleteFile.swift */,
                                1849DC902BECD131002C2D2D /* IBCode.swift */,
                        );
                        path = Models;
                                180B019E2BFC9CF400524729 /* IBHistoryBaseTraining.swift in Sources */,
                                8A87FBB52BAA85FB00096761 /* IBTrainingData.swift in Sources */,
                                8A878FE42BA94D09008C7F26 /* IBChecker.swift in Sources */,
+                               18884C442C11DBA300E01458 /* IBDeleteFile.swift in Sources */,
                                189C15892C05E0CD00676A80 /* IBTarinState.swift in Sources */,
                                8A76B60B2BA851730016F2AB /* IBParser.swift in Sources */,
                                18EFF59B2C080F14001B1E0E /* IBUserInfo.swift in Sources */,
                                8A65F9652BAC271B005C1EA4 /* IBScreen.swift in Sources */,
                                1859DFA02BFF5A2700112E8C /* IBSendTime.swift in Sources */,
                                8A65F9632BAC1018005C1EA4 /* IBTargetStep.swift in Sources */,
+                               181441D32C115AC500CCDD46 /* IBFileSender.swift in Sources */,
                                8A34B9252BA2A069000F66BD /* IBWatchInfo.swift in Sources */,
                                8A0A39D62B980EC9006A3B18 /* IBPeripheralUUID.swift in Sources */,
                                189C15952C05FFC700676A80 /* IBHistoryCalorie.swift in Sources */,
+                               181441CF2C11571400CCDD46 /* IBMp3.swift in Sources */,
                                8A9F6AC12BA04BE100DA520F /* IBManager.swift in Sources */,
                                18EC6E282BFF4C6D00757CA8 /* IBPhoneInfo.swift in Sources */,
                                18C9589F2C086A9D006A5DE8 /* IBHistorySleep.swift in Sources */,
                                18E7AC962BF5E39900CB9393 /* IBHeartRate.swift in Sources */,
                                18C9589B2C082FA7006A5DE8 /* IBWeather.swift in Sources */,
                                8A0A39D82B980F58006A3B18 /* UTF8.swift in Sources */,
+                               181441D12C11575D00CCDD46 /* IBOta.swift in Sources */,
                                18E7AC922BF44C6800CB9393 /* IBSleep.swift in Sources */,
                                8A0A39C62B980C88006A3B18 /* IBluetooth.swift in Sources */,
                                8A0A39CB2B980CFC006A3B18 /* Logger.swift in Sources */,
                                189C158F2C05F85200676A80 /* IBHistoryStep.swift in Sources */,
                                8A5822D12BA1C80700590AB6 /* LRC.swift in Sources */,
                                8A0A39DA2B981037006A3B18 /* Date.swift in Sources */,
+                               181441D52C116AE500CCDD46 /* IBDial.swift in Sources */,
                                18993AA22C073FED006742D2 /* IBBloodOxygen.swift in Sources */,
                                8A0A39CD2B980D53006A3B18 /* IBPeripheral.swift in Sources */,
+                               18884C462C12A4EA00E01458 /* IBEpo.swift in Sources */,
                                8A87FBB32BAA7F3900096761 /* IBLanguage.swift in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
index 69bbb2d..d9462a7 100644 (file)
Binary files a/IOTBluetooth/IOTBluetooth/IOTBluetooth.xcodeproj/project.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate and b/IOTBluetooth/IOTBluetooth/IOTBluetooth.xcodeproj/project.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate differ
index a7565fc..cb5c81d 100644 (file)
@@ -9,7 +9,7 @@ import Foundation
 
 /// 功能指令
 public class IBAbility {
-   
+    
     /// 命令类型
     let type: `Type`
     
@@ -168,7 +168,7 @@ public extension IBAbility {
     /// 最高不超过 250 ,如果需要关闭最高心率提醒,可将最高心率设为255,开启则设正常值即可。
     static let heartRateHigh = IBAbility.short.id(0x15).parser(IBGeneralParser.self).checker(IBHeartRateHighChecker.self)
     
-    /// 手势拍照 
+    /// 手势拍照
     /// - Parameter action:
     ///   0 = 退出手势拍照 \
     ///   1 = 进入手势拍照
@@ -204,7 +204,7 @@ public extension IBAbility {
     
     /// APP获取某表盘ID是否已安装
     /// - Parameter value:Int
-    /// - Returns: Int  
+    /// - Returns: Int
     ///      1 = 已安装 \
     ///      2 = 未安装   \
     ///   Read from ``IBResponse``.value
@@ -338,7 +338,7 @@ public extension IBAbility {
     /// - Returns: [IBHistoryBurningItem]  \
     /// Read from ``IBResponse``.items
     static let syncFatBurning = IBAbility.short.id(0x44).parser(IBSyncBurningParser.self).checker(IBValueChecker.self)
-
+    
     /// 同步站立历史数据
     /// - Parameter value:
     ///   0 = 今天    \
@@ -393,7 +393,7 @@ public extension IBAbility {
     /// - Returns: [IBHistorySleepItem]  \
     /// Read from ``IBResponse``.items
     static let syncSleep = IBAbility.short.id(0x4B).parser(IBSyncSleepParser.self).checker(IBValueChecker.self)
- 
+    
     /// 同步路径坐标集历史数据
     /// - Parameter value:开始训练时间戳
     /// - Returns: [IBHistoryGpsItem]  \
@@ -431,75 +431,87 @@ public extension IBAbility {
     /// - Parameter weather: see ``IBWeather``
     static let sendWeather = IBAbility.long.id(0x20).parser(IBGeneralParser.self).checker(IBWeatherChecker.self)
     
-    /// APP发送通讯录
+    /// 发送通讯录
     /// - Parameter addressBook: see ``IBAddressBook``
-    /// 0~20
+    /// 联系人个数0~20
     static let addressBook = IBAbility.long.id(0x0B).parser(IBGeneralParser.self).checker(IBAddressBookChecker.self)
     
-//    /// 撤销当前文件传输
-//    static let revokeFileSend = IBAbility.short.id(0x20).parser(IBGeneralParser.self).checker(IBFileChecker.self)
-//    /// 获取指定类型所有文件(当前只支持 MP3 和 表盘)
-//     static let fetchFiles = IBAbility.short.id(0x21).parser(IBGeneralParser.self).checker(IBFileChecker.self)
-//    /// 删除指定类型所有文件(当前只支持 MP3 和 表盘)
-//    static let deleteFiles = IBAbility.short.id(0x22).parser(IBGeneralParser.self).checker(IBFileChecker.self)
-//
-//
+    // MARK: - 文件
+    
+    /// 发送MP3文件信息
+    /// - Parameter mp3: see ``IBMp3``
+    static let mp3 = IBAbility.file.id(0x21).parser(IBGeneralParser.self).checker(IBMp3Checker.self)
+    
+    /// 发送自定义表盘文件汇总信息
+    /// - Parameter customDial: see ``IBCustomDail``
+    static let customDial = IBAbility.file.id(0x22).parser(IBGeneralParser.self).checker(IBCustomDialChecker.self)
+    
+    /// 发送市场表盘文件汇总信息
+    /// - Parameter marketDial: see ``IBMarketDail``
+    static let marketDial = IBAbility.file.id(0x22).parser(IBGeneralParser.self).checker(IBMarketDialChecker.self)
+    
+    /// 发送单个表盘文件信息
+    /// - Parameter dialInfo: see ``IBDailInfo``
+    static let dialInfo = IBAbility.file.id(0x24).parser(IBGeneralParser.self).checker(IBDialInfoChecker.self)
+    
+    /// 发送文件校验码
+    /// - Parameter value:Int
+    static let fileCheckCode = IBAbility.file.id(0x23).parser(IBGeneralParser.self).checker(IBValueChecker.self)
+    
+    /// 删除指定文件
+    /// - Parameter deleteFile: see ``IBDeleteFile``
+    static let deleteFile = IBAbility.long.id(0x22).parser(IBGeneralParser.self).checker(IBDeleteFileChecker.self)
+    
+    /// 删除指定类型所有文件(当前只支持 MP3 和 表盘)
+    /// - Parameter file: see ``IBFile``
+    static let deleteFiles = IBAbility.short.id(0x22).parser(IBGeneralParser.self).checker(IBFileChecker.self)
+    
+    /// 发送OTA文件信息
+    /// - Parameter ota: see ``IBOta``
+    static let ota = IBAbility.file.id(0x20).parser(IBGeneralParser.self).checker(IBOtaChecker.self)
+    
+
+    /// 发送EPO文件信息
+    /// - Parameter epo: see ``IBEpo``
+    static let epo = IBAbility.file.id(0x28).parser(IBGeneralParser.self).checker(IBEpoChecker.self)
+    
+    /// 撤销当前文件传输
+    /// - Parameter file: see ``IBFile``
+    static let revokeFileSend = IBAbility.short.id(0x20).parser(IBGeneralParser.self).checker(IBFileChecker.self)
+    
+    //    /// 获取指定类型所有文件(当前只支持 MP3 和 表盘)
+    //     static let fetchFiles = IBAbility.short.id(0x21).parser(IBGeneralParser.self).checker(IBFileChecker.self)
 }
 
 extension IBAbility {
-
-
-//    
-//    // MARK: - Fetch 获取数据
-
-//    /// 撤销当前文件传输
-//    static let revokeFileTransfer = IBAbility.short.id(0x20)
-
-//    /// 删除指定文件(数据包为文件索引号)
-//    static let deleteFile = IBAbility.long.id(0x22)
-
-
-//    
-//    
-//    /// 发送OTA文件信息
-//    static let ota = IBAbility.file.id(0x20)
-//    /// 发送MP3文件信息
-//    static let mp3 = IBAbility.file.id(0x21)
-//    /// 发送表盘文件信息
-//    static let dial = IBAbility.file.id(0x22)
-//    /// APP发送文件校验码
-//    static let fileCheckCode = IBAbility.file.id(0x23)
-//    ///  发送单个表盘文件信息
-//    static let dialInfo = IBAbility.file.id(0x24)
-//    /// 发送EPO文件信息(04,25)
-//    static let epo = IBAbility.file.id(0x28)
-//    
-//    
-//    // MARK: - 私有
-
-//    
-//    /// 获取当前数据(jSON格式)【不使用】
-//    static let var681B9E92 = IBAbility.short.id(0x06)
-//    /// 开关多媒体功能(播放手机音乐、通话等)【不使用】
-//    static let var681254AC = IBAbility.short.id(0x09)
-//    /// 进入工厂测试模式【不使用】
-//    static let varD3D21DC8 = IBAbility.short.id(0x30)
-//    /// 同步压力历史数据【不使用】
-//    static let varA2A25CD8 = IBAbility.short.id(0x42)
-//    
-//    /// 修改手表蓝牙名称【未使用】
-//    static let var8FA46D73 = IBAbility.long.id(0x03)
-//    /// 同步基础训练实时心率记录【不使用】
-//    static let var6CFBF636 = IBAbility.long.id(0x4B)
-//    /// 同步当天任意时间之后的基础训练记录【不使用】
-//    static let var4D0264A9 = IBAbility.long.id(0x4D)
-//    /// APP发送靶心率区间值给手表(暂不用)
-//    static let var7EE39B21 = IBAbility.long.id(0x0C)
-//    
-//    /// 发送模块升级信息(04,26)【不使用】
-//    static let var1FFA68BC = IBAbility.file.id(0x26)
-//    ///  发送模块单个文件升级信息(04,27)【不使用】
-//    static let var9AD723C3 = IBAbility.file.id(0x27)
-//    /// 发送EPO文件信息(04,25)(旧版,不用)
-//    static let var4F791698 = IBAbility.file.id(0x25)
+    
+    //
+    //
+    //    // MARK: - 私有
+    
+    //
+    //    /// 获取当前数据(jSON格式)【不使用】
+    //    static let var681B9E92 = IBAbility.short.id(0x06)
+    //    /// 开关多媒体功能(播放手机音乐、通话等)【不使用】
+    //    static let var681254AC = IBAbility.short.id(0x09)
+    //    /// 进入工厂测试模式【不使用】
+    //    static let varD3D21DC8 = IBAbility.short.id(0x30)
+    //    /// 同步压力历史数据【不使用】
+    //    static let varA2A25CD8 = IBAbility.short.id(0x42)
+    //
+    //    /// 修改手表蓝牙名称【未使用】
+    //    static let var8FA46D73 = IBAbility.long.id(0x03)
+    //    /// 同步基础训练实时心率记录【不使用】
+    //    static let var6CFBF636 = IBAbility.long.id(0x4B)
+    //    /// 同步当天任意时间之后的基础训练记录【不使用】
+    //    static let var4D0264A9 = IBAbility.long.id(0x4D)
+    //    /// APP发送靶心率区间值给手表(暂不用)
+    //    static let var7EE39B21 = IBAbility.long.id(0x0C)
+    //
+    //    /// 发送模块升级信息(04,26)【不使用】
+    //    static let var1FFA68BC = IBAbility.file.id(0x26)
+    //    ///  发送模块单个文件升级信息(04,27)【不使用】
+    //    static let var9AD723C3 = IBAbility.file.id(0x27)
+    //    /// 发送EPO文件信息(04,25)(旧版,不用)
+    //    static let var4F791698 = IBAbility.file.id(0x25)
 }
index 43f0f55..b30715a 100644 (file)
@@ -95,6 +95,22 @@ struct IBFileChecker: IBChecker {
         return [value.rawValue.byte]
     }
 }
+struct IBOtaChecker: IBChecker {
+    static func check(_ parameters: [IBParameter]) -> [UInt8] {
+        guard case let .ota(value) = parameters[.ota] else { fatalError("缺少参数: ota") }
+        guard let data = value.encode else { fatalError("json解析异常: ota") }
+        Logger.log(value.jsonString ?? "")
+        return data.bytes
+    }
+}
+struct IBEpoChecker: IBChecker {
+    static func check(_ parameters: [IBParameter]) -> [UInt8] {
+        guard case let .epo(value) = parameters[.epo] else { fatalError("缺少参数: epo") }
+        guard let data = value.encode else { fatalError("json解析异常: epo") }
+        Logger.log(value.jsonString ?? "")
+        return data.bytes
+    }
+}
 
 struct IBTargetStepChecker: IBChecker {
     static func check(_ parameters: [IBParameter]) -> [UInt8] {
@@ -289,3 +305,64 @@ struct IBAddressBookChecker: IBChecker {
     }
 }
 
+// MARK: - 文件传输
+struct IBMp3Checker: IBChecker {
+    static func check(_ parameters: [IBParameter]) -> [UInt8] {
+        guard case let .MP3(value) = parameters[.mp3] else { fatalError("缺少参数: MP3") }
+        guard let data = value.encode else { fatalError("json解析异常: MP3") }
+        Logger.log(value.jsonString ?? "")
+        return data.bytes
+    }
+}
+struct IBCustomDialChecker: IBChecker {
+    static func check(_ parameters: [IBParameter]) -> [UInt8] {
+        guard case let .customDial(value) = parameters[.customDial] else { fatalError("缺少参数: customDial") }
+        Logger.log(value.description)
+        let data = value.UID.byte2 + [value.batteryStyle.byte] + [value.timeStyle.byte] + [value.timeColor.byte] + [value.numberOfFiles.byte]
+        return data
+    }
+}
+struct IBMarketDialChecker: IBChecker {
+    static func check(_ parameters: [IBParameter]) -> [UInt8] {
+        guard case let .marketDial(value) = parameters[.marketDial] else { fatalError("缺少参数: marketDial") }
+        Logger.log(value.description)
+        var data = value.UID.byte2
+        if let name = value.theme?.data(using: .utf8),!name.isEmpty  {
+            data += [name.count.byte]
+            data += name
+        }
+        else{
+            data += [0.byte]
+        }
+        data += [value.numberOfFiles.byte]
+        return data
+    }
+}
+struct IBDialInfoChecker: IBChecker {
+    static func check(_ parameters: [IBParameter]) -> [UInt8] {
+        guard case let .dialInfo(value) = parameters[.dialInfo] else { fatalError("缺少参数: marketDial") }
+        Logger.log(value.description)
+        var data = value.UID.byte2 + [value.number.byte] + [value.fileType.byte]
+        if let name = value.fileName.data(using: .utf8),!name.isEmpty  {
+            data += [name.count.byte]
+            data += name
+        }
+        else{
+            data += [0.byte]
+        }
+        data += value.fizeSize.byte4
+        return data
+    }
+}
+
+struct IBDeleteFileChecker: IBChecker {
+    static func check(_ parameters: [IBParameter]) -> [UInt8] {
+        guard case let .deleteFile(value) = parameters[.deleteFile] else { fatalError("缺少参数: deleteFile") }
+        Logger.log(value.description)
+        var data = [value.uids.count.byte] + [value.fileType.byte]
+        for uid in value.uids {
+            data += uid.byte2
+        }
+        return data
+    }
+}
diff --git a/IOTBluetooth/IOTBluetooth/IOTBluetooth/IBFileSender.swift b/IOTBluetooth/IOTBluetooth/IOTBluetooth/IBFileSender.swift
new file mode 100644 (file)
index 0000000..bb776e8
--- /dev/null
@@ -0,0 +1,37 @@
+//
+//  IBFileSender.swift
+//  IOTBluetooth
+//
+//  Created by incar on 2024/6/6.
+//
+
+import Foundation
+
+
+public class IBFileSender {
+    
+    
+    public init() {
+        
+    }
+    
+//    public func sendMp3(_ filePath:URL){
+////        let data = Data(filePath)
+//        let model = IBMp3()
+//        
+//        IBSender()
+//            .ability(.mp3)
+//            .parameters([.MP3(model)])
+//            .response {[weak self]  result in
+//                guard let self = self else {return}
+//                if result.isSuccess{
+//                    //请求成功
+//                }
+//                else{
+//                    //请求失败
+//                }
+//                print(result)
+//
+//            }
+//    }
+}
index bf98a16..3d8f214 100644 (file)
@@ -31,7 +31,7 @@ public class IBManager {
 
 public extension IBManager {
     /// SDK 版本号
-    static let version: String = "1.0.7"
+    static let version: String = "1.0.8"
     /// 默认为 false
     static var isDebug: Bool = false {
         didSet { Logger.isDebug = isDebug }
index 23dfa2e..b10eb73 100644 (file)
@@ -30,6 +30,13 @@ enum IBKey: String {
     case userInfo = "userInfo"
     case weather = "weather"
     case addressBook = "addressBook"
+    case epo = "epo"
+    case ota = "ota"
+    case mp3 = "mp3"
+    case customDial = "customDial"
+    case marketDial = "marketDial"
+    case dialInfo = "dialInfo"
+    case deleteFile = "deleteFile"
 }
 
 /// 参数
@@ -78,6 +85,20 @@ public enum IBParameter {
     case weather(IBWeather)
     /// 发送通讯录
     case addressBook([IBAddressBook])
+    /// 发送EPO文件信息
+    case epo(IBEpo)
+    /// 发送OTA文件信息
+    case ota(IBOta)
+    /// 发送mp3文件信息
+    case MP3(IBMp3)
+    /// 发送自定义表盘信息汇总
+    case customDial(IBCustomDial)
+    /// 发送表盘市场信息汇总
+    case marketDial(IBMarketDial)
+    /// 发送单个表盘文件信息
+    case dialInfo(IBDialInfo)
+    /// 删除指定文件
+    case deleteFile(IBDeleteFile)
     
     var key: IBKey {
         switch self {
@@ -103,6 +124,14 @@ public enum IBParameter {
         case .userInfo(_): return .userInfo
         case .weather(_): return .weather
         case .addressBook(_): return .addressBook
+        case .epo(_): return .epo
+        case .ota(_): return .ota
+        case .MP3(_): return .mp3
+        case .customDial(_): return .customDial
+        case .marketDial(_): return .marketDial
+        case .dialInfo(_): return .dialInfo
+        case .deleteFile(_): return .deleteFile
+            
         }
     }
 }
@@ -123,10 +152,10 @@ public enum IBFile: Int {
     case mp3
     /// 表盘信息
     case dial
-    /// 天气
-    case weather
-    /// 闹钟
-    case clock
+    /// OTA(W4)
+    case ota_w4
+    ///EPO
+    case epo
 }
 //0:运动
 //1:心率
index 7b12f33..600d82b 100644 (file)
@@ -12,7 +12,17 @@ public class IBClock: Codable {
     /// 闹钟列表
     public var alarms: [IBClockInfo] = []
 
-    public init() { }
+    public init() { 
+//        for i in 0...4{
+//            let model = IBClockInfo()
+//            model.id = i
+//            model.hour = i*3
+//            model.minute = i*10
+//            model.enable = i%2
+//            model.repeat = [1,2,3,4,5,6,7]
+//            alarms.append(model)
+//        }
+    }
 }
 
 /// 闹钟信息模型
diff --git a/IOTBluetooth/IOTBluetooth/IOTBluetooth/Models/IBDeleteFile.swift b/IOTBluetooth/IOTBluetooth/IOTBluetooth/Models/IBDeleteFile.swift
new file mode 100644 (file)
index 0000000..eeac194
--- /dev/null
@@ -0,0 +1,22 @@
+//
+//  IBDeleteFile.swift
+//  IOTBluetooth
+//
+//  Created by incar on 2024/6/6.
+//
+
+import Foundation
+
+/// 删除文件模型
+public class IBDeleteFile:Codable {
+    /// 文件类型,2:MP3   3:表盘
+    public var fileType: Int = 2
+    /// 文件UID,文件唯一编号。一次最多5个
+    public var uids: [Int] = []
+
+    public init() { }
+    
+    public var description: String  {
+        return "IBDeleteFile(fileType: \(fileType), uids:\(uids))"
+    }
+}
diff --git a/IOTBluetooth/IOTBluetooth/IOTBluetooth/Models/IBDial.swift b/IOTBluetooth/IOTBluetooth/IOTBluetooth/Models/IBDial.swift
new file mode 100644 (file)
index 0000000..cb5dea1
--- /dev/null
@@ -0,0 +1,67 @@
+//
+//  IBDail.swift
+//  IOTBluetooth
+//
+//  Created by incar on 2024/6/6.
+//
+
+import Foundation
+/// 表盘文件汇总信息模型(自定义)
+public class IBCustomDial {
+    /// UID,0~4:自定义表盘UID(不可变更)
+    public var UID: Int = 0
+    /// 电池图标样式,  0:无图标  1:黑色图标  2:白色图标
+    public var batteryStyle: Int = 0
+    /// 时间样式  0:时间在下方   1:时间在上方
+    public var timeStyle: Int = 0
+    /// 时间字体颜色    0:亮白      1:黑      2:暗白      3:绿      4:橙      5:蓝
+    public var timeColor: Int = 0
+    /// 文件数目,0~255,为0则后面无需发送各个文件。(仅有一种情况为0,即自定义表盘背景图跟之前一样,仅改变了电池和时间样式)
+    public var numberOfFiles: Int = 0
+    
+    public init() { }
+
+    public var description: String  {
+        return "IBCustomDail(UID: \(UID), batteryStyle:\(batteryStyle), timeStyle:\(timeStyle), timeColor:\(timeColor), numberOfFiles:\(numberOfFiles))"
+    }
+}
+
+/// 表盘文件汇总信息模型(表盘市场)
+public class IBMarketDial {
+    /// UID,0x05~0xffff:表盘市场UID
+    public var UID: Int = 0
+    /// 主题名称长度。0~255,为0则后面名称不用传,且SD卡中该表盘文件夹名字为“unknown_xxxx”(xxxx为UID)。(仅表盘市场有该项)
+    public var themeLength: Int = 0
+    /// 主题名称,名字字节数为前面名称长度指定,UTF-8编码,仅表盘市场有该项,自定义表盘名称统一为"custom"
+    public var theme: String?
+    /// 文件数目,0~255,为0则后面无需发送各个文件。(仅有一种情况为0,即自定义表盘背景图跟之前一样,仅改变了电池和时间样式)
+    public var numberOfFiles: Int = 0
+    
+    public init() { }
+
+    public var description: String  {
+        return "IBMarketDail(UID: \(UID), themeLength:\(themeLength), theme:\(theme ?? ""), numberOfFiles:\(numberOfFiles))"
+    }
+}
+
+/// 单个表盘文件信息模型
+public class IBDialInfo {
+    /// UID,0x05~0xffff:表盘市场UID
+    public var UID: Int = 0
+    /// 文件编号,1~255,即该主题表盘中的第几个文件,最大为表盘文件汇总信息中的文件数目
+    public var number: Int = 0
+    /// 文件类型,0:表盘jSON文件(压缩后统一命名为local_page.lzma)1:图片文件(除缩略图外的其他图片)(背景图压缩后统一命名为main_bg.lzma)2:缩略图:(压缩后统一命名为thumbnail.lzma)
+    public var fileType: Int = 0
+    /// 文件名称长度,6~255,不能为0,文件后缀统一为.lzma
+    public var nameLength: Int = 0
+    /// 文件名称,名称字节数为前面名称长度指定,UTF-8编码
+    public var fileName: String = ""
+    /// 文件大小,0x01~0xffffffff
+    public var fizeSize: Int = 0
+    
+    public init() { }
+
+    public var description: String  {
+        return "IBDailInfo(UID: \(UID), number:\(number),fileType: \(fileType), nameLength:\(nameLength), fileName:\(fileName), fizeSize:\(fizeSize))"
+    }
+}
diff --git a/IOTBluetooth/IOTBluetooth/IOTBluetooth/Models/IBEpo.swift b/IOTBluetooth/IOTBluetooth/IOTBluetooth/Models/IBEpo.swift
new file mode 100644 (file)
index 0000000..03e29c3
--- /dev/null
@@ -0,0 +1,25 @@
+//
+//  IBEpo.swift
+//  IOTBluetooth
+//
+//  Created by incar on 2024/6/7.
+//
+
+import Foundation
+/// IBEpo信息模型
+public class IBEpo:Codable {
+    /// 文件类型,7
+    internal var type: Int = 7
+    /// 固定字段为1
+    internal var valid: Int = 1
+    /// 文件名
+    public var fileName: String = ""
+    /// 纬度值
+    public var lat: String = ""
+    /// 经度值
+    public var lon: String = ""
+    /// 文件大小,单位byte
+    public var size: Int = 1000
+    
+    public init() { }
+}
diff --git a/IOTBluetooth/IOTBluetooth/IOTBluetooth/Models/IBMp3.swift b/IOTBluetooth/IOTBluetooth/IOTBluetooth/Models/IBMp3.swift
new file mode 100644 (file)
index 0000000..d30879c
--- /dev/null
@@ -0,0 +1,25 @@
+//
+//  IBMp3.swift
+//  IOTBluetooth
+//
+//  Created by incar on 2024/6/6.
+//
+
+import Foundation
+/// mp3文件信息模型
+public class IBMp3:Codable {
+    /// 歌曲名字
+    public var name: String = ""
+    /// 文件类型,2:MP3
+    internal var type: Int = 2
+    /// 文件大小,单位byte
+    public var size: Int = 0
+    
+//    enum CodingKeys: String, CodingKey {
+//        case name = "pn"
+//        case type = "tp"
+//        case mac = "mac"
+//    }
+    
+    public init() { }
+}
diff --git a/IOTBluetooth/IOTBluetooth/IOTBluetooth/Models/IBOta.swift b/IOTBluetooth/IOTBluetooth/IOTBluetooth/Models/IBOta.swift
new file mode 100644 (file)
index 0000000..6e6bdf6
--- /dev/null
@@ -0,0 +1,25 @@
+//
+//  IBOta.swift
+//  IOTBluetooth
+//
+//  Created by incar on 2024/6/6.
+//
+
+import Foundation
+/// OTA文件信息模型
+public class IBOta:Codable {
+    /// 文件类型,1:OTA
+    internal var type: Int = 1
+    /// 文件大小,单位byte
+    public var size: Int = 0
+    /// major是主版本号,mid是中间版本号,minor是次版本号,用于与手表当前版本比较,新于当前版本才可升级
+    public var major: Int = 0
+    /// mid是中间版本号
+    public var mid: Int = 0
+    /// minor是次版本号
+    public var minor: Int = 0
+    /// 是否强制升级,0为非强制,1为强制
+    public var isForced: Int = 0
+    
+    public init() { }
+}