252 lines
9.4 KiB
Swift
252 lines
9.4 KiB
Swift
import UIKit
|
|
import os.log
|
|
import AVFoundation
|
|
import PKHUD
|
|
import AutoCatCore
|
|
import SwiftLocation
|
|
import CoreLocation
|
|
import SwiftUI
|
|
|
|
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|
|
|
var window: UIWindow?
|
|
|
|
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
|
|
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
|
|
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
|
|
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
|
|
|
|
var number: String?
|
|
|
|
if let activity = connectionOptions.userActivities.first {
|
|
|
|
if let url = activity.webpageURL {
|
|
if let param = URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems?.first, let token = param.value {
|
|
if let jwt = JWT<NumberPayload>(string: token) {
|
|
number = jwt.payload.plateNumber
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Task {
|
|
try? await registerServices()
|
|
setupRootController(scene: scene, openReport: number)
|
|
}
|
|
}
|
|
|
|
func registerServices() async throws {
|
|
|
|
let container = ServiceContainer.shared
|
|
|
|
let settingsService = await SettingsService()
|
|
|
|
container.register(SettingsServiceProtocol.self, instance: settingsService)
|
|
|
|
let apiService = ApiService(settingsService: settingsService)
|
|
container.register(ApiServiceProtocol.self, instance: apiService)
|
|
|
|
let locationService = LocationService(
|
|
geocoder: CLGeocoder(),
|
|
locationManager: Location(),
|
|
settingsService: settingsService
|
|
)
|
|
|
|
container.register(LocationServiceProtocol.self, instance: locationService)
|
|
|
|
let storageService = try await StorageService(settingsService: settingsService)
|
|
container.register(StorageServiceProtocol.self, instance: storageService)
|
|
|
|
let vehicleService = VehicleService(apiService: apiService,
|
|
storageService: storageService,
|
|
locationService: locationService)
|
|
container.register(VehicleServiceProtocol.self, instance: vehicleService)
|
|
|
|
let audioRecordService = AudioRecordService()
|
|
container.register(AudioRecordServiceProtocol.self, instance: audioRecordService)
|
|
|
|
let vehicleRecordService = VehicleRecordService(
|
|
recordService: audioRecordService,
|
|
locationService: locationService,
|
|
settingsService: settingsService
|
|
)
|
|
container.register(VehicleRecordServiceProtocol.self, instance: vehicleRecordService)
|
|
container.register(RecordPlayerServiceProtocol.self, instance: RecordPlayerService())
|
|
}
|
|
|
|
func setupRootController(scene: UIScene, openReport number: String?) {
|
|
guard let windowScene = (scene as? UIWindowScene) else {
|
|
return
|
|
}
|
|
|
|
self.window = UIWindow(windowScene: windowScene)
|
|
let storyboard = UIStoryboard(name: "Main", bundle: nil)
|
|
|
|
let settingsService = ServiceContainer.shared.resolve(SettingsServiceProtocol.self)
|
|
|
|
if settingsService.user.token.isEmpty {
|
|
let coordinator = AuthCoordinator(window: self.window)
|
|
self.window?.rootViewController = coordinator.start()
|
|
//self.window?.rootViewController = storyboard.instantiateViewController(identifier: "AuthController")
|
|
} else {
|
|
self.window?.rootViewController = storyboard.instantiateViewController(identifier: "MainSplitController")
|
|
if let number {
|
|
Task { await openReport(with: number) }
|
|
}
|
|
}
|
|
|
|
#if targetEnvironment(macCatalyst)
|
|
|
|
let toolbar = NSToolbar(identifier: "main")
|
|
toolbar.delegate = self
|
|
toolbar.displayMode = .iconOnly
|
|
|
|
if let titlebar = windowScene.titlebar {
|
|
titlebar.toolbar = toolbar
|
|
if #available(macCatalyst 14.0, *) {
|
|
titlebar.toolbarStyle = .unifiedCompact
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
self.window?.makeKeyAndVisible()
|
|
}
|
|
|
|
func sceneDidDisconnect(_ scene: UIScene) {
|
|
// Called as the scene is being released by the system.
|
|
// This occurs shortly after the scene enters the background, or when its session is discarded.
|
|
// Release any resources associated with this scene that can be re-created the next time the scene connects.
|
|
// The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
|
|
}
|
|
|
|
func sceneDidBecomeActive(_ scene: UIScene) {
|
|
// Called when the scene has moved from an inactive state to an active state.
|
|
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
|
|
}
|
|
|
|
func sceneWillResignActive(_ scene: UIScene) {
|
|
// Called when the scene will move from an active state to an inactive state.
|
|
// This may occur due to temporary interruptions (ex. an incoming phone call).
|
|
}
|
|
|
|
func sceneWillEnterForeground(_ scene: UIScene) {
|
|
// Called as the scene transitions from the background to the foreground.
|
|
// Use this method to undo the changes made on entering the background.
|
|
}
|
|
|
|
func sceneDidEnterBackground(_ scene: UIScene) {
|
|
// Called as the scene transitions from the foreground to the background.
|
|
// Use this method to save data, release shared resources, and store enough scene-specific state information
|
|
// to restore the scene back to its current state.
|
|
}
|
|
|
|
func windowScene(_ windowScene: UIWindowScene, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
|
|
|
|
}
|
|
|
|
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
|
|
|
|
if let url = userActivity.webpageURL {
|
|
if let param = URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems?.first, let token = param.value {
|
|
if let jwt = JWT<NumberPayload>(string: token) {
|
|
Task { await self.openReport(with: jwt.payload.plateNumber) }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func openReport(with number: String) async {
|
|
guard let rootController = self.window?.rootViewController else { return }
|
|
|
|
let apiService: ApiServiceProtocol = ServiceContainer.shared.resolve(ApiServiceProtocol.self)
|
|
|
|
do {
|
|
HUD.show(.progress)
|
|
let vehicle = try await apiService.getReport(for: number)
|
|
|
|
Task {
|
|
let screen = ReportScreen(vehicle: vehicle, isPersistent: false, onUpdate: { _ in })
|
|
let controller = UIHostingController(rootView: screen)
|
|
let navController = UINavigationController(rootViewController: controller)
|
|
rootController.present(navController, animated: true)
|
|
}
|
|
|
|
HUD.hide()
|
|
} catch {
|
|
HUD.show(error: error)
|
|
}
|
|
}
|
|
}
|
|
|
|
#if targetEnvironment(macCatalyst)
|
|
|
|
extension NSToolbarItem.Identifier {
|
|
|
|
static let addNumber = NSToolbarItem.Identifier("pro.aliencat.add.number")
|
|
}
|
|
|
|
extension SceneDelegate: NSToolbarDelegate {
|
|
|
|
func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
|
|
let identifiers: [NSToolbarItem.Identifier] = [
|
|
.addNumber
|
|
]
|
|
return identifiers
|
|
}
|
|
|
|
func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
|
|
return toolbarDefaultItemIdentifiers(toolbar)
|
|
}
|
|
|
|
func toolbar(_ toolbar: NSToolbar,
|
|
itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier,
|
|
willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? {
|
|
|
|
var toolbarItem: NSToolbarItem?
|
|
|
|
switch itemIdentifier {
|
|
case .addNumber:
|
|
let item = NSToolbarItem(itemIdentifier: itemIdentifier)
|
|
item.image = UIImage(systemName: "plus")
|
|
item.label = "Add"
|
|
item.target = self
|
|
item.action = #selector(showAddNumberPanel)
|
|
toolbarItem = item
|
|
|
|
default:
|
|
toolbarItem = nil
|
|
}
|
|
|
|
return toolbarItem
|
|
}
|
|
|
|
@objc func showAddNumberPanel() {
|
|
let controller = NewNumberController()
|
|
controller.preferredContentSize = CGSize(width: 400, height: 350)
|
|
controller.onCheck = { number in
|
|
controller.dismiss(animated: true) { [weak self] in
|
|
self?.checkNewNumber(number)
|
|
}
|
|
}
|
|
|
|
self.window?.rootViewController?.present(controller, animated: true)
|
|
}
|
|
|
|
func checkNewNumber(_ number: String) {
|
|
guard let split = self.window?.rootViewController as? MainSplitController,
|
|
let tabvc = split.viewControllers.first as? MainTabController
|
|
else {
|
|
return
|
|
}
|
|
|
|
tabvc.selectedIndex = 0
|
|
|
|
Task {
|
|
await tabvc.historyViewModel?.checkNewNumber(number)
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|