Commit b867ff0ea6c6095132da9e89f2983de498aa526b

Authored by jason
1 parent 0f975482

feat:fetch exercise data

HDFwear.xcodeproj/project.pbxproj
... ... @@ -286,6 +286,7 @@
286 286 847482762B03793C0004F0C2 /* NewWeatherModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847482752B03793C0004F0C2 /* NewWeatherModel.swift */; };
287 287 847672B82B074E43007DC2DE /* NewBeiDouContactModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847672B72B074E43007DC2DE /* NewBeiDouContactModel.swift */; };
288 288 8477B04C2B5A243B0018ADA8 /* NewExerciseRealtimeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8477B04B2B5A243B0018ADA8 /* NewExerciseRealtimeModel.swift */; };
  289 + 8477B04E2B5A79EE0018ADA8 /* NewExerciseModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8477B04D2B5A79EE0018ADA8 /* NewExerciseModel.swift */; };
289 290 847AF36E2B4CF35F00E3456E /* NewSleepModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847AF36D2B4CF35F00E3456E /* NewSleepModel.swift */; };
290 291 847B88EF2B5780CA00851EE7 /* NewIntensiveTimeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847B88EE2B5780CA00851EE7 /* NewIntensiveTimeModel.swift */; };
291 292 84DA399D2B4D3A5B008D34A9 /* NewGpsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84DA399C2B4D3A5B008D34A9 /* NewGpsModel.swift */; };
... ... @@ -668,6 +669,7 @@
668 669 847482752B03793C0004F0C2 /* NewWeatherModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewWeatherModel.swift; sourceTree = "<group>"; };
669 670 847672B72B074E43007DC2DE /* NewBeiDouContactModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewBeiDouContactModel.swift; sourceTree = "<group>"; };
670 671 8477B04B2B5A243B0018ADA8 /* NewExerciseRealtimeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewExerciseRealtimeModel.swift; sourceTree = "<group>"; };
  672 + 8477B04D2B5A79EE0018ADA8 /* NewExerciseModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewExerciseModel.swift; sourceTree = "<group>"; };
671 673 847AF36D2B4CF35F00E3456E /* NewSleepModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewSleepModel.swift; sourceTree = "<group>"; };
672 674 847B88EE2B5780CA00851EE7 /* NewIntensiveTimeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewIntensiveTimeModel.swift; sourceTree = "<group>"; };
673 675 847D1C4A2B009FAC0097A96E /* 20231111ReadMe.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = 20231111ReadMe.md; sourceTree = "<group>"; };
... ... @@ -1293,6 +1295,7 @@
1293 1295 845ADEA02B551C8E00C3AD73 /* NewStepModel.swift */,
1294 1296 847B88EE2B5780CA00851EE7 /* NewIntensiveTimeModel.swift */,
1295 1297 8477B04B2B5A243B0018ADA8 /* NewExerciseRealtimeModel.swift */,
  1298 + 8477B04D2B5A79EE0018ADA8 /* NewExerciseModel.swift */,
1296 1299 );
1297 1300 path = Model;
1298 1301 sourceTree = "<group>";
... ... @@ -1642,6 +1645,7 @@
1642 1645 6CC6E57927717FF8006C01A7 /* DailSyncViewController.swift in Sources */,
1643 1646 6C6F406D2743509500F9473C /* MotionViewController.swift in Sources */,
1644 1647 6C1D4D3F27B89BD000C43AA3 /* NFCCardCell.swift in Sources */,
  1648 + 8477B04E2B5A79EE0018ADA8 /* NewExerciseModel.swift in Sources */,
1645 1649 847482762B03793C0004F0C2 /* NewWeatherModel.swift in Sources */,
1646 1650 6C6505CE2799059D0043DB7A /* TitleView.swift in Sources */,
1647 1651 6C5B545C27759CFA007F7901 /* RemindViewController.swift in Sources */,
... ...
HDFwear/20240126ReadMe.md
... ... @@ -127,5 +127,19 @@ BluetoothManager+Function
127 127 接收: [237, 126, 0, 1, 128, 1, 0, 1, 0, 5, 0, 1, 0, 9, 0, 76, 235]
128 128  
129 129  
  130 +拉取运动记录
  131 + func getExerciseData(option: SyncOption = .now, closure: ExerciseClosure? = nil)
  132 + 建议用代理来处理回调,这里不确定所有的0x8024都由拉取动作而来
  133 + 0x8024触发BluetoothSyncDelegate中的didReceiveExerciseData
  134 + 发送: [237, 126, 0, 1, 0, 40, 0, 1, 0, 2, 7, 1, 191, 95]
  135 + 接收: [237, 126, 0, 1, 128, 36, 0, 1, 0, 56, 1, 101, 167, 77, 196, 0, 0, 0, 1, 54, 0, 0, 13, 152, 0, 0, 0, 72, 0, 183, 0, 23, 0, 0, 0, 29, 0, 120, 0, 45, 1, 128, 3, 12, 0, 120, 0, 100, 86, 6, 180, 60, 120, 0, 0, 0, 0, 2, 60, 180, 120, 120, 0, 0, 0, 120, 0, 92]
  136 + 接收: [237, 126, 0, 1, 128, 36, 0, 2, 0, 12, 0, 5, 0, 100, 0, 150, 0, 200, 0, 250, 1, 44, 12, 70]
  137 + 接收: [237, 126, 0, 1, 128, 36, 0, 3, 0, 12, 0, 5, 0, 120, 0, 135, 0, 110, 0, 150, 0, 60, 227, 165]
  138 + 接收: [237, 126, 0, 1, 128, 36, 0, 4, 0, 12, 0, 5, 0, 183, 0, 150, 0, 200, 0, 100, 0, 160, 68, 241]
  139 + 接收: [237, 126, 0, 1, 128, 36, 0, 5, 0, 12, 0, 5, 0, 80, 0, 150, 0, 170, 0, 120, 0, 60, 53, 89]
  140 + 接收: [237, 126, 0, 1, 128, 36, 0, 6, 0, 12, 0, 5, 0, 100, 0, 120, 0, 150, 0, 170, 0, 190, 169, 1]
  141 + 接收: [237, 126, 0, 1, 128, 36, 0, 7, 0, 12, 0, 5, 0, 65, 0, 48, 0, 98, 0, 115, 0, 140, 194, 200]
  142 + 接收: [237, 126, 0, 1, 128, 36, 0, 1, 0, 1, 255, 46, 6]
  143 +
130 144  
131 145 接受数据类
... ...
HDFwear/Home/HomeViewController.swift
... ... @@ -798,7 +798,7 @@ extension HomeViewController: XMLParserDelegate {
798 798 func syncTrain(_ day: SyncDay) {
799 799 print("\(queryArray)---同步训练---\(day)")
800 800 if queryArray.contains("Train"), let index = queryArray.firstIndex(of: "Train") {
801   - BluetoothManager.shared.getTrainHistoryData() {[weak self] train, error in
  801 + BluetoothManager.shared.getExerciseData() {[weak self] train, error in
802 802 if error == nil || error == 2000 || error == -1001 {
803 803 self?.queryArray.remove(at: index)
804 804 if day == .today {
... ...
HDFwear/Home/Model/NewExerciseModel.swift 0 → 100644
  1 +//
  2 +// NewExerciseModel.swift
  3 +// HDFwear
  4 +//
  5 +// Created by admin on 2024/1/19.
  6 +//
  7 +
  8 +import Foundation
  9 +import UIKit
  10 +import HandyJSON
  11 +import SwiftDate
  12 +
  13 +var localExerciseModel : NewExerciseModel?
  14 +
  15 +class NewExerciseModel: NSObject {
  16 + required override init() { }
  17 +
  18 + // 每次分7组数据传过来,一定会有7组,不管是否空
  19 + // 第一组
  20 + var starter: UInt32 = 0//谁发起的运动
  21 + var type: UInt32 = 0//运动类型
  22 + var startTimeInterval: TimeInterval = 0
  23 + var startTime: Date?//运动开始时间
  24 + var strength: UInt32 = 0//训练负荷
  25 + var duration: UInt32 = 0//运动时长
  26 + var distance: Float = 0//距离
  27 + var calorie: Float = 0//卡路里
  28 + var avaragePace: Float = 0//平均配速
  29 + var maxPace: Float = 0//最大配速
  30 + var step: UInt32 = 0//步数
  31 + var stepPitch: Float = 0//步距
  32 + var avarageFrequency: Float = 0//平均步频
  33 + var maxFrequency: Float = 0//最大步频
  34 + var climbAltitude: Float = 0//海拔 累计爬升
  35 + var maxAltitude: Float = 0//最大海拔
  36 + var minAltitude: Float = 0//最小海拔
  37 + var maxOxygenUptake: UInt32 = 0//最大摄氧量
  38 + var oxygenUptakeGrade: UInt32 = 0//摄氧量等级
  39 + var maxHr: UInt32 = 0//最大心率
  40 + var minHr: UInt32 = 0//最小心率
  41 + var avarageHr: UInt32 = 0//平均心率
  42 + var hrSectionPercent_warmUp: UInt32 = 0//心率区间百分比 热身
  43 + var hrSectionPercent_fatBurning: UInt32 = 0//心率区间百分比 燃脂
  44 + var hrSectionPercent_cardiopulmonary: UInt32 = 0//心率区间百分比 心肺提高
  45 + var hrSectionPercent_anaerobic: UInt32 = 0//心率区间百分比 无氧
  46 + var masterSwimming: UInt32 = 0//主泳姿
  47 + var strokes: UInt32 = 0//划水次数
  48 + var lap: UInt32 = 0//趟数
  49 + var avarageSwolf: UInt32 = 0//平均swolf
  50 + var maxSwolf: UInt32 = 0//最大swolf
  51 + var hiits: UInt32 = 0//hiit个数
  52 + //第二组
  53 + var altitudeCount: UInt32 = 0//海拔高度个数
  54 + var altitudeArray: [Float] = []//实时海拔
  55 + //第三组
  56 + var frequencyCount: UInt32 = 0//步频个数
  57 + var frequencyArray: [Float] = []//实时步频
  58 + //第四组
  59 + var paceCount: UInt32 = 0//配速个数
  60 + var paceArray: [Float] = []//实时配速
  61 + //第五组
  62 + var speedCount: UInt32 = 0//速度个数
  63 + var speedArray: [Float] = []//实时速度
  64 + //第六组
  65 + var swolfCount: UInt32 = 0//swolf个数
  66 + var swolfArray: [UInt32] = []//实时swolf
  67 + //第七组
  68 + var strokeCount: UInt32 = 0//划水个数
  69 + var strokeArray: [UInt32] = []//划水速度
  70 +
  71 + override var description: String {
  72 + let dateFormatter = DateFormatter()
  73 + dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
  74 + dateFormatter.timeZone = TimeZone.current
  75 +
  76 + var desc = "NewExerciseModel\n"
  77 + desc += "Starter: \(starter)\n"
  78 + desc += "Type: \(type)\n"
  79 + desc += "StartTime: \(dateFormatter.string(from:(startTime ?? Date())))\n"
  80 + desc += "Strength: \(strength)\n"
  81 + desc += "Duration: \(duration)\n"
  82 + desc += "Distance: \(distance)\n"
  83 + desc += "Calorie: \(calorie)\n"
  84 + desc += "AveragePace: \(avaragePace)\n"
  85 + desc += "MaxPace: \(maxPace)\n"
  86 + desc += "Step: \(step)\n"
  87 + desc += "StepPitch: \(stepPitch)\n"
  88 + desc += "AverageFrequency: \(avarageFrequency)\n"
  89 + desc += "MaxFrequency: \(maxFrequency)\n"
  90 + desc += "ClimbAltitude: \(climbAltitude)\n"
  91 + desc += "MaxAltitude: \(maxAltitude)\n"
  92 + desc += "MinAltitude: \(minAltitude)\n"
  93 + desc += "MaxOxygenUptake: \(maxOxygenUptake)\n"
  94 + desc += "OxygenUptakeGrade: \(oxygenUptakeGrade)\n"
  95 + desc += "MaxHr: \(maxHr)\n"
  96 + desc += "MinHr: \(minHr)\n"
  97 + desc += "AvarageHr: \(avarageHr)\n"
  98 + desc += "HrSectionPercent_warmUp: \(hrSectionPercent_warmUp)\n"
  99 + desc += "HrSectionPercent_fatBurning: \(hrSectionPercent_fatBurning)\n"
  100 + desc += "HrSectionPercent_cardiopulmonary: \(hrSectionPercent_cardiopulmonary)\n"
  101 + desc += "HrSectionPercent_anaerobic: \(hrSectionPercent_anaerobic)\n"
  102 + desc += "MasterSwimming: \(masterSwimming)\n"
  103 + desc += "Strokes: \(strokes)\n"
  104 + desc += "Lap: \(lap)\n"
  105 + desc += "AvarageSwolf: \(avarageSwolf)\n"
  106 + desc += "MaxSwolf: \(maxSwolf)\n"
  107 + desc += "Hiits: \(hiits)\n"
  108 +
  109 + // 第二组
  110 + desc += "Altitude Count: \(altitudeCount)\n"
  111 + desc += "Altitude Array: \(altitudeArray)\n"
  112 +
  113 + // 第三组
  114 + desc += "Frequency Count: \(frequencyCount)\n"
  115 + desc += "Frequency Array: \(frequencyArray)\n"
  116 +
  117 + // 第四组
  118 + desc += "Pace Count: \(paceCount)\n"
  119 + desc += "Pace Array: \(paceArray)\n"
  120 +
  121 + // 第五组
  122 + desc += "Speed Count: \(speedCount)\n"
  123 + desc += "Speed Array: \(speedArray)\n"
  124 +
  125 + // 第六组
  126 + desc += "Swolf Count: \(swolfCount)\n"
  127 + desc += "Swolf Array: \(swolfArray)\n"
  128 +
  129 + // 第七组
  130 + desc += "Stroke Count: \(strokeCount)\n"
  131 + desc += "Stroke Array: \(strokeArray)\n"
  132 +
  133 + return desc
  134 + }
  135 +
  136 + class func toExerciseModel(_ data: [UInt8], _ index: Int) {
  137 + if index == 1 {
  138 + guard data.count >= 57 else {
  139 + return
  140 + }
  141 + }else {
  142 + guard data.count >= 1, localExerciseModel != nil else {
  143 + return
  144 + }
  145 + }
  146 +
  147 + switch index {
  148 + case 1:
  149 + localExerciseModel = NewExerciseModel()
  150 + localExerciseModel?.starter = data[0..<1].reduce(0) { ($0 << 8) + UInt32($1) }
  151 + localExerciseModel?.type = data[1..<2].reduce(0) { ($0 << 8) + UInt32($1) }
  152 + let hexValue = data[2..<6].reduce(0) { ($0 << 8) + UInt32($1) }
  153 + localExerciseModel?.startTimeInterval = TimeInterval(hexValue)
  154 + localExerciseModel?.startTime = Date(timeIntervalSince1970: TimeInterval(hexValue))
  155 + localExerciseModel?.strength = data[6..<7].reduce(0) { ($0 << 8) + UInt32($1) }
  156 + localExerciseModel?.duration = data[7..<11].reduce(0) { ($0 << 8) + UInt32($1) }
  157 + localExerciseModel?.distance = Float(data[11..<15].reduce(0) { ($0 << 8) + UInt32($1) }) / 100
  158 + localExerciseModel?.calorie = Float(data[15..<19].reduce(0) { ($0 << 8) + UInt32($1) }) / 100
  159 + localExerciseModel?.avaragePace = Float(data[19..<21].reduce(0) { ($0 << 8) + UInt32($1) }) / 100
  160 + localExerciseModel?.maxPace = Float(data[21..<23].reduce(0) { ($0 << 8) + UInt32($1) }) / 100
  161 + localExerciseModel?.step = data[23..<27].reduce(0) { ($0 << 8) + UInt32($1) }
  162 + localExerciseModel?.stepPitch = Float(data[27..<29].reduce(0) { ($0 << 8) + UInt32($1) }) / 100
  163 + localExerciseModel?.avarageFrequency = Float(data[29..<31].reduce(0) { ($0 << 8) + UInt32($1) }) / 100
  164 + localExerciseModel?.maxFrequency = Float(data[31..<33].reduce(0) { ($0 << 8) + UInt32($1) }) / 100
  165 + localExerciseModel?.climbAltitude = Float(data[33..<35].reduce(0) { ($0 << 8) + UInt32($1) }) / 100
  166 + localExerciseModel?.maxAltitude = Float(data[35..<37].reduce(0) { ($0 << 8) + UInt32($1) }) / 100
  167 + localExerciseModel?.minAltitude = Float(data[37..<39].reduce(0) { ($0 << 8) + UInt32($1) }) / 100
  168 + localExerciseModel?.maxOxygenUptake = data[39..<40].reduce(0) { ($0 << 8) + UInt32($1) }
  169 + localExerciseModel?.oxygenUptakeGrade = data[40..<41].reduce(0) { ($0 << 8) + UInt32($1) }
  170 + localExerciseModel?.maxHr = data[41..<42].reduce(0) { ($0 << 8) + UInt32($1) }
  171 + localExerciseModel?.minHr = data[42..<43].reduce(0) { ($0 << 8) + UInt32($1) }
  172 + localExerciseModel?.avarageHr = data[43..<44].reduce(0) { ($0 << 8) + UInt32($1) }
  173 + localExerciseModel?.hrSectionPercent_warmUp = data[44..<45].reduce(0) { ($0 << 8) + UInt32($1) }
  174 + localExerciseModel?.hrSectionPercent_fatBurning = data[45..<46].reduce(0) { ($0 << 8) + UInt32($1) }
  175 + localExerciseModel?.hrSectionPercent_cardiopulmonary = data[46..<47].reduce(0) { ($0 << 8) + UInt32($1) }
  176 + localExerciseModel?.hrSectionPercent_anaerobic = data[47..<48].reduce(0) { ($0 << 8) + UInt32($1) }
  177 + localExerciseModel?.masterSwimming = data[48..<49].reduce(0) { ($0 << 8) + UInt32($1) }
  178 + localExerciseModel?.strokes = data[49..<50].reduce(0) { ($0 << 8) + UInt32($1) }
  179 + localExerciseModel?.lap = data[50..<51].reduce(0) { ($0 << 8) + UInt32($1) }
  180 + localExerciseModel?.avarageSwolf = data[51..<52].reduce(0) { ($0 << 8) + UInt32($1) }
  181 + localExerciseModel?.maxSwolf = data[52..<53].reduce(0) { ($0 << 8) + UInt32($1) }
  182 + localExerciseModel?.hiits = data[53..<57].reduce(0) { ($0 << 8) + UInt32($1) }
  183 + case 2:
  184 + localExerciseModel!.altitudeCount = data[0..<2].reduce(0) { ($0 << 8) + UInt32($1) }
  185 + if data.count >= 2 * localExerciseModel!.altitudeCount + 2 {
  186 + // 从下标1开始,每次取2个元素,合并为一个数
  187 + localExerciseModel!.altitudeArray = stride(from: 2, to: data.count, by: 2).map { index in
  188 + let combinedValue = data[index..<index + 2].reduce(0) { ($0 << 8) + UInt32($1) }
  189 + return Float(combinedValue) / 100
  190 + }
  191 + }
  192 + case 3:
  193 + localExerciseModel!.frequencyCount = data[0..<2].reduce(0) { ($0 << 8) + UInt32($1) }
  194 + if data.count >= 2 * localExerciseModel!.frequencyCount + 2 {
  195 + // 从下标1开始,每次取2个元素,合并为一个数
  196 + localExerciseModel!.frequencyArray = stride(from: 2, to: data.count, by: 2).map { index in
  197 + let combinedValue = data[index..<index + 2].reduce(0) { ($0 << 8) + UInt32($1) }
  198 + return Float(combinedValue) / 100
  199 + }
  200 + }
  201 + case 4:
  202 + localExerciseModel!.paceCount = data[0..<2].reduce(0) { ($0 << 8) + UInt32($1) }
  203 + if data.count >= 2 * localExerciseModel!.paceCount + 2 {
  204 + // 从下标1开始,每次取2个元素,合并为一个数
  205 + localExerciseModel!.paceArray = stride(from: 2, to: data.count, by: 2).map { index in
  206 + let combinedValue = data[index..<index + 2].reduce(0) { ($0 << 8) + UInt32($1) }
  207 + return Float(combinedValue) / 100
  208 + }
  209 + }
  210 + case 5:
  211 + localExerciseModel!.speedCount = data[0..<2].reduce(0) { ($0 << 8) + UInt32($1) }
  212 + if data.count >= 2 * localExerciseModel!.speedCount + 2 {
  213 + // 从下标1开始,每次取2个元素,合并为一个数
  214 + localExerciseModel!.speedArray = stride(from: 2, to: data.count, by: 2).map { index in
  215 + let combinedValue = data[index..<index + 2].reduce(0) { ($0 << 8) + UInt32($1) }
  216 + return Float(combinedValue) / 100
  217 + }
  218 + }
  219 + case 6:
  220 + localExerciseModel!.swolfCount = data[0..<2].reduce(0) { ($0 << 8) + UInt32($1) }
  221 + if data.count >= 2 * localExerciseModel!.swolfCount + 2 {
  222 + // 从下标1开始,每次取2个元素,合并为一个数
  223 + localExerciseModel!.swolfArray = stride(from: 2, to: data.count, by: 2).map { index in
  224 + let combinedValue = data[index..<index + 2].reduce(0) { ($0 << 8) + UInt32($1) }
  225 + return combinedValue
  226 + }
  227 + }
  228 + case 7:
  229 + localExerciseModel!.strokeCount = data[0..<2].reduce(0) { ($0 << 8) + UInt32($1) }
  230 + if data.count >= 2 * localExerciseModel!.strokeCount + 2 {
  231 + // 从下标1开始,每次取2个元素,合并为一个数
  232 + localExerciseModel!.strokeArray = stride(from: 2, to: data.count, by: 2).map { index in
  233 + let combinedValue = data[index..<index + 2].reduce(0) { ($0 << 8) + UInt32($1) }
  234 + return combinedValue
  235 + }
  236 + }
  237 + default: break
  238 + }
  239 + }
  240 +}
... ...
HDFwear/Home/Model/NewExerciseRealtimeModel.swift
... ... @@ -15,7 +15,7 @@ class NewExerciseRealtimeModel: NSObject {
15 15  
16 16 var hr: UInt32 = 0
17 17 var step: UInt32 = 0
18   - var calorie: UInt32 = 0
  18 + var calorie: Float = 0
19 19  
20 20  
21 21 override var description: String {
... ... @@ -29,7 +29,7 @@ class NewExerciseRealtimeModel: NSObject {
29 29 let s = NewExerciseRealtimeModel()
30 30 s.hr = data[0..<1].reduce(0) { ($0 << 8) + UInt32($1) }
31 31 s.step = data[1..<5].reduce(0) { ($0 << 8) + UInt32($1) }
32   - s.calorie = data[5..<9].reduce(0) { ($0 << 8) + UInt32($1) }
  32 + s.calorie = Float(data[5..<9].reduce(0) { ($0 << 8) + UInt32($1) }) / 100
33 33 return s;
34 34 }
35 35 }
... ...
HDFwear/Home/TrainViewController.swift
... ... @@ -52,7 +52,7 @@ class TrainViewController: UIViewController, DateSegmentViewDelegate, RangeSlide
52 52 }
53 53 override func viewDidAppear(_ animated: Bool) {
54 54 super.viewDidAppear(animated)
55   - BluetoothManager.shared.getTrainHistoryData() {[weak self] train, error in
  55 + BluetoothManager.shared.getExerciseData() {[weak self] train, error in
56 56 if error == 2000 || error == nil {
57 57 self?.updateTodayData()
58 58 // self?.didSelectedDate(date: DateInRegion((self?.selectedDate)!, region: .current), dateType: .day)
... ...
HDFwear/Mine/MineViewController.swift
... ... @@ -561,17 +561,6 @@ extension MineViewController: UITableViewDataSource, UITableViewDelegate {
561 561 }
562 562 }
563 563  
564   - let archiveAction16 = UIAlertAction(title: "getTrainHistoryData", style: .default) {[weak self] action in
565   - BluetoothManager.shared.getTrainHistoryData() { tArray, error in
566   - if error != nil {
567   - print("getTrainHistoryData" + (error?.description ?? ""))
568   - }else {
569   - self?.showDetailAlert(msg: tArray?.description)
570   - print("getTrainHistoryData success")
571   - }
572   - }
573   - }
574   -
575 564 let archiveAction17a = UIAlertAction(title: "getPressureData now", style: .default) {[weak self] action in
576 565 BluetoothManager.shared.getPressureData(option: .now) { pArray, error in
577 566 if error != nil {
... ... @@ -656,6 +645,27 @@ extension MineViewController: UITableViewDataSource, UITableViewDelegate {
656 645 }
657 646 }
658 647  
  648 + let archiveAction104a = UIAlertAction(title: "getExerciseData now", style: .default) {[weak self] action in
  649 + BluetoothManager.shared.getExerciseData() {exerciseModel, error in
  650 + if error != nil {
  651 + print("getExerciseData" + (error?.description ?? ""))
  652 + }else {
  653 +// self?.showDetailAlert(msg: card)
  654 + print("getExerciseData success")
  655 + }
  656 + }
  657 + }
  658 + let archiveAction104b = UIAlertAction(title: "getExerciseData history", style: .default) {[weak self] action in
  659 + BluetoothManager.shared.getExerciseData(option: .history) {exerciseModel, error in
  660 + if error != nil {
  661 + print("getExerciseData" + (error?.description ?? ""))
  662 + }else {
  663 +// self?.showDetailAlert(msg: card)
  664 + print("getExerciseData success")
  665 + }
  666 + }
  667 + }
  668 +
659 669 alert.addAction(archiveAction9a)
660 670 alert.addAction(archiveAction9b)
661 671 alert.addAction(archiveAction10a)
... ... @@ -664,7 +674,6 @@ extension MineViewController: UITableViewDataSource, UITableViewDelegate {
664 674 alert.addAction(archiveAction14b)
665 675 alert.addAction(archiveAction15a)
666 676 alert.addAction(archiveAction15b)
667   - alert.addAction(archiveAction16)
668 677 alert.addAction(archiveAction17a)
669 678 alert.addAction(archiveAction17b)
670 679 alert.addAction(archiveAction22)
... ... @@ -673,6 +682,8 @@ extension MineViewController: UITableViewDataSource, UITableViewDelegate {
673 682 alert.addAction(archiveAction102a)
674 683 alert.addAction(archiveAction102b)
675 684 alert.addAction(archiveAction103)
  685 + alert.addAction(archiveAction104a)
  686 + alert.addAction(archiveAction104b)
676 687  
677 688 alert.addAction(UIAlertAction(title: "取消", style: .destructive, handler: nil))
678 689 present(alert, animated: true, completion: nil)
... ... @@ -704,4 +715,8 @@ extension MineViewController: BluetoothSyncDelegate {
704 715 func didReceiveExerciseRealtimeData(realtimeData: NewExerciseRealtimeModel) {
705 716 showDetailAlert(msg: realtimeData.description)
706 717 }
  718 +
  719 + func didReceiveExerciseData(exerciseData: NewExerciseModel) {
  720 + showDetailAlert(msg: exerciseData.description)
  721 + }
707 722 }
... ...
HDFwear/ReadMe.txt
... ... @@ -39,10 +39,6 @@ BluetoothManager+Function
39 39 func newSetNotDisturb(remind: RemindModel, weekflag:[WeekFlag], isRepeat:Bool, completion: @escaping(_ error: Int?) -> ())
40 40 发送: [237, 126, 0, 1, 0, 39, 0, 1, 0, 7, 0, 1, 33, 22, 0, 22, 0, 159, 5]
41 41  
42   -23. 拉取训练数据
43   - func getTrainHistoryData(closure: TrainClosure? = nil)
44   - 发送: [237, 126, 0, 1, 0, 40, 0, 1, 0, 1, 7, 224, 11]
45   -
46 42 接受数据类
47 43 1. 通用返回数据
48 44 private func parseDefaultResponseData(_ bytes: [UInt8])
... ...
HDFwear/Tools/BluetoothManager+Function.swift
... ... @@ -284,8 +284,8 @@ extension BluetoothManager {
284 284 newStartSyncHealthData(closure: closure, data: data, synType: .step)
285 285 }
286 286  
287   - // 拉取训练数据
288   - func getTrainHistoryData(option: SyncOption = .now, closure: TrainClosure? = nil) {
  287 + // 拉取运动记录
  288 + func getExerciseData(option: SyncOption = .now, closure: ExerciseClosure? = nil) {
289 289 let data = BleMessage.shared.getSyncCmd(.train, option)
290 290 newStartSyncHealthData(closure: closure, data: data, synType: .train)
291 291 }
... ... @@ -339,11 +339,11 @@ extension BluetoothManager {
339 339 stepClosure?([], -1002)
340 340 stepClosure = nil
341 341 }
342   - case is TrainClosure:
343   - if trainClosure == nil {
344   - trainClosure = closure as? TrainClosure
345   - trainClosure?(nil, -1002)
346   - trainClosure = nil
  342 + case is ExerciseClosure:
  343 + if exerciseClosure == nil {
  344 + exerciseClosure = closure as? ExerciseClosure
  345 + exerciseClosure?(nil, -1002)
  346 + exerciseClosure = nil
347 347 }
348 348 case is PressureClosure:
349 349 if pressureClosure == nil {
... ... @@ -565,6 +565,17 @@ extension BluetoothManager {
565 565 delegate.didReceiveExerciseRealtimeData(realtimeData: realtimeData)
566 566 }
567 567 }
  568 + case 0x8024:// 运动实时数据
  569 + print("运动实时数据")
  570 + let content = parseContentFromBytes(bytes)
  571 + if (content.count == 1 && content.first == 0xff) {
  572 + for delegate in syncDelegateList {
  573 + delegate.didReceiveFinishCommand(0x8028)
  574 + }
  575 + }else {
  576 + let index = Int(UInt16(bytes[6]) << 8 | UInt16(bytes[7]))
  577 + parseExerciseData(content, index)
  578 + }
568 579 case 0x8025://手表户外运动定位轨迹
569 580 print("gps轨迹")
570 581 let content = parseContentFromBytes(bytes)
... ... @@ -807,4 +818,21 @@ extension BluetoothManager {
807 818 let card = String(bytes: content, encoding: .ascii)
808 819 beidouCardClosure?(card, nil)
809 820 }
  821 +
  822 + // 运动数据
  823 + func parseExerciseData(_ content: [UInt8], _ index: Int) {
  824 + guard content.count > 0 else {
  825 + print("无有效的信息")
  826 + exerciseClosure?(nil, nil)
  827 + return
  828 + }
  829 + NewExerciseModel.toExerciseModel(content, index)
  830 + if let em = localExerciseModel, index == 7 {
  831 + for delegate in syncDelegateList {
  832 + delegate.didReceiveExerciseData(exerciseData: em)
  833 + }
  834 + exerciseClosure?(em, nil)
  835 + }
  836 +
  837 + }
810 838 }
... ...
HDFwear/Tools/BluetoothManager.swift
... ... @@ -42,6 +42,7 @@ protocol BluetoothSyncDelegate {
42 42 func didReceiveCameraCommand(status: UInt8)// 0x00 进入拍照 0x01 拍照 0x02 关闭
43 43 func didReceiveExerciseStatus(value: Int)
44 44 func didReceiveExerciseRealtimeData(realtimeData: NewExerciseRealtimeModel)
  45 + func didReceiveExerciseData(exerciseData: NewExerciseModel)
45 46  
46 47 func didReceiveFinishCommand(_ receiveDataType: Int)
47 48 }
... ... @@ -61,6 +62,7 @@ extension BluetoothSyncDelegate {
61 62 func didReceiveCameraCommand(status: UInt8) { }
62 63 func didReceiveExerciseStatus(value: Int) { }
63 64 func didReceiveExerciseRealtimeData(realtimeData: NewExerciseRealtimeModel) { }
  65 + func didReceiveExerciseData(exerciseData: NewExerciseModel) { }
64 66  
65 67 func didReceiveFinishCommand(_ receiveDataType: Int) { }
66 68 }
... ... @@ -93,8 +95,8 @@ class BluetoothManager: NSObject {
93 95 var sleepClosure: SleepClosure?
94 96 typealias StepClosure = (_ stepArray: [NewStepModel], _ error: Int?) -> Void
95 97 var stepClosure: StepClosure?
96   - typealias TrainClosure = (_ trainArray: TrainModel?, _ error: Int?) -> Void
97   - var trainClosure: TrainClosure?
  98 + typealias ExerciseClosure = (_ trainArray: NewExerciseModel?, _ error: Int?) -> Void
  99 + var exerciseClosure: ExerciseClosure?
98 100 typealias PressureClosure = (_ pressureArray: [PressureModel], _ error: Int?) -> Void
99 101 var pressureClosure: PressureClosure?
100 102 typealias MettClosure = (_ mettArray: [MettModel], _ error: Int?) -> Void
... ... @@ -1287,7 +1289,7 @@ class BluetoothManager: NSObject {
1287 1289 bloodOxygenClosure?([], -1001)
1288 1290 sleepClosure?(nil, -1001)
1289 1291 stepClosure?([], -1001)
1290   - trainClosure?(nil, -1001)
  1292 + exerciseClosure?(nil, -1001)
1291 1293 pressureClosure?([], -1001)
1292 1294 mettClosure?([], -1001)
1293 1295 }
... ... @@ -1298,7 +1300,7 @@ class BluetoothManager: NSObject {
1298 1300 bloodOxygenClosure = nil
1299 1301 sleepClosure = nil
1300 1302 stepClosure = nil
1301   - trainClosure = nil
  1303 + exerciseClosure = nil
1302 1304 pressureClosure = nil
1303 1305 mettClosure = nil
1304 1306 gpsClosure = nil
... ... @@ -1315,8 +1317,8 @@ class BluetoothManager: NSObject {
1315 1317 sleepClosure = closure as? SleepClosure
1316 1318 case is StepClosure:
1317 1319 stepClosure = closure as? StepClosure
1318   - case is TrainClosure:
1319   - trainClosure = closure as? TrainClosure
  1320 + case is ExerciseClosure:
  1321 + exerciseClosure = closure as? ExerciseClosure
1320 1322 case is PressureClosure:
1321 1323 pressureClosure = closure as? PressureClosure
1322 1324 case is MettClosure:
... ...