jsdw_ios/QuickLocation/Section/Scan/ScanVC.swift

129 lines
4.0 KiB
Swift

//
// ScanVC.swift
// QuickLocation
//
import UIKit
import AVFoundation
import RxSwift
class ScanVC: BaseViewController {
override var isNavigationBarHidden: Bool { true }
override var preferredStatusBarStyle: UIStatusBarStyle { .lightContent }
private var rootView: CameraCaptureView!
private let scanDoneAction: ((String) -> Void)?
private var isHandling = false
override func loadView() {
rootView = CameraCaptureView(mode: .scan)
view = rootView
}
override func viewDidLoad() {
super.viewDidLoad()
rootView.onClose = { [weak self] in
self?.closeCapture()
}
rootView.onScan = { [weak self] text in
self?.handleScanResult(text: text)
}
rootView.onOpenAlbum = { [weak self] in
self?.openAlbum()
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
isHandling = false
rootView.startSession()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
rootView.stopSession()
}
init(scanDoneAction: ((String) -> Void)? = nil) {
self.scanDoneAction = scanDoneAction
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func closeCapture() {
if presentingViewController != nil {
dismiss(animated: true)
} else {
navigationController?.popViewController(animated: true)
}
}
private func handleScanResult(text: String) {
guard !isHandling else { return }
isHandling = true
rootView.stopSession()
if let scanDoneAction {
scanDoneAction(text)
closeCapture()
return
}
requestJoinGroup(code: text)
}
private func requestJoinGroup(code: String) {
DLToast.showLoading()
GroupService.operate(opType: "join", requestData: ["share_code": code]).subscribe(onNext: { response in
DLToast.showSuccess(text: response.message ?? "申请成功") {
AppRouter.shared.popOrDismiss()
}
}, onError: { [weak self] _ in
DLToast.showError(text: "无法识别该二维码")
DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
self?.isHandling = false
self?.rootView.startSession()
}
}).disposed(by: disposeBag)
}
private func openAlbum() {
guard UIImagePickerController.isSourceTypeAvailable(.photoLibrary) else { return }
let picker = UIImagePickerController()
picker.sourceType = .photoLibrary
picker.delegate = self
present(picker, animated: true)
}
private func decodeQR(from image: UIImage) {
guard let ciImage = CIImage(image: image) else {
DLToast.show(text: "无法识别二维码")
isHandling = false
return
}
let detector = CIDetector(ofType: CIDetectorTypeQRCode, context: nil, options: [CIDetectorAccuracy: CIDetectorAccuracyHigh])
let features = detector?.features(in: ciImage) ?? []
if let qr = features.first as? CIQRCodeFeature, let text = qr.messageString, !text.isEmpty {
handleScanResult(text: text)
} else {
DLToast.show(text: "未识别到二维码")
isHandling = false
}
}
}
extension ScanVC: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
picker.dismiss(animated: true)
if let image = info[.originalImage] as? UIImage {
decodeQR(from: image)
}
}
}