// // HomeViewController.swift // Twear // // Created by yangbin on 2021/11/16. // import UIKit import SwiftDate import Charts import CoreBluetooth import Alamofire import HandyJSON import MJRefresh import AVFoundation import CoreLocation class HomeViewController: UIViewController, CLLocationManagerDelegate { @IBOutlet weak var titleLabel: UILabel! @IBOutlet weak var collectionView: UICollectionView! @IBOutlet weak var collectViewHeight: NSLayoutConstraint! @IBOutlet weak var scrollView: UIScrollView! @IBOutlet weak var bindButton: UIButton! @IBOutlet weak var bindLabel: UILabel? @IBOutlet weak var stepProgressView: StepCircleView! @IBOutlet weak var stepsTimeLabel: UILabel! @IBOutlet weak var stepsDistanceLabel: UILabel! @IBOutlet weak var stepsCalorieLabel: UILabel! @IBOutlet weak var topView: UIView! // @IBOutlet weak var weatherImageView: UIImageView! // @IBOutlet weak var weatherDateLabel: UILabel! // @IBOutlet weak var weatherLabel: UILabel! // private var weatherArray: [WeatherModel] = [] var collectArray: [String] = CurDevice.homePage var scanView: ScanView? = nil var queryArray: [String] = CurDevice.queryArray let locationManager = CLLocationManager() var aMapLocationManager: AMapLocationManager? lazy private var qWeather: AllWeatherInquieirs = { let weather: AllWeatherInquieirs = AllWeatherInquieirs.sharedInstance()! weather.languageType = .ZH return weather }() override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.navigationController?.setNavigationBarHidden(true, animated: true) updateConnectView(DeviceIsConnected) updateStepView() // updateWeatherView() } override func viewDidLoad() { super.viewDidLoad() AMapLocationManager.updatePrivacyAgree(.didAgree) AMapLocationManager.updatePrivacyShow(.didShow, privacyInfo: .didContain) aMapLocationManager = AMapLocationManager() aMapLocationManager?.desiredAccuracy = kCLLocationAccuracyKilometer // aMapLocationManager?.delegate = self aMapLocationManager?.locationTimeout = 2 aMapLocationManager?.reGeocodeTimeout = 5 // let pressureHistory = [0, 0, 1, 2, 3, 0] // print(pressureHistory.reversed().first(where: {$0 > 0}) testDate() let header = MJRefreshNormalHeader(refreshingBlock: { [weak self] in self?.getNewestData() }) // print("lastDate == \(UserInfo.menstrual.lastDate)") // print("MenstrualCalendarModel== \(RealmTools.queryObjects(MenstrualCalendarModel.self))") // str0 = str0.replacingOccurrences(of: "HC:", with: "").uppercased() header.setTitle(LocString("正在同步数据中..."), for: .refreshing) header.lastUpdatedTimeLabel?.isHidden = true scrollView.mj_header = header if IsSwitchLanguage { scrollView.mj_header?.isHidden = false IsSwitchLanguage = false } else { scrollView.mj_header?.isHidden = true } configureCollectionView() BluetoothManager.shared.startScanning()//modify断蓝牙连接不上Bug BluetoothManager.shared.registerDelegate(self) BluetoothManager.shared.registerSyncDelegate(self) BluetoothManager.shared.reConnect() // updateStepView() if #available(iOS 14.0, *) { locationManager.delegate = self } SystemAuth.authLocation {[weak self] isAuth, isFirst in if isAuth || isFirst { // self?.updateWeatherView(true) } } MedalModel.create() // let motion = MotionModel(type: .running, date: Date(), length: 10000, calorie: 299, distance: 100000, steps: 12000, altitude: 323, coordinateArray: "", speedArray: "", stepCadenceArray: "", altitudeArray: "") // MedalModel.update(motion: motion) NotificationCenter.default.addObserver(self, selector: #selector(clockDidChanged), name: NSNotification.Name.NSSystemClockDidChange, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(becomeActive(_:)), name: UIApplication.didBecomeActiveNotification, object: nil) // GCDTimer.shared.scheduledDispatchTimer(WithTimerName: "qWeather", timeInterval: 1, queue: .main, repeats: true) {[ weak self] in // print("查询天气") // self?.queryAMapWeather("430104", city: "长沙") // } }//systemClockDidChangeNotification @objc func becomeActive(_ notification: Notification) { print("前台") reconnectTimer() } @objc func clockDidChanged() { let date = DateInRegion().date // weatherDateLabel.text = date.toString(.custom("yyyy/MM/dd")) + " " + date.weekText BluetoothManager.shared.setTime(format: TimeFormat(rawValue: UInt8(UserInfo.timeFormat))!, completion: nil) } func testDate() { // let testDate = DateInRegion(year: 2022, month: 1, day: 13, hour: 0, minute: 0, second: 0) if IsTest { if let i = collectArray.firstIndex(of: "BloodPressure") { collectArray.remove(at: i) } if let i = collectArray.firstIndex(of: "BloodOxygen") { collectArray.remove(at: i) } } } @available(iOS 14.0, *) func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { switch manager.authorizationStatus { case .notDetermined: if manager.authorizationStatus == .authorizedAlways || manager.authorizationStatus == .authorizedWhenInUse { // updateWeatherView(true) } else { } break // case .authorizedAlways, .authorizedWhenInUse: // updateWeatherView(true) default: break } } // func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { // print(locations) // } // func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { // print(error) // } private func queryLocation() { print("请求定位") // locationManager.delegate = self // locationManager.requestLocation() aMapLocationManager?.requestLocation(withReGeocode: true) {[weak self] location, reGeocode, error in if let error = error { let error = error as NSError if error.code == AMapLocationErrorCode.locateFailed.rawValue { //定位错误:此时location和regeocode没有返回值,不进行annotation的添加 print("定位错误:{\(error.code) - \(error.localizedDescription)};") return } else if error.code == AMapLocationErrorCode.reGeocodeFailed.rawValue || error.code == AMapLocationErrorCode.timeOut.rawValue || error.code == AMapLocationErrorCode.cannotFindHost.rawValue || error.code == AMapLocationErrorCode.badURL.rawValue || error.code == AMapLocationErrorCode.notConnectedToInternet.rawValue || error.code == AMapLocationErrorCode.cannotConnectToHost.rawValue { //逆地理错误:在带逆地理的单次定位中,逆地理过程可能发生错误,此时location有返回值,regeocode无返回值,进行annotation的添加 print("逆地理错误:{\(error.code) - \(error.localizedDescription)};") } else { //没有错误:location有返回值,regeocode是否有返回值取决于是否进行逆地理操作,进行annotation的添加 } } if let location = location { print("location:%@", location) } if let reGeocode = reGeocode { print("reGeocode:%@", reGeocode) if reGeocode.country == "中国" { self?.queryAMapWeather(reGeocode.adcode, city: reGeocode.city) } else { self?.queryQWeatherLocation() } } } } private func queryQWeatherLocation() { qWeather.weather(withInquireType: .GEO_CITY_LOOKUP) {[weak self] responseObject in if let geo = responseObject as? GeoBaseClass { if geo.location.count > 0 { print(geo.location[0]) self?.qWeather.city = geo.location[0].cid self?.queryWeather(geo.location[0].adm2) } } } faileureForError: { _ in } } private func queryAMapWeather(_ cityCode: String, city: String) { Alamofire.request("https://restapi.amap.com/v3/weather/weatherInfo?city=\(cityCode)&extensions=all&key=3729745536c70fe567e107a37ca5310b").responseJSON {[weak self] response in if response.result.isSuccess { if let json = response.result.value as? Dictionary, let forecasts = json["forecasts"] as? Array>, let forecast = forecasts.first { if let casts = forecast["casts"] as? Array> { guard let data = try? JSONSerialization.data(withJSONObject: casts, options: []), let str = String(data: data, encoding: .utf8) else { return } guard var array = [AMapWeatherModel].deserialize(from: str) as? [AMapWeatherModel] else { print("数据解析错误") return } if array.count > 3 { array = Array(array[0...2]) } let weatherArray = WeatherModel.aMapWeather(array, city: city) self?.updateWeather(weatherArray) print(array) } // } } } } private func queryWeather(_ city: String) { qWeather.weather(withInquireType: .WEATHER_3D, withSuccess: {[weak self] responseObject in if let weather = responseObject as? WeatherBaseClass, let daily = weather.daily { let weatherArray = WeatherModel.dailyToWeather(daily, city: city) self?.updateWeather(weatherArray) } }, faileureForError: { err in }) } private func updateWeather(_ array: [WeatherModel]) { if array.count == 3 { let weatherArray = array let nowDate = DateInRegion().date weatherArray[0].date = nowDate weatherArray[1].date = nowDate + 1.days weatherArray[2].date = nowDate + 2.days AdminHelper.shared.savaWeather(weatherArray) // updateWeatherView() } } // private func updateWeatherView(_ isQuery: Bool = false) { // let date = DateInRegion().date // weatherDateLabel.text = date.toString(.custom("yyyy/MM/dd")) + " " + date.weekText // let weatherArray = AdminHelper.shared.loadLocalWeatherData() // if weatherArray.count > 0, let weather = weatherArray.first { // if UserInfo.temperatureUnit == 0 { // weatherLabel.text = "\(LocString(weather.text)) \(weather.lowest)℃-\(weather.highest)℃" // } else { // weatherLabel.text = "\(LocString(weather.text)) \(Int(32+Float(weather.lowest)*1.8))℉-\(Int(32+Float(weather.highest)*1.8))℉" // } // weatherImageView.image = UIImage(named: weather.icon) // if isQuery { // if let lastDate = weather.date { // if (date - lastDate).in(.hour) ?? 9 >= 8 { // queryLocation() // } // } // } // } else { // queryLocation() // weatherLabel.text = LocString("无法获取当前天气") // } // } private func updateConnectView(_ isConnected: Bool) { if CurDevice.uuid == "" { bindButton.setImage(UIImage(named: "add_device"), for: .normal) // bindLabel.text = LocString("添加设备") } else { bindButton.setImage(UIImage(named: "device_connected"), for: .normal) // bindLabel.text = isConnected ? LocString("已连接") : LocString("已断开") } } private func updateStepView() { let step = StepModel.getRecentSteps() let goal = UserInfo.stepsGoal stepProgressView.stepLabel.text = "\(step.number)" stepProgressView.value = min(step.number*100/goal, 100) stepProgressView.locLabel2.text = "\(LocString("目标"))\(UserInfo.stepsGoal)\(LocString("步"))" // stepsGoalLabel.text = "/\(StepsGoal)步/\(String(format:"%.2f", step.calorie))千卡/\(String(format:"%.2f", step.distance))公里" // stepsGoalLabel.toUnitMode1(title: LocString("目标步数"), text: "\(goal)", unit: LocString("步"), font: RegularFont(13), unitFont: LightFont(11)) // stepsCalorieLabel.toUnitMode1(title: LocString("热量"), text: String(format:"%02d",Int(step.calorie)), unit: LocString("千卡"), font: RegularFont(13), unitFont: LightFont(11)) stepsCalorieLabel.text = "\(Int(step.calorie))" stepsTimeLabel.text = "111"//jtd! stepsDistanceLabel.text = "\(String(format:"%.2f", step.distance))" // if UserInfo.distanceUnit == 0 { // stepsDistanceLabel.toUnitMode1(title: LocString("距离"), text: "\(String(format:"%.2f", step.distance))", unit: LocString("公里"), font: RegularFont(13), unitFont: LightFont(11)) // } else { // stepsDistanceLabel.toUnitMode1(title: LocString("距离"), text: "\(step.distance.mileString())", unit: LocString("英里"), font: RegularFont(13), unitFont: LightFont(11)) // } if let index = collectArray.firstIndex(of: "MotionRecord") { collectionView.reloadItems(at: [IndexPath(row: index, section: 0)]) } } @IBAction func bindDevice(_ sender: UIButton) { if CurDevice.uuid.count > 0 { // func unbindDevice() { let vc = UIStoryboard.loadViewControllerIdentifier(storyboardName: "Setting", identifier: "UnbindViewController") as! UnbindViewController vc.unbindClosure = {[weak self] in self?.updateConnectView(false) } navigationController?.pushViewController(vc, animated: true) // } return } scanView = ScanView() scanView?.show() startScan() scanView?.clickClosure = {[weak self] index, device in if index == 2 { self?.scanView = nil BluetoothManager.shared.stopScanning() } else if index == 3 { //配对失败 重试 self?.startScan() } else if index == 4 { //重新搜索 self?.startScan() } if let per = device as? CBPeripheral { BluetoothManager.shared.connect(peripheral: per) self?.scanView?.updateUI(.Pairing) } if GCDTimer.shared.isExistTimer(WithTimerName: "StartScan") { GCDTimer.shared.cancleTimer(WithTimerName: "StartScan") } if GCDTimer.shared.isExistTimer(WithTimerName: "DevicePairing") { GCDTimer.shared.cancleTimer(WithTimerName: "DevicePairing") } GCDTimer.shared.scheduledDispatchTimerNotNow(WithTimerName: "DevicePairing", timeInterval: 12, queue: .main, repeats: false) { self?.pairingFail() } } } private func startScan() { BluetoothManager.shared.startScanning() GCDTimer.shared.scheduledDispatchTimerNotNow(WithTimerName: "StartScan", timeInterval: 10, queue: .main, repeats: false) { BluetoothManager.shared.stopScanning() self.scanView?.updateUI(.ScanComplete) } } @IBAction func addDevice(_ sender: Any) { // let shareView = ShareView(getShareImage()) // shareView.shareImage = getShareImage() // shareView.show() } @IBAction func share(_ sender: Any) { let shareView = ShareView(getShareImage()) // shareView.shareImage = getShareImage() shareView.show() } func getShareImage() -> UIImage? { scrollView.removeFromSuperview() let image = scrollView.captureLongImage view.addSubview(scrollView) scrollView.snp.makeConstraints { (make) in make.top.equalTo(topView.snp.bottom) make.left.bottom.right.equalToSuperview() } view.sendSubviewToBack(scrollView) return image } @IBAction func sortPage(_ sender: Any) { let vc = UIStoryboard.loadViewControllerIdentifier(storyboardName: "Home", identifier: "HomePageSortVC") as! HomePageSortVC vc.ary1 = collectArray vc.sortClosure = {[weak self] array in self?.collectArray = array self?.collectViewHeight.constant = CGFloat(array.count/2 + array.count%2)*200 + 25 self?.collectionView.reloadData() } navigationController?.pushViewController(vc, animated: true) } @IBAction func clickStepView(_ sender: Any) { let vc = UIStoryboard.loadViewControllerIdentifier(storyboardName: "Home", identifier: "StepViewController") as! StepViewController navigationController?.pushViewController(vc, animated: true) } func reconnectTimer() { if GCDTimer.shared.isExistTimer(WithTimerName: "Reconnect") { GCDTimer.shared.cancleTimer(WithTimerName: "Reconnect") } GCDTimer.shared.scheduledDispatchTimerNotNow(WithTimerName: "Reconnect", timeInterval: 10, queue: .main, repeats: true) {[weak self] in self?.reconnect() } } func reconnect() { print("重连") if bindLabel?.text == LocString("连接中...") || bindLabel?.text == LocString("已断开") { BluetoothManager.shared.reConnect() BluetoothManager.shared.reconnectPer() } else { if GCDTimer.shared.isExistTimer(WithTimerName: "Reconnect") { GCDTimer.shared.cancleTimer(WithTimerName: "Reconnect") } } } deinit { BluetoothManager.shared.unRegisterSyncDelegate(self) BluetoothManager.shared.unRegisterDelegate(self) print("deinit\(NSStringFromClass(type(of: self)))!!!!!!!") } } extension HomeViewController: BluetoothManagerDelegate { func centralManagerDidUpdateState(_ state: Int) { switch state { case 4: //power off if CurDevice.uuid != "" { bindLabel?.text = LocString("已断开") } case 5: //power on print("home power on ??") default: print("其他状态:\(state)") } } func didDisconnected() { DeviceIsConnected = false updateConnectView(false) if CurDevice.uuid != "" { reconnectTimer() // bindLabel.text = LocString("连接中...") } // bindLabel.text = LocString("已断开") } func didDiscover(devices: [ScanDevice]) { if scanView != nil { scanView?.deviceArray = devices } } func didConnect(_ peripheral: CBPeripheral) { if GCDTimer.shared.isExistTimer(WithTimerName: "Reconnect") { GCDTimer.shared.cancleTimer(WithTimerName: "Reconnect") } updateConnectView(true) collectArray = CurDevice.homePage testDate() collectViewHeight.constant = CGFloat(collectArray.count/2 + collectArray.count%2)*200 + 25 if GCDTimer.shared.isExistTimer(WithTimerName: "StartScan") { GCDTimer.shared.cancleTimer(WithTimerName: "StartScan") } if GCDTimer.shared.isExistTimer(WithTimerName: "DevicePairing") { GCDTimer.shared.cancleTimer(WithTimerName: "DevicePairing") } collectionView.reloadData() scanView?.updateUI(.PairSuccess) } private func pairingFail() { if !DeviceIsConnected { BluetoothManager.shared.pairFail() scanView?.updateUI(.PairFail) } } } extension HomeViewController: UICollectionViewDataSource,UICollectionViewDelegateFlowLayout { func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { let cell = collectionView.cellForItem(at: indexPath) var cellId: String = "" switch cell { case is BloodPressureCell: cellId = "BloodPressureVC" case is BloodOxygenCell: cellId = "BloodOxygenVC" case is HeartRateCell: cellId = "HeartRateVC" case is SleepCell: cellId = "SleepViewController" case is TrainCell: cellId = "TrainViewController" case is MotionCell: cellId = "RecordDetailVC"//"MotionRecordVC" case is PressureCell: cellId = "PressureViewController" case is MettCell: cellId = "MettViewController" // case is WomenHealthCell: // cellId = "WomenHealthVC" default: break } if cell is WomenHealthCell { if UserInfo.menstrual.days == 0 { let vc = UIStoryboard.loadViewControllerIdentifier(storyboardName: "Home", identifier: "WomenHealthVC") as! WomenHealthVC vc.isFirst = true vc.setClosure = {[weak self] in if let index = self?.collectArray.firstIndex(of: "WomenHealth") { self?.collectionView.reloadItems(at: [IndexPath(row: index, section: 0)]) } } navigationController?.pushViewController(vc, animated: true) cellId = "MenstrualCalendarVC" } else { let vc = UIStoryboard.loadViewControllerIdentifier(storyboardName: "Home", identifier: "MenstrualCalendarVC") as! MenstrualCalendarVC vc.setClosure = {[weak self] in if let index = self?.collectArray.firstIndex(of: "WomenHealth") { self?.collectionView.reloadItems(at: [IndexPath(row: index, section: 0)]) } } navigationController?.pushViewController(vc, animated: true) } } else if cell is MotionCell { let vc = UIStoryboard.loadViewControllerIdentifier(storyboardName: "Motion", identifier: "RecordDetailVC") as! RecordDetailVC vc.motionType = .table_tennis navigationController?.pushViewController(vc, animated: true) } else { let vc = UIStoryboard.loadViewControllerIdentifier(storyboardName: "Home", identifier: cellId) navigationController?.pushViewController(vc, animated: true) } } private func configureCollectionView(){ collectViewHeight.constant = CGFloat(collectArray.count/2 + collectArray.count%2)*200 + 25 let flowLayout = UICollectionViewFlowLayout() flowLayout.scrollDirection = .vertical flowLayout.minimumLineSpacing = 10 flowLayout.minimumInteritemSpacing = 10 flowLayout.sectionInset = UIEdgeInsets(top: 10, left: 12.5, bottom: 15, right: 12.5) flowLayout.itemSize = CGSize(width: (SCREEN_WIDTH-35)/2, height: 190) collectionView.showsVerticalScrollIndicator = false collectionView.bounces = false collectionView.collectionViewLayout = flowLayout collectionView.register(UINib.init(nibName: "BloodPressureCell", bundle: .main), forCellWithReuseIdentifier: "BloodPressureCell") collectionView.register(UINib.init(nibName: "BloodOxygenCell", bundle: .main), forCellWithReuseIdentifier: "BloodOxygenCell") collectionView.register(UINib.init(nibName: "HeartRateCell", bundle: .main), forCellWithReuseIdentifier: "HeartRateCell") collectionView.register(UINib.init(nibName: "SleepCell", bundle: .main), forCellWithReuseIdentifier: "SleepCell") collectionView.register(UINib.init(nibName: "TrainCell", bundle: .main), forCellWithReuseIdentifier: "TrainCell") collectionView.register(UINib.init(nibName: "WomenHealthCell", bundle: .main), forCellWithReuseIdentifier: "WomenHealthCell") collectionView.register(UINib.init(nibName: "MotionCell", bundle: .main), forCellWithReuseIdentifier: "MotionCell") collectionView.register(UINib.init(nibName: "PressureCell", bundle: .main), forCellWithReuseIdentifier: "PressureCell") collectionView.register(UINib.init(nibName: "MettCell", bundle: .main), forCellWithReuseIdentifier: "MettCell") } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return collectArray.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { switch collectArray[indexPath.row] { case "BloodPressure": let cell: BloodPressureCell = collectionView.dequeueReusableCell(withReuseIdentifier: "BloodPressureCell", for: indexPath) as! BloodPressureCell cell.bpHistory = BloodPressureModel.getRecentData() return cell case "BloodOxygen": let cell: BloodOxygenCell = collectionView.dequeueReusableCell(withReuseIdentifier: "BloodOxygenCell", for: indexPath) as! BloodOxygenCell cell.boHistory = BloodOxygenModel.getRecentData() return cell case "HeartRate": let cell: HeartRateCell = collectionView.dequeueReusableCell(withReuseIdentifier: "HeartRateCell", for: indexPath) as! HeartRateCell cell.hrHistory = HeartRateModel.getRecentData() return cell case "Sleep": let cell: SleepCell = collectionView.dequeueReusableCell(withReuseIdentifier: "SleepCell", for: indexPath) as! SleepCell cell.sleep = SleepModel.getRecentData() return cell case "Train": let cell: TrainCell = collectionView.dequeueReusableCell(withReuseIdentifier: "TrainCell", for: indexPath) as! TrainCell // let t3 = TrainModel(type: .running, date: DateInRegion().date-100.minutes, length: 100, calorie: 200, mileage: 300, steps: 500) // let t2 = TrainModel(type: .steppers, date: DateInRegion().date-300.minutes, length: 66, calorie: 1000, mileage: 300, steps: 500) // let t1 = TrainModel(type: .steppers, date: DateInRegion().date-500.minutes, length: 200, calorie: 1000, mileage: 300, steps: 500) cell.trainHistory = TrainModel.getRecentData() return cell case "Pressure": let cell: PressureCell = collectionView.dequeueReusableCell(withReuseIdentifier: "PressureCell", for: indexPath) as! PressureCell // let t1 = PressureModel(value: 30, date: (DateInRegion().date-1.hours).dateAtStartOf(.hour)) // let t2 = PressureModel(value: 70, date: (DateInRegion().date-2.hours).dateAtStartOf(.hour)) // let t3 = PressureModel(value: 60, date: (DateInRegion().date-3.hours).dateAtStartOf(.hour)) cell.pressureHistory = PressureModel.getRecentData() return cell case "Mett": let cell: MettCell = collectionView.dequeueReusableCell(withReuseIdentifier: "MettCell", for: indexPath) as! MettCell // let t1 = MettModel(value: 30, date: (DateInRegion().date-0.days).dateAtStartOf(.day)) // let t2 = MettModel(value: 70, date: (DateInRegion().date-1.days).dateAtStartOf(.day)) // let t3 = MettModel(value: 60, date: (DateInRegion().date-3.days).dateAtStartOf(.day)) cell.mettArray = MettModel.getRecentData() return cell case "WomenHealth": let cell: WomenHealthCell = collectionView.dequeueReusableCell(withReuseIdentifier: "WomenHealthCell", for: indexPath) as! WomenHealthCell cell.menstrual = UserInfo.menstrual return cell case "Motion": let cell: MotionCell = collectionView.dequeueReusableCell(withReuseIdentifier: "MotionCell", for: indexPath) as! MotionCell cell.motion = MotionModel.getRecentData().last ?? MotionModel() return cell default: let cell: MotionCell = collectionView.dequeueReusableCell(withReuseIdentifier: "MotionCell", for: indexPath) as! MotionCell cell.motion = MotionModel.getRecentData().last ?? MotionModel() return cell } } } extension HomeViewController: BluetoothSyncDelegate { func didReceiveHeartRate(value: Int) { if let index = collectArray.firstIndex(of: "HeartRate") { collectionView.reloadItems(at: [IndexPath(row: index, section: 0)]) } } func didReceiveBloodOxygen() { if let index = collectArray.firstIndex(of: "BloodOxygen") { collectionView.reloadItems(at: [IndexPath(row: index, section: 0)]) } } func didReceiveBloodPressure() { if let index = collectArray.firstIndex(of: "BloodPressure") { collectionView.reloadItems(at: [IndexPath(row: index, section: 0)]) } } func firstSync() { getNewestData() } func didReceiveStep() { updateStepView() } } extension HomeViewController: XMLParserDelegate { func getNewestData() { if !DeviceIsConnected { scrollView.mj_header?.endRefreshing() scrollView.mj_header?.isHidden = false return } isFirstSync = true queryArray = CurDevice.queryArray print("开始同步数据 Home") BluetoothManager.shared.syncBug() syncStep(.today) } func syncStep(_ day: SyncDay) { if day == .yesterday { queryArray = CurDevice.queryArray } print("\(queryArray)---同步步数---\(day)") if queryArray.contains("Step"), let index = queryArray.firstIndex(of: "Step") { BluetoothManager.shared.getStepHistoryData() {[weak self] stepArray, error in self?.queryArray.remove(at: index) if error == nil { StepModel.addArray(stepArray) NotificationCenter.default.post(name: NSNotification.Name("UpdateStepData"), object: nil)//计步页面同步过程中拖动闪退的问题 } self?.syncBloodOxygen(day) } } else { syncBloodOxygen(day) } } func syncBloodOxygen(_ day: SyncDay) { print("\(queryArray)---同步血氧---\(day)") if queryArray.contains("BloodOxygen"), let index = queryArray.firstIndex(of: "BloodOxygen") { BluetoothManager.shared.getBloodOxygenHistoryData() {[weak self] boArray, error in self?.queryArray.remove(at: index) if error == nil { BloodOxygenModel.addArray(boArray) } self?.syncBloodPressure(day) } } else { syncBloodPressure(day) } } func syncBloodPressure(_ day: SyncDay) { print("\(queryArray)---同步血压---\(day)") if queryArray.contains("BloodPressure"), let index = queryArray.firstIndex(of: "BloodPressure") { BluetoothManager.shared.getBloodPressureHistoryData() {[weak self] bpArray, error in self?.queryArray.remove(at: index) if error == nil { BloodPressureModel.addArray(bpArray) } self?.syncHeartRate(day) } } else { syncHeartRate(day) } } func syncHeartRate(_ day: SyncDay) { print("\(queryArray)---同步心率---\(day)") if queryArray.contains("HeartRate"), let index = queryArray.firstIndex(of: "HeartRate") { BluetoothManager.shared.getHeartRateHistoryData() {[weak self] hrArray, error in self?.queryArray.remove(at: index) if error == nil { HeartRateModel.addArray(hrArray) NotificationCenter.default.post(name: NSNotification.Name("UpdateSleepData"), object: nil) } self?.syncSleep(day) } } else { syncSleep(day) } } func syncSleep(_ day: SyncDay) { print("\(queryArray)---同步睡眠---\(day)") if queryArray.contains("Sleep"), let index = queryArray.firstIndex(of: "Sleep") { BluetoothManager.shared.getSleepHistoryData() {[weak self] sleepArray, error in self?.queryArray.remove(at: index) if error == nil { SleepModel.addArray(sleepArray) } self?.syncPressure(day) } } else { syncPressure(day) } } func syncPressure(_ day: SyncDay) { print("\(queryArray)---同步压力---\(day)") if queryArray.contains("Pressure"), let index = queryArray.firstIndex(of: "Pressure") { BluetoothManager.shared.getPressureHistoryData() {[weak self] pressureArray, error in self?.queryArray.remove(at: index) if error == nil { PressureModel.addArray(pressureArray) } self?.syncTrain(day) } } else { syncTrain(day) } } func syncTrain(_ day: SyncDay) { print("\(queryArray)---同步训练---\(day)") if queryArray.contains("Train"), let index = queryArray.firstIndex(of: "Train") { BluetoothManager.shared.getTrainHistoryData() {[weak self] train, error in if error == nil || error == 2000 || error == -1001 { self?.queryArray.remove(at: index) if day == .today { self?.syncStep(.yesterday) } else { self?.getSettingData() } } } } else { if day == .today { syncStep(.yesterday) } else { getSettingData() } } } func syncMett() { print("\(queryArray)---同步梅脱---") if queryArray.contains("Mett"), let index = queryArray.firstIndex(of: "Mett") { BluetoothManager.shared.getMettHistoryData() {[weak self] mettArray, error in self?.queryArray.remove(at: index) if error == nil { MettModel.addArray(mettArray) } // self?.setWeatherData() } } else { // setWeatherData() } } func getSettingData() { print("\(queryArray)---同步设置---") if queryArray.contains("Setting"), let index = queryArray.firstIndex(of: "Setting") { BluetoothManager.shared.getSettingData {[weak self] error in self?.queryArray.remove(at: index) // isFirstSync = false self?.queryFirmwareVersion() self?.syncFinish() } } else { queryFirmwareVersion() syncFinish() } } // func setWeatherData() { // print("同步天气") // if weatherArray.count == 0 { // weatherArray = AdminHelper.shared.loadLocalWeatherData() // } // BluetoothManager.shared.setWeather(weatherArray) {[weak self] error in // self?.getSettingData() // } // } func queryFirmwareVersion() { print("查询固件版本") BluetoothManager.shared.getFirmwareVersion {version, type, updateDic, error in // if isUpdate { // let remindView = FirmwareRemindView(title: LocString("版本更新"), detail: LocString("监测到你的手表当前使用的不是最新版本固件,为了不影响手表的正常使用,并给你带来更好的用户体验,请务必将手表更新至最新固件版本。"), sureText: LocString("去更新")) // remindView.show() // } } } func syncFinish() { print("\(queryArray)---同步完成!!!---") collectionView.reloadData() queryArray = CurDevice.queryArray updateStepView() isFirstSync = false // if DailSyncBug { // GCDTimer.shared.scheduledDispatchTimerNotNow(WithTimerName: "DailSyncBug", timeInterval: 5, queue: .main, repeats: false) { // self.dailSyncBug() // } // } scrollView.mj_header?.endRefreshing() scrollView.mj_header?.isHidden = false } // func dailSyncBug() { // DailSyncBug = false // } func syncBug() { // if !isFirstSync { syncFinish() // } } }