Advance UIKit rewrite with AMap integration and core UI modules.

Integrate高德 SDK with simulator-safe build flags, add map views for operating area and punch points, refactor main tabs and key feature screens to UIKit with Diffable lists, and document Swift concurrency defaults in AGENTS.md.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-26 15:16:12 +08:00
parent 9edf993432
commit d99a5b1bf8
124 changed files with 5195 additions and 1536 deletions

View File

@ -32,6 +32,7 @@ final class OrderCodeScannerViewController: UIViewController {
private let scannerController = OrderScannerCaptureViewController()
/// UI
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .black
@ -49,6 +50,7 @@ final class OrderCodeScannerViewController: UIViewController {
#endif
}
/// embed
private func embedScanner() {
scannerController.onScanResult = { [weak self] result in
self?.onScanResult?(result)
@ -77,6 +79,7 @@ final class OrderCodeScannerViewController: UIViewController {
}
}
/// UnavailablePlaceholder
private func showUnavailablePlaceholder() {
let stack = UIStackView()
stack.axis = .vertical
@ -109,6 +112,7 @@ final class OrderCodeScannerViewController: UIViewController {
}
}
/// close
@objc private func closeTapped() {
dismiss(animated: true)
}
@ -145,6 +149,7 @@ final class OrderScannerCaptureViewController: UIViewController, AVCaptureMetada
return button
}()
/// UI
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .black
@ -152,17 +157,20 @@ final class OrderScannerCaptureViewController: UIViewController, AVCaptureMetada
checkPermissionAndStart()
}
/// frame UI
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
previewLayer?.frame = view.layer.bounds
}
///
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
updateTorch(enabled: false)
stopSession()
}
/// check
private func checkPermissionAndStart() {
switch AVCaptureDevice.authorizationStatus(for: .video) {
case .authorized:
@ -185,6 +193,7 @@ final class OrderScannerCaptureViewController: UIViewController, AVCaptureMetada
}
}
/// Session
private func startSession() {
hasFinishedScan = false
guard !session.isRunning else { return }
@ -199,11 +208,13 @@ final class OrderScannerCaptureViewController: UIViewController, AVCaptureMetada
}
}
/// Session
private func stopSession() {
guard session.isRunning else { return }
session.stopRunning()
}
/// ScannerButton
private static func makeScannerButton(title: String) -> UIButton {
var config = UIButton.Configuration.filled()
config.title = title
@ -213,6 +224,7 @@ final class OrderScannerCaptureViewController: UIViewController, AVCaptureMetada
return UIButton(configuration: config)
}
/// Session
private func configureSession() throws {
if previewLayer != nil { return }
guard let videoDevice = AVCaptureDevice.default(for: .video) else {
@ -242,6 +254,7 @@ final class OrderScannerCaptureViewController: UIViewController, AVCaptureMetada
torchButton.isEnabled = videoDevice.hasTorch
}
/// metadataOutput
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
guard !hasFinishedScan else { return }
guard let metadataObject = metadataObjects.first as? AVMetadataMachineReadableCodeObject,
@ -253,6 +266,7 @@ final class OrderScannerCaptureViewController: UIViewController, AVCaptureMetada
onScanResult?(.success(code))
}
/// Controls UI
private func setupControls() {
view.addSubview(scanFrameView)
view.addSubview(torchButton)
@ -273,10 +287,12 @@ final class OrderScannerCaptureViewController: UIViewController, AVCaptureMetada
}
}
/// toggleTorch
@objc private func toggleTorch() {
updateTorch(enabled: !(videoDevice?.isTorchActive ?? false))
}
/// Torch
private func updateTorch(enabled: Bool) {
guard let device = videoDevice, device.hasTorch else { return }
do {
@ -293,6 +309,7 @@ final class OrderScannerCaptureViewController: UIViewController, AVCaptureMetada
}
}
/// restart
@objc private func restartScan() {
hasFinishedScan = false
updateTorch(enabled: false)