// // DeviceViewControllers.swift // FireBoltt // // Created by lemo. on 2020/3/7. // Copyright © 2020 Sheldon. All rights reserved. // import UIKit import Photos fileprivate enum Resuable { static let tableViewCell = ReusableCell(nibName: "CommonTableViewCell") } class DeviceViewControllers: TableViewController { var imagePickerController: CustomPickerControllers? var isCamera: Bool = false var isOpenCamera: Bool = false lazy var footerView: DeviceFooterView = { let view = DeviceFooterView(frame: CGRect(x: 0, y: 0, width: kScreenW, height: kScaleWidth(80))) view.unBindingBtn.addTarget(self, action: #selector(unBindingTouch), for: .touchUpInside) return view }() lazy var noDeviceImg: UIImageView = { return UIImageView(image: R.image.fb_default_device_icon()) }() lazy var fbheaderView: DeviceHeaderView = { let view = DeviceHeaderView() return view }() lazy var fbbindingTipLabel: UILabel = { let label = UILabel() label.text = MultiLanguageKey_FB.noDeviceTipFB.localized label.textAlignment = .center label.font = SystemRegularFont(14) label.textColor = kHexColor(0x858585) return label }() lazy var fbbindingBtn: UIButton = { let btn = UIButton() btn.gradient(colors: [kHexColor(0x59AAFF), kHexColor(0x2B75FF)], startPoint: CGPoint(x: 0, y: 0.5), endPoint: CGPoint(x: 1, y: 0.5), locations: [0, 1], autoLaoutFrame: CGRect(x: 0, y: 0, width: kScaleWidth(190), height: kScaleWidth(45))) btn.layer.cornerRadius = kScaleWidth(22.5) btn.layer.masksToBounds = true btn.setTitle(MultiLanguageKey_FB.bindingDeviceFB.localized, for: .normal) btn.titleLabel?.font = SystemRegularFont(18) btn.setTitleColor(kHexColor(0xffffff), for: .normal) return btn }() override func viewDidLoad() { super.viewDidLoad() monitor() tableView.rx.setDelegate(self).disposed(by: rx.disposeBag) tableView.register(Resuable.tableViewCell) } override func tongzhi() { monitor() } override func makeUI() { super.makeUI() isTitleCenter = true navigationTitle = MultiLanguageKey_FB.mineDeviceFB.localized if #available(iOS 13.0, *) { tableViewStyle = .insetGrouped } else { tableViewStyle = .grouped } tableView.backgroundColor = kHexColor(0xFAFAFA) tableView.rowHeight = kScaleWidth(52) view.addSubview(noDeviceImg) view.addSubview(fbbindingTipLabel) view.addSubview(fbbindingBtn) view.bringSubviewToFront(tableView) // 头视图 fbheaderView.backgroundColor = .white tableView.tableHeaderView = fbheaderView footerView.backgroundColor = .clear tableView.tableFooterView = footerView layoutUI() } private func layoutUI() { tableView.snp.makeConstraints { (make) in make.edges.equalToSuperview() } noDeviceImg.snp.makeConstraints { (make) in make.top.equalTo(kScaleHeight(60)) make.width.height.equalTo(kScaleWidth(180)) make.centerX.equalToSuperview() } fbbindingTipLabel.snp.makeConstraints { (make) in make.top.equalTo(noDeviceImg.snp.bottom).offset(kScaleHeight(15)) make.centerX.equalToSuperview() } fbbindingBtn.snp.makeConstraints { (make) in make.bottom.equalTo(-50) make.width.equalTo(kScaleWidth(190)) make.height.equalTo(kScaleWidth(45)) make.centerX.equalToSuperview() } fbheaderView.snp.makeConstraints { (make) in make.width.equalTo(kScreenW) make.height.equalTo(kScaleWidth(150) + 10) } } override func bindViewModel() { guard let viewModel = viewModel as? DeviceViewModels else { return } viewModel.isBinding .map { !$0 } .bind(to: tableView.rx.isHidden) .disposed(by: rx.disposeBag) // 数据源 let rxDataSource = RxTableViewSectionedReloadDataSource>(configureCell: { (_ , tv, indexPath, model) -> UITableViewCell in let cell: CommonTableViewCell = tv.dequeue(Resuable.tableViewCell, for: indexPath) cell.bindViewModel(model: model) // CELL上开关时间处理 cell.rightSwitch.rx.isOn .skip(1) .subscribe(onNext: { (isOn) in guard let functionType = model.functionType else { return } if !BluetoothService.shared.checkBleCmdEnable(isShow: true) { return; } switch functionType { case .handUp: BluetoothService.shared.handup(isOn: isOn) GlobalDeviceProfileModel.shareInstance.gestureModel?.Raise = isOn case .callRemind: BluetoothService.shared.setPushStatus(pushType: .call, isOn: isOn) case .messageRemind: BluetoothService.shared.setPushStatus(pushType: .message, isOn: isOn) default: break } viewModel.fbloadFuncation() }) .disposed(by: cell.cellDisposeBag) return cell }) viewModel.datasource .bind(to: tableView.rx.items(dataSource: rxDataSource)) .disposed(by: rx.disposeBag) // 头视图 viewModel.deviceName .bind(to: fbheaderView.fbdeviceNameLabel.rx.text) .disposed(by: rx.disposeBag) let connectState = viewModel.connectState.share(replay: 1) connectState .bind(to: fbheaderView.fbstatusBtn.rx.isSelected) .disposed(by: rx.disposeBag) viewModel.powerState .bind(to: fbheaderView.fbpowerBtn.rx.image(for: .normal)) .disposed(by: rx.disposeBag) // 设备未连接处理 connectState .map { !$0 } .bind(to: fbheaderView.fbsyncBtn.rx.isHidden) .disposed(by: rx.disposeBag) // 绑定 let input = DeviceViewModels.Input(syncData: fbheaderView.fbsyncBtn.rx.tap.asObservable()) let output = viewModel.transform(input: input) output.syncState .drive(fbheaderView.fbsyncBtn.rx.title(for: .normal)) .disposed(by: rx.disposeBag) tableView.rx.modelSelected(TableViewCellModel.self) .map { $0.functionType } .filter { $0 != nil } .subscribe(onNext: { [weak self] (functionType) in guard let `self` = self else { return } guard let functionType = functionType else { return } switch functionType { case .handUp, .callRemind, .messageRemind, .unBinding, .wechatSport: break default: // 检查指令状态 if !BluetoothService.shared.checkBleCmdEnable(isShow: true) { return } } switch functionType { case .findPhone: BluetoothService.shared.findDevice() case .remoteCamera: // 获取相机权限 SystemAuthorityFireBoltt.shared.getCameraAuthority(result: { (result) in if result { self.isCamera = true if BluetoothService.shared.checkBleCmdEnable(isShow: true) { BluetoothService.shared.cameraSwitchWithBleCmdType(isOpen: true) } } }) case .notice: let viewModel = NoticeViewModels() self.navigator.show(segue: .notice(viewModel: viewModel), sender: self) case .heartCheck: let viewModel = HeartRateCheckViewModels() self.navigator.show(segue: .heartRateCheck(viewModel: viewModel), sender: self) case .tempeartureCheck: let viewModel = TemperarureCheckViewModels() self.navigator.show(segue: .temperatureCheck(viewModel: viewModel), sender: self) case .notDisturb: let viewModel = NotDisturbViewModels() self.navigator.show(segue: .notDisturb(viewModel: viewModel), sender: self) case .drinkRemind: let viewModel = DrinkRemindViewModels() self.navigator.show(segue: .drinkRemind(viewModel: viewModel), sender: self) case .sedentary: let viewModel = SedentaryViewModels() self.navigator.show(segue: .sedentary(viewModel: viewModel), sender: self) case .alarmClock: let viewModel = NewAlarmListViewModel() self.navigator.show(segue: .alarmList(viewModel: viewModel), sender: self) case .dialPush: let viewModel = DialPushViewModels() self.navigator.show(segue: .dialPush(viewModel: viewModel), sender: self) case .firmwareUpgrade: let viewModel = FirmwareUpdateViewModels() self.navigator.show(segue: .firmwareUpdate(viewModel: viewModel), sender: self) case .unBinding: showAlert(self, MultiLanguageKey_FB.unbindingTipFB.localized, cancelText: MultiLanguageKey_FB.cancelFB.localized, confirmText: MultiLanguageKey_FB.confirmFB.localized) { (result) in if result { UserDefaultsManagerFrieBoltt.deleteDeviceInfo() BluetoothFireBoltt.shareInstance()?.disConnectedCurrenDevice(true) kNotificationCenter.post(name: NSNotification.Name(UnBindingDeviceFireBoltt), object: nil) } } case .wechatSport: let viewModel = WeChatSportViewModelss() self.navigator.show(segue: .wechatSport(viewModel: viewModel), sender: self) case .telephoneBook: NSLog("%@", "通讯录") let viewModel = TelephoneBookViewModels() self.navigator.show(segue: .telephonebook(ViewModel: viewModel), sender: self) case .businessCard: NSLog("%@", "名片") let viewModel = businessCardViewModels() self.navigator.show(segue: .businesscard(ViewModel: viewModel), sender: self) case .theWallet: NSLog("%@", "钱包") let viewModel = PaymentCodeViewModels() self.navigator.show(segue: .theWallet(ViewModel: viewModel), sender: self) case .music: print("音乐管理") let vc = MusicManageViewControllers() vc.view.backgroundColor = UIColor.white; vc.hidesBottomBarWhenPushed = true; self.navigationController?.pushViewController(vc, animated: true) default: return } }) .disposed(by: rx.disposeBag) // 强制升级 viewModel.mandatoryUpdate .subscribe(onNext: { [weak self] viewModel in guard let `self` = self, let temp = viewModel else { return } showAlert(self, MultiLanguageKey_FB.updateConfirmFB.localized, confirmText: "YES") { self.navigator.show(segue: .firmwareUpdate(viewModel: temp), sender: self) } }) .disposed(by: rx.disposeBag) } override func handleEvent() { fbbindingBtn.rx.tap .subscribe(onNext: { [weak self] _ in guard let `self` = self else { return } self.navigator.show(segue:.binding(viewModel: BindingViewModels()), sender: self) }) .disposed(by: rx.disposeBag) } private func monitor() { /// 指令成功失败监听 Observable.of(kNotificationCenter.rx.notification(Notification.Name(rawValue: CmdSuccess)), kNotificationCenter.rx.notification(Notification.Name(rawValue: CmdTimeout))) .merge() .subscribe(onNext: { [weak self] notification in guard let `self` = self, let cmd = notification.object as? BleCMD_FireBoltt else { return } let isSuccess = notification.name.rawValue == CmdSuccess switch cmd { case .cameraSwitch: if isSuccess { if self.isCamera { self.openAndtoTakePhoto() } return } SVProgressHUD.showSuccess(withStatus: MultiLanguageKey_FB.setFailFB.localized) default: break } }) .disposed(by: rx.disposeBag) // 设备上报指令 kNotificationCenter.rx.notification(Notification.Name(rawValue: "DeviceControlNotification"), object: nil) .subscribe(onNext: { [weak self] notification in guard let `self` = self, let cmdInt = notification.object as? Int, let cmd = BleCMD_FireBoltt(rawValue: cmdInt) else { return } let data = notification.userInfo?["data"] as! NSData let contentData = data.subdata(with: NSMakeRange(13, data.length - 13)) as NSData switch cmd { case .cameraSwitch: // 0:退出 1:打开相机 //2:拍照 let state = contentData.bytes.load(as: Int.self) switch state { case 0: guard self.isOpenCamera else { return } self.isOpenCamera = false self.imagePickerController?.dismiss(animated: true, completion: nil) case 1: if self.isOpenCamera == true { return } self.openAndtoTakePhoto() case 2: guard self.isOpenCamera else { return } // source type 必须在实例化UIImagePickerController后面设置 if UIImagePickerController.isSourceTypeAvailable(.camera) { self.imagePickerController?.sourceType = UIImagePickerController.SourceType.camera self.imagePickerController?.selfTakePicture() } default: break } default: break } }) .disposed(by: rx.disposeBag) } /// 打开相机 private func openAndtoTakePhoto() { isCamera = false let permission = handleCameraPower(viewController: self) guard permission else { return } self.imagePickerController = CustomPickerControllers() self.imagePickerController?.delegate = self self.imagePickerController?.allowsEditing = true; imagePickerController?.selectedClosure = { [weak self] (selectedType) in guard let `self` = self else { return } if selectedType == ImagePickerButtonType.cancelCamera { self.imagePickerController?.dismiss(animated: true, completion: nil) if BluetoothService.shared.checkBleCmdEnable(isShow: true) { BluetoothService.shared.cameraSwitchWithBleCmdType(isOpen: false) } self.isOpenCamera = false } } if UIImagePickerController.isSourceTypeAvailable(.camera) { self.imagePickerController?.sourceType = UIImagePickerController.SourceType.camera self.imagePickerController?.delegate = self isOpenCamera = true if let pickerVC = self.imagePickerController { self.present(pickerVC, animated: true, completion: nil) } }else { let alertVC = UIAlertController.init(title: "提示", message: "无可用摄像头", preferredStyle: .alert) let sureAction = UIAlertAction.init(title: "确定", style: .default, handler: nil) alertVC.addAction(sureAction) self.present(alertVC, animated: true, completion: nil) } } @objc func unBindingTouch(){ print("解绑") showAlert(self, MultiLanguageKey_FB.unbindingTipFB.localized, cancelText: MultiLanguageKey_FB.cancelFB.localized, confirmText: MultiLanguageKey_FB.confirmFB.localized) { (result) in if result { UserDefaultsManagerFrieBoltt.deleteDeviceInfo() BluetoothFireBoltt.shareInstance()?.disConnectedCurrenDevice(true) kNotificationCenter.post(name: NSNotification.Name(UnBindingDeviceFireBoltt), object: nil) } } } } // MARK: - 相机相册协议 extension DeviceViewControllers: UIImagePickerControllerDelegate, UINavigationControllerDelegate { func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { SystemAuthorityFireBoltt.shared.getPhotoAuthority { [weak self] (result) in if result { if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage { // 保存图片至相册 UIImageWriteToSavedPhotosAlbum(image, self, nil, nil) } } } } func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { isOpenCamera = false isCamera = false if BluetoothService.shared.checkBleCmdEnable(isShow: true) { BluetoothService.shared.cameraSwitchWithBleCmdType(isOpen: false) } picker.dismiss(animated: true, completion: nil) } func handleCameraPower(viewController: UIViewController) -> Bool { let authStatus = AVCaptureDevice.authorizationStatus(for: AVMediaType.video) if authStatus == .denied || authStatus == .restricted { let alertVC = UIAlertController.init(title: MultiLanguageKey_FB.tipFB.localized, message: MultiLanguageKey_FB.carmaPowerFB.localized, preferredStyle: .alert) let cancelAction = UIAlertAction.init(title: MultiLanguageKey_FB.cancelFB.localized, style: UIAlertAction.Style.cancel, handler: nil) let goToAction = UIAlertAction.init(title: MultiLanguageKey_FB.gotoFB.localized, style: UIAlertAction.Style.default) { (action) in if let url = URL(string: UIApplication.openSettingsURLString) { if UIApplication.shared.canOpenURL(url) { UIApplication.shared.openURL(url) } } } alertVC.addAction(cancelAction) alertVC.addAction(goToAction) viewController.present(alertVC, animated: true, completion: nil) return false } return true } } extension DeviceViewControllers: UITableViewDelegate { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { tableView.deselectRow(at: indexPath, animated: true) } }