// // DeviceViewControllers.swift // Lookfit // // 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 noDeviceImg: UIImageView = { return UIImageView(image: R.image.default_device()) }() lazy var headerView: DeviceHeaderView = { let view = DeviceHeaderView() return view }() lazy var bindingTipLabel: UILabel = { let label = UILabel() label.text = MultiLanguageKey.noDeviceTip.localized label.textAlignment = .center label.font = SystemRegularFont(14) label.textColor = kHexColor(0x858585) return label }() lazy var bindingBtn: 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 = 22.5 btn.layer.masksToBounds = true btn.setTitle(MultiLanguageKey.bindingDevice.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.mineDevice.localized tableViewStyle = .grouped tableView.backgroundColor = kHexColor(0xFAFAFA) view.addSubview(noDeviceImg) view.addSubview(bindingTipLabel) view.addSubview(bindingBtn) view.bringSubviewToFront(tableView) // 头视图 headerView.backgroundColor = .white tableView.tableHeaderView = headerView 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() } bindingTipLabel.snp.makeConstraints { (make) in make.top.equalTo(noDeviceImg.snp.bottom).offset(kScaleHeight(15)) make.centerX.equalToSuperview() } bindingBtn.snp.makeConstraints { (make) in make.bottom.equalTo(-50) make.width.equalTo(kScaleWidth(190)) make.height.equalTo(kScaleWidth(45)) make.centerX.equalToSuperview() } headerView.snp.makeConstraints { (make) in make.width.equalTo(kScreenW) make.height.equalTo(kScaleWidth(85) + 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.loadFuncation() }) .disposed(by: cell.cellDisposeBag) return cell }) viewModel.datasource .bind(to: tableView.rx.items(dataSource: rxDataSource)) .disposed(by: rx.disposeBag) // 头视图 viewModel.deviceName .bind(to: headerView.deviceNameLabel.rx.text) .disposed(by: rx.disposeBag) let connectState = viewModel.connectState.share(replay: 1) connectState .bind(to: headerView.statusBtn.rx.isSelected) .disposed(by: rx.disposeBag) viewModel.powerState .bind(to: headerView.powerBtn.rx.image(for: .normal)) .disposed(by: rx.disposeBag) // 设备未连接处理 connectState .map { !$0 } .bind(to: headerView.syncBtn.rx.isHidden) .disposed(by: rx.disposeBag) // 绑定 let input = DeviceViewModels.Input(syncData: headerView.syncBtn.rx.tap.asObservable()) let output = viewModel.transform(input: input) output.syncState .drive(headerView.syncBtn.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: // 获取相机权限 SystemAuthority.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.unbindingTip.localized, cancelText: MultiLanguageKey.cancel.localized, confirmText: MultiLanguageKey.confirm.localized) { (result) in if result { UserDefaultsManager.deleteDeviceInfo() Bluetooth.shareInstance()?.disConnectedCurrenDevice(true) kNotificationCenter.post(name: NSNotification.Name(UnBindingDevice), 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.updateConfirm.localized, confirmText: "YES") { self.navigator.show(segue: .firmwareUpdate(viewModel: temp), sender: self) } }) .disposed(by: rx.disposeBag) } override func handleEvent() { bindingBtn.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 else { return } let isSuccess = notification.name.rawValue == CmdSuccess switch cmd { case .cameraSwitch: if isSuccess { if self.isCamera { self.openAndtoTakePhoto() } return } SVProgressHUD.showSuccess(withStatus: MultiLanguageKey.setFail.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(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) } } } // MARK: - 相机相册协议 extension DeviceViewControllers: UIImagePickerControllerDelegate, UINavigationControllerDelegate { func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { SystemAuthority.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.tip.localized, message: MultiLanguageKey.carmaPower.localized, preferredStyle: .alert) let cancelAction = UIAlertAction.init(title: MultiLanguageKey.cancel.localized, style: UIAlertAction.Style.cancel, handler: nil) let goToAction = UIAlertAction.init(title: MultiLanguageKey.goto.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) } }