case deviceList
/// 绑定设备
case bindDevice(param:[String:Any])
+ /// 解绑
+ case unbind(deviceId:String)
/// 获取登录记录
case loginRecord(page:Int)
/// 删除登录记录
/// 上报版本号
case otaUpdateVersion( param:[String:Any])
+ /// 检查硬件是否有更新
+ case otaTask( param:[String:Any])
+ /// 检查app是否有更新
+ case otaTaskApp( param:[String:Any])
+ ///获取banner
+ case bannerList
+ /// banner点击统计
+ case bannerClick(bannerId:String)
}
// 实现TargetType协议
case .deviceList:
return "/dev/device/list"
case .bindDevice(let param):
- return "/dev/bind?deviceId=\(param["deviceId"]!)&mac=\(param["mac"]!)&prodName=\(param["prodName"]!)"
+ return "/dev/bind?deviceName=\(param["deviceName"]!)&mac=\(param["mac"]!)&prodName=\(param["prodName"]!)"
+ case .unbind(let deviceId):
+ return "/dev/unbind?deviceId=\(deviceId)"
case .loginRecord(let page):
return "/uc/login-record/list/\(page)"
case .deleteLoginRecord(let recordId):
return "/uc/login-record/\(recordId)"
case .otaUpdateVersion(let param):
- return "/ota/task/rest"
+ return "/ota/task/rest?deviceId=\(param["deviceId"]!)&version=\(param["version"]!)"
+ case .otaTask(let param):
+ return "/ota/task?deviceId=\(param["deviceId"]!)&sourceVersion=\(param["sourceVersion"]!)"
+ case .otaTaskApp(let param):
+ return "/ota/task/app?sourceVersion=\(param["sourceVersion"]!)&platform=\(param["platform"]!)"
+
+ case .bannerList:
+ return "/res/banner/list"
+ case .bannerClick(let bannerId):
+ return "/res/banner/click/\(bannerId)"
}
}
switch self {
case .register(_),.phoneCodeLogin(_),.emailCodeLogin(_),.login(_),.commitFeedback(_):
return .post
- case .updatePwd(_),.updateUserInfo(_),.updatePhone(_),.updateEmail(_),.bindDevice(_):
+ case .updatePwd(_),.updateUserInfo(_),.updatePhone(_),.updateEmail(_),.bindDevice(_),.otaUpdateVersion(_):
return .put
- case .deleteLoginRecord(_):
+ case .deleteLoginRecord(_),.unbind(_):
return .delete
default:
return .get
}
func show(animate:Bool = true) -> Void {
+ self.layer.opacity = 1
App.shared.window?.addSubview(self)
}
v.font = .regular(18)
v.textAlignment = .left
v.lineBreakMode = .byTruncatingTail
- v.text = "Hi," + CacheManager.shared.user.info.userName
}
tableView.do { v in
v.delegate = self
tableView.reloadData()
}
}
+ titleLabel.text = "Hi," + CacheManager.shared.user.info.userName
}
}
extension QaHeaderView:UITableViewDelegate,UITableViewDataSource {
}
override func navleftViewTapped() {
if toolBar.recordBtn.isSelected {
- CustomAlert.showWith(title: "提示", messgage: "当前正在录音,确定放弃当前录音吗?", cancelCallback: nil) {[unowned self] in
+ CustomAlert.showWith(title: "提示", messgage: "当前正在录音,确定放弃当前录音吗?", cancelCallback: {}) {[unowned self] in
self.rhythView.stopTimer()
JoyGemCallManager.shared().stop()
PcmSound.sharedInstance().stopAudioUnit()
}
override func navleftViewTapped() {
if toolBar.recordBtn.isSelected {
- CustomAlert.showWith(title: "提示", messgage: "当前正在录音,确定放弃当前录音吗?", cancelCallback: nil) {
+ CustomAlert.showWith(title: "提示", messgage: "当前正在录音,确定放弃当前录音吗?", cancelCallback: {}) {
JoyGemSIDeviceManager.shared().stop()
PcmSound.sharedInstance().stopAudioUnit()
PcmSound.sharedInstance().cleanup()
var deviceId = ""
var image = ""
var productName = ""
+ var mac = ""
+ var version = ""
+ var createTime = ""
+ var updateTime = ""
required public init() { }
}
+++ /dev/null
-//
-// DeviceVM.swift
-// ShenYin
-//
-// Created by liangshi on 2025/10/20.
-//
-
-
-
-
-class DeviceVM:BaseVM{
- static let shared = DeviceVM()
- var dataList = [HomeDeviceModel]()
-
- public func refresh(completion:@escaping (_ result:HomeDeviceModelRoot) ->Void) {
- let api = CommomApi.deviceList
- HttpClient.request(api) {[weak self] (model:HomeDeviceModelRoot,res) in
- guard let self = self else {return}
- if model.isSuccess{
- self.dataList = model.data
- }
- completion(model)
- }
- }
-}
let icon = UIImageView()
let titleLabel = UILabel()
let valueLabel = UILabel()
+ var longPress:((_ model:HomeDeviceModel)->Void)?
+
var model:HomeDeviceModel!{
didSet{
- titleLabel.text = model.productName + model.deviceId.prefix(5)
- valueLabel.text = "未连接"
+ titleLabel.text = model.productName + model.mac.prefix(5)
+
icon.kf.setImage(with: model.image.yc.asUrl)
+
+ if BleManager.shared.isConected(mac: model.mac) {
+ valueLabel.text = "已连接"
+ bgView.alpha = 1
+ }
+ else{
+ valueLabel.text = "未连接"
+ bgView.alpha = 0.5
+ }
}
}
var enable:Bool = false{
v.font = .regular(12)
v.text = "未连接"
}
+ let longTap = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(_:)))
+ bgView.addGestureRecognizer(longTap)
}
override func setupLayout() {
m.top.equalToSuperview().inset(58)
}
}
+
+ @objc func handleLongPress(_ gesture: UILongPressGestureRecognizer) {
+ if gesture.state == .began {
+ CustomAlert.showWith(title: "提示", messgage: "确定要解绑该设备吗?", cancelCallback: {}) {[weak self] in
+ guard let self = self else{return}
+ longPress?(model)
+ }
+ } else if gesture.state == .ended {
+ print("长按结束")
+ }
+ }
+
}
override func viewDidLoad() {
super.viewDidLoad()
-
+ NotificationManager.add(self, selector: #selector(deviceChange(_:)), forName: .deviceValidChange)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
func reloadData() {
DeviceVM.shared.refresh {[weak self] result in
self?.collectionView.reloadData()
+ if !BleManager.shared.isConnetd,let model = DeviceVM.shared.dataList.first{
+ self?.startConectBle(model)
+ }
}
CacheManager.shared.tokenIsValid(){[weak self] in
self?.collectionView.reloadData()
App.shared.goToPage(AddDeviceVC())
}
+
@objc func addDeviceAction(){
let vc = AddDeviceVC()
self.navigationController?.pushViewController(vc, animated: true)
}
+ func unbindAction(_ deviceModel:HomeDeviceModel){
+ YLprogressHUD.showLoading()
+ let api = CommomApi.unbind(deviceId: deviceModel.deviceId)
+ HttpClient.request(api) {[weak self] (model:HomeDeviceModelRoot,res) in
+ guard let self = self else {return}
+ if model.isSuccess{
+ YLprogressHUD.hidden()
+ DeviceVM.shared.dataList.removeAll(where: {$0.deviceId == deviceModel.deviceId})
+ collectionView.reloadData()
+ BleManager.shared.cancel()
+ }
+ else{
+ YLprogressHUD.showAutoHiden(model.msg)
+ }
+ }
+ }
+ func startConectBle(_ model:HomeDeviceModel,autoJump:Bool = false){
+ BleManager.shared.connect(mac: model.mac) { result in
+ if result{
+ ConnectPopView.shared.stateDidChange(.connected) {
+ if autoJump{
+ App.shared.goToPage(HomeVC(device: model))
+ }
+ }
+ }
+ else{
+ ConnectPopView.shared.stateDidChange(.failure)
+ }
+ }
+ }
+ @objc func deviceChange(_ noti:Notification){
+ collectionView.reloadData()
+ }
}
extension HomeDeviceVC:UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = HomeDeviceCell.cell(withCollectionView: collectionView, indexPath: indexPath)
cell.model = DeviceVM.shared.dataList[indexPath.row]
+ cell.longPress = {[weak self] model in
+ self?.unbindAction(model)
+ }
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let model = DeviceVM.shared.dataList[indexPath.row]
- if BleManager.shared.isConected(deviceId: model.deviceId) {
- App.shared.goToPage(HomeVC())
+ if BleManager.shared.isConected(mac: model.mac) {
+ App.shared.goToPage(HomeVC(device: model))
return
}
-
ConnectPopView.shared.stateDidChange(.connecting)
- BleManager.shared.connect(deviceId: model.deviceId) { result in
- if result{
- ConnectPopView.shared.stateDidChange(.connected) {
- App.shared.goToPage(HomeVC())
- }
- }
- else{
- ConnectPopView.shared.stateDidChange(.failure)
- }
- }
-
+ startConectBle(model,autoJump: true)
}
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView{
let header = HomeHeadInfoView.header(with: collectionView, indexPath: indexPath)
titleLabel.snp.makeConstraints { (m) in
m.top.equalToSuperview().inset(10)
- m.left.equalToSuperview().inset(32)
+ m.left.equalToSuperview().inset(14)
m.right.equalToSuperview().offset(-20)
}
deviceLabel.snp.makeConstraints { (m) in
m.top.equalToSuperview().inset(50)
- m.left.equalToSuperview().inset(32)
+ m.left.equalToSuperview().inset(14)
m.height.equalTo(30)
m.width.equalTo(120)
}
nameLabel.snp.makeConstraints { (m) in
m.top.equalTo(deviceLabel.snp.bottom).offset(40)
- m.left.equalToSuperview().inset(32)
+ m.left.equalToSuperview().inset(14)
m.height.equalTo(30)
m.width.equalTo(120)
}
}
override func navleftViewTapped() {
if toolBar.recordBtn.isSelected {
- CustomAlert.showWith(title: "提示", messgage: "当前正在录音,确定放弃当前录音吗?", cancelCallback: nil) {[unowned self] in
+ CustomAlert.showWith(title: "提示", messgage: "当前正在录音,确定放弃当前录音吗?", cancelCallback: {}) {[unowned self] in
self.rhythView.stopTimer()
JoyGemRecordManager.shared().stop()
PcmSound.sharedInstance().stopAudioUnit()
}
override func navleftViewTapped() {
if toolBar.recordBtn.isSelected {
- CustomAlert.showWith(title: "提示", messgage: "当前正在录音,确定放弃当前录音吗?", cancelCallback: nil) {
+ CustomAlert.showWith(title: "提示", messgage: "当前正在录音,确定放弃当前录音吗?", cancelCallback: {}) {
JoyGemSIDeviceManager.shared().stop()
PcmSound.sharedInstance().stopAudioUnit()
PcmSound.sharedInstance().cleanup()
//
class CurrentDeviceView: BaseView {
- let icon = UIImageView()
+ let imageView = UIImageView()
override func setupViews() {
// backgroundColor = .blue
- addSubviews([icon])
- icon.do { v in
+ addSubviews([imageView])
+ imageView.do { v in
//v.backgroundColor = .lightGray
- v.image = UIImage(named: "home_header")
+// v.image = UIImage(named: "home_header")
}
}
override func setupLayout() {
- icon.snp.makeConstraints { make in
+ imageView.snp.makeConstraints { make in
make.width.equalTo(168)
make.height.equalTo(138)
make.centerX.equalToSuperview()
let functionView = HomeFunctionView()
let bottomView = HomeBottomView()
+ private var device: HomeDeviceModel
+ init(device model: HomeDeviceModel) {
+ self.device = model
+ super.init()
+ }
+
override func viewDidLoad() {
super.viewDidLoad()
}
override func setupViews() {
- self.navBar.title = "AI智能"
+ navBar.title = device.productName
navBar.backgroundColor = .white
view.backgroundColor = .white
- navBar.rightView.setImage(UIImage(named: "add_icon"), for: .normal)
+// navBar.rightView.setImage(UIImage(named: "add_icon"), for: .normal)
view.addSubview(bgView)
bgView.addSubviews([headerView,functionView,bottomView])
+
+ headerView.icon.imageView.kf.setImage(with: device.image.yc.asUrl)
}
override func setupLayout() {
bgView.snp.makeConstraints { make in
func startScan(){
list = []
tableView.reloadData()
- BleManager.shared.startScanDevice()
-
- BleManager.shared.didConnectDeviceCallback = { [weak self] device in
- self?.getDeviceInfo(device)
- }
- BleManager.shared.conetedFailureCallback = { [weak self] device in
- self?.showError()
- }
- }
-
- func startConnecte(_ data:DCPeripheral){
- ConnectPopView.shared.stateDidChange(.connecting)
- BleManager.shared.connectPeripheral(data.device)
-
+ DeviceVM.startScan()
}
- /// 带冒号
- func getDeviceInfo(_ device:CBPeripheral){
- guard let prodName = device.name,prodName.count > 0 else{
- showError()
- BleManager.shared.cancel()
- return
- }
- getMac {[weak self] mac in
- guard let self = self else {return}
- guard let mac = mac else{
- BleManager.shared.cancel()
- self.showError()
- return
- }
- startBind(dn: "EEBD03250F66", mac: mac, prodName: prodName)
- }
- }
-
- func startBind(dn deviceId:String,mac:String,prodName:String){
- var params:[String:Any] = [:]
- params["deviceId"] = deviceId//dn
- params["mac"] = mac
- params["prodName"] = prodName
- let api = CommomApi.bindDevice(param: params)
- HttpClient.request(api) {[weak self] (model:ResponseBaseModel,res) in
- guard let self = self else {return}
- if model.isSuccess{
- ConnectPopView.shared.stateDidChange(.connected) {
- App.shared.didLogin()
- }
- }
- else{
- self.showError()
- BleManager.shared.cancel()
- }
- }
- }
- func getMac(finished:@escaping ((_ mac:String?)->Void)) {
- JoyGemAIManager.shared().device.macAddress { edr, ble in
- Logger.debug("edr:\(edr),ble:\(ble)");
- finished(ble)
- } error: { error in
- Logger.debug("\(error!.localizedDescription)")
- finished(nil)
- }
- }
- func fshowSuccess(){
-
- }
- func showError(){
- ConnectPopView.shared.stateDidChange(.failure) {
-
- }
- }
-
- func formatStringAsMacAddress(_ input: String) -> String? {
- guard input.count == 12 else {
- return nil
- }
- var result = ""
- var startIndex = input.startIndex
- while startIndex < input.endIndex {
- let endIndex = input.index(startIndex, offsetBy: min(2, input.distance(from: startIndex, to: input.endIndex)))
- let substring = String(input[startIndex..<endIndex])
- result += substring
- if endIndex < input.endIndex {
- result += ":"
- }
- startIndex = endIndex
- }
- return result
- }
-
}
extension BleScanVC:UITableViewDelegate,UITableViewDataSource {
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let data = list[indexPath.row]
- startConnecte(data)
+ DeviceVM.startConnecte(data)
}
}
--- /dev/null
+//
+// DeviceVM.swift
+// ShenYin
+//
+// Created by liangshi on 2025/10/20.
+//
+
+import JoyGemAI
+
+
+class DeviceVM:BaseVM{
+ static let shared = DeviceVM()
+ var dataList = [HomeDeviceModel]()
+
+ public func refresh(completion:@escaping (_ result:HomeDeviceModelRoot) ->Void) {
+ let api = CommomApi.deviceList
+ HttpClient.request(api) {[weak self] (model:HomeDeviceModelRoot,res) in
+ guard let self = self else {return}
+ if model.isSuccess{
+ self.dataList = model.data
+ }
+ completion(model)
+ }
+ }
+}
+
+extension DeviceVM{
+ static func startScan(){
+ BleManager.shared.startScanDevice()
+
+ BleManager.shared.didConnectDeviceCallback = { device in
+ self.getDeviceInfo(device)
+ }
+ BleManager.shared.conetedFailureCallback = { device in
+ self.showError()
+ }
+ }
+
+ static func startConnecte(_ data:DCPeripheral){
+ ConnectPopView.shared.stateDidChange(.connecting)
+ BleManager.shared.connectPeripheral(data)
+
+ }
+ /// 带冒号
+ static func getDeviceInfo(_ device:DCPeripheral){
+ guard let prodName = device.device.name,prodName.count > 0 else{
+ showError()
+ BleManager.shared.cancel()
+ return
+ }
+ // getMac {[weak self] mac in
+ // guard let self = self else {return}
+ // guard let mac = mac,let mac1 = formatStringAsMacAddress(mac) else{
+ // BleManager.shared.cancel()
+ // self.showError()
+ // return
+ // }
+ // getDN {[weak self] dn in
+ // guard let self = self else {return}
+ // guard let deviceName = dn else{
+ // BleManager.shared.cancel()
+ // self.showError()
+ // return
+ // }
+ //
+ // startBind(dn: deviceName, mac: mac1, prodName: prodName)
+ // }
+ // }
+ getDN { dn in
+ guard let deviceName = dn else{
+ BleManager.shared.cancel()
+ self.showError()
+ return
+ }
+
+ startBind(dn: deviceName, mac: device.mac, prodName: prodName)
+ }
+ }
+
+ static func startBind(dn deviceId:String,mac:String,prodName:String){
+ var params:[String:Any] = [:]
+ params["deviceName"] = deviceId//dn
+ params["mac"] = mac
+ params["prodName"] = prodName
+ let api = CommomApi.bindDevice(param: params)
+ HttpClient.request(api) {(model:ResponseBaseModel,res) in
+ if model.isSuccess{
+ ConnectPopView.shared.stateDidChange(.connected) {
+ App.shared.didLogin()
+ }
+ }
+ else{
+ self.showError()
+ BleManager.shared.cancel()
+ }
+ }
+ }
+
+ static func showSuccess(){
+
+ }
+ static func showError(){
+ ConnectPopView.shared.stateDidChange(.failure) {
+
+ }
+ }
+
+ static func formatStringAsMacAddress(_ input: String) -> String? {
+ guard input.count == 12 else {
+ return nil
+ }
+ var result = ""
+ var startIndex = input.startIndex
+ while startIndex < input.endIndex {
+ let endIndex = input.index(startIndex, offsetBy: min(2, input.distance(from: startIndex, to: input.endIndex)))
+ let substring = String(input[startIndex..<endIndex])
+ result += substring
+ if endIndex < input.endIndex {
+ result += ":"
+ }
+ startIndex = endIndex
+ }
+ return result
+ }
+}
+
+extension DeviceVM{
+ static func getMac(finished:@escaping ((_ mac:String?)->Void)) {
+ JoyGemAIManager.shared().device.macAddress { edr, ble in
+ Logger.debug("edr:\(edr),ble:\(ble)");
+ finished(edr.uppercased())
+ } error: { error in
+ Logger.debug("\(error!.localizedDescription)")
+ finished(nil)
+ }
+ }
+ static func getDN(finished:@escaping ((_ mac:String?)->Void)) {
+ finished("EEBD03250F66")
+ // JoyGemAIManager.shared().device.macAddress { edr, ble in
+ // Logger.debug("edr:\(edr),ble:\(ble)");
+ // finished(ble)
+ // } error: { error in
+ // Logger.debug("\(error!.localizedDescription)")
+ // finished(nil)
+ // }
+ }
+ static func getVersion(finished:@escaping ((_ version:String?)->Void)) {
+ JoyGemAIManager.shared().device.software { version in
+ finished(version)
+ } error: { error in
+ debugPrint("\(error!.localizedDescription)");
+ finished(nil)
+ }
+ }
+}
+
+extension DeviceVM{
+ static func updateOtaVersion(){
+ getVersion { version in
+ guard let v = version else{
+ return
+ }
+ getDN { dn in
+ guard let deviceName = dn else{
+ return
+ }
+ var params:[String:Any] = [:]
+ params["deviceId"] = deviceName
+ params["version"] = v
+ let api = CommomApi.otaUpdateVersion(param:params )
+ HttpClient.request(api) { (model:ResponseBaseModel,res) in
+ }
+ }
+ }
+ }
+}
setupKeyboard()
loadCache()
-
+// AppUpdateVM.shared.checkedUpdate()
}
@MainActor static func setupKeyboard(){
class BleManager: NSObject {
var discoverDeviceCallback: (([DCPeripheral]) -> Void)?
- var didConnectDeviceCallback: ((CBPeripheral) -> Void)?
- var disConnectDeviceCallback: ((CBPeripheral) -> Void)?
- var conetedFailureCallback: ((CBPeripheral) -> Void)?
+ var didConnectDeviceCallback: ((DCPeripheral) -> Void)?
+ var disConnectDeviceCallback: ((DCPeripheral) -> Void)?
+ var conetedFailureCallback: ((DCPeripheral) -> Void)?
private var centralManager: CBCentralManager!
var devices: [DCPeripheral] = []
- private var connectPeripheral: CBPeripheral?
+ var connectPeripheral: DCPeripheral?
private override init() {
super.init()
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
stopScanDevice()
Logger.debug("蓝牙已连接 \(peripheral)")
- connectPeripheral = peripheral
peripheral.delegate = self
peripheral.discoverServices([CBUUID(string: kJoyGemAIServiceUUID)]);
self.isConnetd = true
didConnectDeviceCallback?(connectPeripheral!)
NotificationManager.post(type: .deviceValidChange, objtect: nil)
+ DeviceVM.updateOtaVersion()
}
func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
Logger.debug("peripheral: %@ failed to connect", peripheral)
- conetedFailureCallback?(peripheral)
+ conetedFailureCallback?(connectPeripheral!)
}
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
- Logger.debug("蓝牙已断开 \(peripheral)")
+ Logger.debug("蓝牙已断开 \(connectPeripheral)")
self.isConnetd = false
NotificationManager.post(type: .deviceValidChange, objtect: nil)
- disConnectDeviceCallback?(peripheral)
+ disConnectDeviceCallback?(connectPeripheral!)
}
func getMac(_ dict:[String:Any])->String?{
if let advMsd = dict[CBAdvertisementDataManufacturerDataKey] as? Data {
if (advMsd.count >= 13) {
let mac = advMsd[7...12];
- return mac.map { String($0, radix: 16).padLeft(toLength: 2, withPad: "0") }.joined(separator: ":")
+ return mac.map { String($0, radix: 16).padLeft(toLength: 2, withPad: "0") }.joined(separator: ":").uppercased()
} else {
return nil
}
centralManager.stopScan()
}
- func connectPeripheral(_ peripheral: CBPeripheral) {
+ func connectPeripheral(_ peripheral: DCPeripheral) {
+ connectPeripheral = peripheral
Logger.debug("连接中...")
- centralManager.connect(peripheral, options: [CBConnectPeripheralOptionEnableTransportBridgingKey:true])
+ centralManager.connect(peripheral.device, options: [CBConnectPeripheralOptionEnableTransportBridgingKey:true])
}
func cancel() {
guard let peripheral = connectPeripheral else { return }
- centralManager.cancelPeripheralConnection(peripheral)
+ centralManager.cancelPeripheralConnection(peripheral.device)
+ }
+ func unbind(_ peripheral: DCPeripheral){
+ if let mac = connectPeripheral?.mac ,peripheral.mac == mac{
+ cancel()
+ }
}
}
func joyGemSend(_ data: Data, with characteristic: CBCharacteristic) {
// print("发送",data.map { String($0) }.joined(separator: ""))
if let connectPeripheral = connectPeripheral{
- connectPeripheral.writeValue(data, for: characteristic, type:.withoutResponse)
+ connectPeripheral.device.writeValue(data, for: characteristic, type:.withoutResponse)
}
}
}
extension BleManager{
- func isConected(deviceId:String)->Bool{
- return false
+ func isConected(mac:String)->Bool{
+ guard let device = connectPeripheral else { return false }
+ if device.mac == mac {
+ return isConnetd
+ }
+ else{
+ return false
+ }
}
- func connect(deviceId:String, finished:@escaping ((Bool) -> Void)){
+ func connect(mac:String, finished:@escaping ((Bool) -> Void)){
BleManager.shared.cancel()
BleManager.shared.discoverDeviceCallback = { list in
if list.count <= 0 {
return
}
-
-// for item in list {
-// if item.name == "" {
-//
-// }
-// }
- BleManager.shared.connectPeripheral(list[0].device)
+ for item in list {
+ if item.mac == mac {
+ BleManager.shared.connectPeripheral(item)
+ break
+ }
+ }
}
BleManager.shared.didConnectDeviceCallback = { device in
finished(true)
}
BleManager.shared.startScanDevice()
}
+
}
make.top.equalTo(kNavBtm)
}
}
+
}
extension AboutVC:UITableViewDelegate,UITableViewDataSource {
App.shared.goToPage(vc)
}
else if data == .update{
- YLprogressHUD.showAutoHiden("当前已经是最新版本")
+ AppUpdateVM.shared.checkedUpdate()
}
}
}
import UIKit
class DeviceInfoVC: BaseVC{
let tableView = UITableView(frame: .zero, style: .plain)
- var vm = MyDeviceInfoVM()
+ var list:[MyDeviceListCellModel] = []
+ var model:HomeDeviceModel
+
+ init(device: HomeDeviceModel) {
+ model = device
+ list = [
+ MyDeviceListCellModel(title: "设备名称",value: model.productName),
+ MyDeviceListCellModel(title: "设备地址",value: model.mac),
+ MyDeviceListCellModel(title: "硬件版本",value: "1.0"),
+ MyDeviceListCellModel(title: "软件版本",value: model.version.isEmpty ? "--":model.version),
+ // MyDeviceListCellModel(title: "剩余容量",value: "100MB"),
+ ]
+ super.init()
+ }
override func viewDidLoad() {
super.viewDidLoad()
v.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: kScreenHei, height: 20))
v.bounces = false
}
-
view.addSubviews([tableView])
-
-
}
override func setupLayout() {
tableView.snp.makeConstraints { make in
extension DeviceInfoVC:UITableViewDelegate,UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- return vm.list.count
+ return list.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = MyDeviceInfoCell.cell(withTableView: tableView, indexPath: indexPath)
let rect = CGRect(x: 0, y: 0, width: kScreenWid - 36, height: 52)
- cell.model = vm.list[indexPath.row]
+ cell.model = list[indexPath.row]
if indexPath.row == 0 {
cell.bgView.yc.setCorners(withRoundedRect: rect, roundingCorners: [.topLeft,.topRight], cornerRadii: CGSize(width: 12, height: 12))
}
- else if indexPath.row == 4{
+ else if indexPath.row == list.count - 1{
cell.bgView.yc.setCorners(withRoundedRect: rect, roundingCorners: [.bottomLeft,.bottomRight], cornerRadii: CGSize(width: 12, height: 12))
}
else{
+++ /dev/null
-//
-// MyDeviceVM.swift
-// ShenYin
-//
-// Created by liangshi on 2025/10/21.
-//
-
-class MyDeviceInfo{
- var deviceName = ""
- var mac = ""
- var heardWear = ""
- var softWear = ""
- var sapce = ""
-}
-
-
-
-class MyDeviceInfoVM:BaseVM{
- var mode = MyDeviceInfo()
- var list:[MyDeviceListCellModel] = [
- MyDeviceListCellModel(title: "设备名称",value: "Deep Gen2 Max"),
- MyDeviceListCellModel(title: "设备地址",value: "E7:FA:D8:C8:CC:62"),
- MyDeviceListCellModel(title: "硬件版本",value: "SY_Gen2_Max_V1.0"),
- MyDeviceListCellModel(title: "软件版本",value: "SY_Gen2_Max_V1.0.1"),
- MyDeviceListCellModel(title: "剩余容量",value: "100MB"),
- ]
-
-// public func refresh(completion:@escaping (_ result:HomeDeviceModelRoot) ->Void) {
-// let api = CommomApi.deviceList
-// HttpClient.request(api) {[weak self] (model:HomeDeviceModelRoot,res) in
-// guard let self = self else {return}
-// if model.isSuccess{
-// self.dataList = model.data
-// }
-// completion(model)
-// }
-// }
-}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let data = DeviceVM.shared.dataList[indexPath.row]
- App.shared.goToPage(DeviceInfoVC())
+ App.shared.goToPage(DeviceInfoVC(device: data))
}
// // 实现滑动删除功能
// func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
}
}
@objc func swictAction(){
- CustomAlert.showWith(title: "提示", messgage: "确定要切换账号吗?", cancelCallback: nil) {
+ CustomAlert.showWith(title: "提示", messgage: "确定要切换账号吗?", cancelCallback: {}) {
CacheManager.shared.logout()
}
}
@objc func logoutAction(){
- CustomAlert.showWith(title: "提示", messgage: "确定要退出登录吗?", cancelCallback: nil) {
+ CustomAlert.showWith(title: "提示", messgage: "确定要退出登录吗?", cancelCallback: {}) {
CacheManager.shared.logout()
}
}
@objc func deactivateAction(){
- CustomAlert.showWith(title: "提示", messgage: "真的要注销账号吗?", cancelCallback: nil) {
+ CustomAlert.showWith(title: "提示", messgage: "真的要注销账号吗?", cancelCallback: {}) {
HttpClient.request(.deactivate) { (result:ResponseBaseModel,res) in
if result.isSuccess{
YLprogressHUD.showSuccess {
--- /dev/null
+//
+// BannerModel.swift
+// ShenYin
+//
+// Created by liangshi on 2025/10/21.
+//
+
+import HandyJSON
+
+class BannerModelRoot:ResponseBaseModel {
+ var data = [BannerModel]()
+}
+
+class BannerModel:HandyJSON {
+ var id = ""
+ var title = ""
+ var cover = ""
+ var url = ""
+ var clickCount = 0
+ required public init() { }
+}
import UIKit
import FSPagerView
-class BannerModel: NSObject {
- /// id
- var id = ""
- /// 图片
- var imgPath = ""
- /// 跳转类型 -1不跳转 0外链
- var jumpType = -1
- /// 跳转地址
- var jumpValue = ""
-}
final class MineBannerView: BaseView {
private var dataArray = [BannerModel]()
func pagerView(_ pagerView: FSPagerView, cellForItemAt index: Int) -> FSPagerViewCell {
let cell = pagerView.dequeueReusableCell(withReuseIdentifier: "PictureViewCell", at: index) as! PictureViewCell
let model = dataArray[index]
-// cell.picture.kf.setImage(with: model.imgPath.yc.asUrl)
- cell.picture.image = UIImage(named: model.imgPath)
+ cell.picture.kf.setImage(with: model.cover.yc.asUrl)
return cell
}
// UIViewController.yc.currentNav?.pushViewController(vc, animated: true)
// } //UIApplication.shared.canOpenURL(URL(string: ))
// }
+ HttpClient.request(.bannerClick(bannerId: model.id)) { (model:BannerModelRoot,res) in
+ }
+
+ guard let url = model.url.yc.asUrl else{
+ return
+ }
+ UIApplication.shared.open(url)
}
}
override func setupViews() {
addSubviews([userInfo,banner])
- let model1 = BannerModel()
- model1.imgPath = "mine_banner1"
- let model2 = BannerModel()
- model2.imgPath = "mine_banner2"
- let model3 = BannerModel()
- model3.imgPath = "mine_banner3"
- banner.config(list: [model1,model2,model3])
+// let model1 = BannerModel()
+// model1.imgPath = "mine_banner1"
+// let model2 = BannerModel()
+// model2.imgPath = "mine_banner2"
+// let model3 = BannerModel()
+// model3.imgPath = "mine_banner3"
+// banner.config(list: [model1,model2,model3])
}
override func setupLayout() {
make.top.equalTo(kNavBtm)
}
}
- override func setupData() {
-
+// override func setupData() {
+// loadData()
+// }
+ override func viewDidAppear(_ animated: Bool) {
+ super.viewDidAppear(animated)
+ loadData()
+ }
+ func loadData(){
CacheManager.shared.user.getStorageSize { result in
}
DeviceVM.shared.refresh { result in
}
- }
- override func viewDidAppear(_ animated: Bool) {
- super.viewDidAppear(animated)
+
+ HttpClient.request(.bannerList) {[weak self] (model:BannerModelRoot,res) in
+ guard let self = self else {return}
+ if model.isSuccess{
+ headerView.banner.config(list: model.data)
+ }
+ }
headerView.userInfo.updateUI()
}
}
--- /dev/null
+//
+// AppUpdateModel.swift
+// ShenYin
+//
+// Created by liangshi on 2025/10/22.
+//
+
+import HandyJSON
+
+class AppUpdateModelRoot:ResponseBaseModel {
+ var data = AppUpdateModel()
+}
+
+class AppUpdateModel:HandyJSON {
+ var sourceVersion = ""
+ var targetVersion = ""
+ var updateType = ""//升级类型:0手动升级,1强制升级,2强制下载
+ var description = ""
+ required public init() { }
+}
--- /dev/null
+//
+// AppUpdateVM.swift
+// ShenYin
+//
+// Created by liangshi on 2025/10/22.
+//
+
+class AppUpdateVM:BaseVM{
+ static let shared = AppUpdateVM()
+ func checkedUpdate(){
+ // YLprogressHUD.showAutoHiden("当前已经是最新版本")
+ var params:[String:Any] = [:]
+ params["sourceVersion"] = Bundle.main.appVersion ?? "1.0.0"
+ params["platform"] = "iOS"
+ YLprogressHUD.showLoading()
+ HttpClient.request(.otaTaskApp(param: params)) {[weak self](model:AppUpdateModelRoot,res) in
+ YLprogressHUD.hidden()
+ guard let self = self else {return}
+ if model.isSuccess,model.data.targetVersion.uppercased() > model.data.sourceVersion.uppercased(){
+ if model.data.updateType != "0"{
+ //可选升级
+ optionUpdate()
+ }
+ else{
+ //强制升级
+ forceUpdate()
+ }
+ }
+ else{
+ YLprogressHUD.showAutoHiden(model.msg)
+ }
+ }
+ }
+ func optionUpdate(){
+ CustomAlert.showWith(title: nil, messgage: "检测到新版本,是否前往更新") {
+
+ } okCallback: {
+ guard let url = "https://www.baidu.com".yc.asUrl else{
+ return
+ }
+ UIApplication.shared.open(url)
+ }
+
+ }
+ func forceUpdate(){
+ CustomAlert.showWith(title: nil, messgage: "检测到新版本", ok: "前往更新",cancelCallback: nil) {
+ guard let url = "https://www.baidu.com".yc.asUrl else{
+ return
+ }
+ UIApplication.shared.open(url, options: [:], completionHandler: {_ in
+ exit(0)
+ })
+ }
+ }
+}
--- /dev/null
+//
+// BleUpdateVM.swift
+// ShenYin
+//
+// Created by liangshi on 2025/10/22.
+//
+
+class BleUpdateVM:BaseVM{
+ static let shared = BleUpdateVM()
+ func checkedUpdate(){
+ // YLprogressHUD.showAutoHiden("当前已经是最新版本")
+ DeviceVM.getDN {[weak self] dn in
+ guard let self = self else{return}
+ guard let deviceName = dn else{
+ return
+ }
+ DeviceVM.getVersion {[weak self] version in
+ guard let self = self else{return}
+ guard let version = version else{
+ return
+ }
+ startCheck(deviceName: deviceName, version: version)
+ }
+ }
+ }
+ func startCheck(deviceName:String,version:String){
+ var params:[String:Any] = [:]
+ params["sourceVersion"] = version
+ params["deviceId"] = deviceName
+ YLprogressHUD.showLoading()
+ HttpClient.request(.otaTask(param: params)) {[weak self](model:AppUpdateModelRoot,res) in
+ YLprogressHUD.hidden()
+ guard let self = self else {return}
+ if model.isSuccess{
+ if model.data.targetVersion.uppercased() > model.data.sourceVersion.uppercased(){
+ if model.data.updateType != "0"{
+ //可选升级
+ optionUpdate()
+ }
+ else{
+ //强制升级
+ forceUpdate()
+ }
+ }
+ else{
+ YLprogressHUD.showAutoHiden("已是最新版本")
+ }
+ }
+ else{
+ YLprogressHUD.showAutoHiden(model.msg)
+ }
+ }
+ }
+ func optionUpdate(){
+ CustomAlert.showWith(title: nil, messgage: "检测到新版本,是否开始更新?") {
+
+ } okCallback: {
+ guard let url = "https://www.baidu.com".yc.asUrl else{
+ return
+ }
+ UIApplication.shared.open(url)
+ }
+
+ }
+ func forceUpdate(){
+ CustomAlert.showWith(title: nil, messgage: "检测到新版本", ok: "开始更新",cancelCallback: nil) {
+ guard let url = "https://www.baidu.com".yc.asUrl else{
+ return
+ }
+ UIApplication.shared.open(url, options: [:], completionHandler: {_ in
+ exit(0)
+ })
+ }
+ }
+}
view.addSubviews([versionLabel,btn])
self.navBar.title = "固件升级"
versionLabel.do { v in
- v.text = "当前版本\n" + "v1.0.6"
+ v.text = "当前版本\n"
v.textAlignment = .center
v.font = .regular(16)
v.textColor = .hexString("#232323")
make.centerX.equalToSuperview()
}
}
+ override func setupData() {
+ DeviceVM.getVersion {[weak self] version in
+ guard let self = self else{return}
+ guard let version = version else{
+ return
+ }
+ versionLabel.text = "当前版本\n" + "\(version)"
+ }
+ }
@objc func tapAction(){
- YLprogressHUD.showAutoHiden("当前已经是最新版本")
+ if !BleManager.shared.isConnetd{
+// YLprogressHUD.showAutoHiden("")
+ return
+ }
+ BleUpdateVM.shared.checkedUpdate()
}
}
}
func startPlay(path:String){
playBtn.isEnabled = true
- guard let path = Bundle.main.path(forResource: "大约在冬季", ofType: "mp3") else {return}
+// guard let path = Bundle.main.path(forResource: "大约在冬季", ofType: "mp3") else {return}
AudioPlayerManager.shared.play(filePath: path)
AudioPlayerManager.shared.start()
playBtn.isSelected = true
// App.shared.topVC()?.present(vc, animated: true)
// }
- static func showWith(title:String,messgage:String,cancel:String = "取消",ok:String = "确定",cancelCallback: (()->Void)?,okCallback: (()->Void)?){
+ static func showWith(title:String?,messgage:String,cancel:String = "取消",ok:String = "确定",cancelCallback: (()->Void)?,okCallback: (()->Void)?){
let vc = UIAlertController(title: title, message: messgage, preferredStyle: .alert)
- let action0 = UIAlertAction(title: cancel, style: .cancel) { action in
- cancelCallback?()
+ if cancelCallback != nil {
+ let action0 = UIAlertAction(title: cancel, style: .cancel) { action in
+ cancelCallback?()
+ }
+ vc.addAction(action0)
}
+
let action1 = UIAlertAction(title: ok, style: .default) { action in
okCallback?()
}
- vc.addAction(action0)
vc.addAction(action1)
App.shared.topVC()?.present(vc, animated: true)
}
+
}