From 45137844843f5209a7ea75b5fbd8e4fc135f4486 Mon Sep 17 00:00:00 2001 From: Fin Date: Sat, 28 Nov 2020 19:40:23 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=20HomeViewModel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Common/Client.swift | 25 +++++----- Controller/HomeViewController.swift | 71 +++++++++++++++-------------- Controller/HomeViewModel.swift | 52 +++++++++++++++++---- 3 files changed, 95 insertions(+), 53 deletions(-) diff --git a/Common/Client.swift b/Common/Client.swift index f48a3b8..62f4938 100644 --- a/Common/Client.swift +++ b/Common/Client.swift @@ -8,6 +8,9 @@ import UIKit import UserNotifications +import RxSwift +import RxCocoa + class Client: NSObject { static let shared = Client() private override init() { @@ -51,33 +54,33 @@ class Client: NSObject { case serverError } - var state = ClienState.ok { - didSet{ - NotificationCenter.default.post(name: Notification.Name(rawValue: "ClientStateChangeds"), object: nil) - } - } + var state = BehaviorRelay(value: .ok) + var dispose:Disposable? func bindDeviceToken(){ if let token = Settings[.deviceToken] , token.count > 0{ - BarkApi.provider + dispose?.dispose() + + dispose = BarkApi.provider .request(.register( key: key, devicetoken: token)) .filterResponseError() - .subscribe(onNext: { (json) in + .map { (json) -> ClienState in switch json { case .success(let json): if let key = json["data","key"].rawString() { Client.shared.key = key - self.state = .ok + return .ok } else{ - self.state = .serverError + return .serverError } case .failure: - self.state = .serverError + return .serverError } - }).disposed(by: rx.disposeBag) + } + .bind(to: state) } } diff --git a/Controller/HomeViewController.swift b/Controller/HomeViewController.swift index 7fbd6b3..98f1da8 100644 --- a/Controller/HomeViewController.swift +++ b/Controller/HomeViewController.swift @@ -77,7 +77,8 @@ class HomeViewController: BaseViewController { viewDidAppear: self.rx.methodInvoked(#selector(viewDidAppear(_:))) .map{ _ in () } .asDriver(onErrorDriveWith: .empty()), - start: self.startButton.rx.tap.asDriver() + start: self.startButton.rx.tap.asDriver(), + clientState: Client.shared.state.asDriver() ) ) @@ -89,23 +90,29 @@ class HomeViewController: BaseViewController { return UITableViewCell() } + //标题 output.title .drive(self.navigationItem.rx.title) .disposed(by: rx.disposeBag) + //TableView数据源 output.previews .drive(self.tableView.rx.items(dataSource: dataSource)) .disposed(by: rx.disposeBag) - output.push.drive(onNext: {[weak self] viewModel in - self?.pushViewModel(viewModel: viewModel) - }).disposed(by: rx.disposeBag) + //跳转到对应页面 + output.push + .drive(onNext: {[weak self] viewModel in + self?.pushViewModel(viewModel: viewModel) + }) + .disposed(by: rx.disposeBag) - output.clienState.drive(onNext: {[weak self] state in - Client.shared.state = state - self?.refreshState() - }).disposed(by: rx.disposeBag) + //通过ping服务器,判断 clienState + output.clienStateChanged + .drive(Client.shared.state) + .disposed(by: rx.disposeBag) + //根据通知权限,设置是否隐藏注册按钮、显示示例预览列表 output.tableViewHidden .map{ !$0 } .drive(self.tableView.rx.isHidden) @@ -114,26 +121,39 @@ class HomeViewController: BaseViewController { .drive(self.startButton.rx.isHidden) .disposed(by: rx.disposeBag) + //弹出提示 output.showSnackbar .drive(onNext: {[weak self] text in self?.showSnackbar(text: text) }) .disposed(by: rx.disposeBag) + //startButton是否可点击 output.startButtonEnable .drive(self.startButton.rx.isEnabled) .disposed(by: rx.disposeBag) - output.copy.drive(onNext: {[weak self] text in - UIPasteboard.general.string = text - self?.showSnackbar(text: NSLocalizedString("Copy")) - }) - .disposed(by: rx.disposeBag) + //复制文本 + output.copy + .drive(onNext: {[weak self] text in + UIPasteboard.general.string = text + self?.showSnackbar(text: NSLocalizedString("Copy")) + }) + .disposed(by: rx.disposeBag) - output.preview.drive(onNext: { url in - UIApplication.shared.open(url, options: [:], completionHandler: nil) - }) - .disposed(by: rx.disposeBag) + //预览 + output.preview + .drive(onNext: { url in + UIApplication.shared.open(url, options: [:], completionHandler: nil) + }) + .disposed(by: rx.disposeBag) + + //原样刷新 TableView + output.reloadData + .drive(onNext: {[weak self] in + self?.tableView.reloadData() + }) + .disposed(by: rx.disposeBag) } @@ -155,20 +175,3 @@ class HomeViewController: BaseViewController { } } - -extension HomeViewController { - @objc func refreshState() { - switch Client.shared.state { - case .ok: - if let url = URL(string: ServerManager.shared.currentAddress) { - if url.scheme?.lowercased() != "https" { - self.showSnackbar(text: NSLocalizedString("InsecureConnection")) - } - self.tableView.reloadData() - } - case .serverError: - self.showSnackbar(text: NSLocalizedString("ServerError")) - default: break; - } - } -} diff --git a/Controller/HomeViewModel.swift b/Controller/HomeViewModel.swift index 016bf30..7ce8fcc 100644 --- a/Controller/HomeViewModel.swift +++ b/Controller/HomeViewModel.swift @@ -15,21 +15,23 @@ import UserNotifications class HomeViewModel: ViewModel, ViewModelType { struct Input { - let addCustomServerTap:Driver - let historyMessageTap:Driver - let viewDidAppear:Driver - let start:Driver + let addCustomServerTap: Driver + let historyMessageTap: Driver + let viewDidAppear: Driver + let start: Driver + let clientState: Driver } struct Output { let previews: Driver<[SectionModel]> let push: Driver - let title:Driver - let clienState: Driver + let title: Driver + let clienStateChanged: Driver let tableViewHidden: Driver let showSnackbar: Driver let startButtonEnable: Driver let copy: Driver let preview: Driver + let reloadData: Driver } let previews:[PreviewModel] = { @@ -72,6 +74,8 @@ class HomeViewModel: ViewModel, ViewModelType { ] }() + var currentState = Client.ClienState.ok + func transform(input: Input) -> Output { let sectionModel = SectionModel( model: "previews", @@ -143,16 +147,48 @@ class HomeViewModel: ViewModel, ViewModelType { .bind(to: showSnackbar) .disposed(by: rx.disposeBag) + //client state 变化时,发出相应错误提醒 + input.clientState.drive(onNext: { state in + switch state { + case .ok: + if let url = URL(string: ServerManager.shared.currentAddress) { + if url.scheme?.lowercased() != "https" { + showSnackbar.accept(NSLocalizedString("InsecureConnection")) + } + } + case .serverError: + showSnackbar.accept(NSLocalizedString("ServerError")) + default: break; + } + }) + .disposed(by: rx.disposeBag) + + //reloadData + let reloadData = input.clientState.filter {[weak self] (state) -> Bool in + if let strongSelf = self { + if state != strongSelf.currentState { + strongSelf.currentState = state + return true + } + } + return false + } + .map { _ in + () + } + + return Output( previews:Driver.just([sectionModel]), push: Driver.merge(customServer,messageHistory,noticeTap), title: Driver.of(URL(string: ServerManager.shared.currentAddress)?.host ?? ""), - clienState: clienState.asDriver(onErrorDriveWith: .empty()), + clienStateChanged: clienState.asDriver(onErrorDriveWith: .empty()), tableViewHidden: tableViewHidden, showSnackbar: showSnackbar.asDriver(onErrorDriveWith: .empty()), startButtonEnable: Driver.just(true), copy: Driver.merge(sectionModel.items.map{ $0.copy.asDriver(onErrorDriveWith: .empty()) }), - preview: Driver.merge(sectionModel.items.map{ $0.preview.asDriver(onErrorDriveWith: .empty()) }) + preview: Driver.merge(sectionModel.items.map{ $0.preview.asDriver(onErrorDriveWith: .empty()) }), + reloadData: reloadData ) }