jsdw_ios/QuickLocation/Section/AppRestrict/AppRestrictVC.swift

142 lines
4.6 KiB
Swift

//
// AppRestrictVC.swift
// QuickLocation
//
import FamilyControls
import UIKit
import RxSwift
import RxCocoa
import ManagedSettings
@available(iOS 16.0, *)
final class AppRestrictVC: BaseViewController {
private var rootView: AppRestrictView!
private var tokens: [ApplicationToken] = []
private var linkingToken: ApplicationToken?
override func loadView() {
rootView = AppRestrictView(frame: UIScreen.main.bounds)
view = rootView
}
override func viewDidLoad() {
super.viewDidLoad()
rootView.tableView.dataSource = self
rootView.tableView.delegate = self
rootView.tableView.register(AppRestrictCell.self, forCellReuseIdentifier: AppRestrictCell.reuseId)
bind()
reload()
}
private func bind() {
rootView.navView.onBackTapped = { [weak self] in
self?.navigationController?.popViewController(animated: true)
}
rootView.addBtn.rx.tap.subscribe(onNext: { [weak self] in
self?.addApps()
}).disposed(by: disposeBag)
}
private func reload() {
tokens = AppRestrictManager.shared.applicationTokens
rootView.setListVisible(!tokens.isEmpty, rowCount: tokens.count)
rootView.tableView.reloadData()
}
private func addApps() {
Task { @MainActor in
do {
if !AppRestrictManager.shared.isAuthorized {
try await AppRestrictManager.shared.requestAuthorization()
}
guard AppRestrictManager.shared.isAuthorized else {
DLToast.show(text: "需要屏幕使用时间权限")
return
}
let presenter = FamilyActivityPickerPresenter(selection: AppRestrictManager.shared.selection)
presenter.onComplete = { [weak self] selection in
AppRestrictManager.shared.mergeSelection(selection)
self?.reload()
}
present(presenter, animated: false)
} catch {
DLToast.show(text: "授权失败,请在设置中开启屏幕使用时间权限")
}
}
}
private func openLink(for token: ApplicationToken) {
linkingToken = token
let vc = SelectActivityVC()
vc.onSelect = { [weak self] item in
guard let self, let token = self.linkingToken else { return }
AppRestrictManager.shared.link(
catalogId: item.id,
token: token,
displayName: item.name,
iconURL: item.iconURL
)
self.linkingToken = nil
self.reload()
}
let nav = UINavigationController(rootViewController: vc)
present(nav, animated: true)
}
private func deleteApp(_ token: ApplicationToken) {
AppRestrictManager.shared.removeApplication(token)
reload()
}
}
@available(iOS 16.0, *)
extension AppRestrictVC: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
tokens.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: AppRestrictCell.reuseId, for: indexPath) as! AppRestrictCell
let token = tokens[indexPath.row]
let catalog = AppRestrictManager.shared.catalogItem(for: token)
cell.configure(token: token, catalog: catalog)
cell.onPair = { [weak self] in
self?.openLink(for: token)
}
cell.onDelete = { [weak self] in
self?.deleteApp(token)
}
return cell
}
}
/// Fallback when system is below iOS 16.
final class AppRestrictUnsupportedVC: BaseViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
let nav = BaseNavigationView(title: "应用配对库")
view.addSubview(nav)
nav.layoutChain.top().edgesHorzontal().height(kNaviHeight)
nav.onBackTapped = { [weak self] in
self?.navigationController?.popViewController(animated: true)
}
let lab = UILabel()
lab.text = "该功能需要 iOS 16 及以上系统"
lab.textAlignment = .center
lab.textColor = UIColor(hexStr: "#767676")
view.addSubview(lab)
lab.layoutChain.center()
}
}
enum AppRestrictFactory {
static func make() -> UIViewController {
if #available(iOS 16.0, *) {
return AppRestrictVC()
}
return AppRestrictUnsupportedVC()
}
}