import UIKit import Flutter import FirebaseCore import CarPlay import CoreLocation @main @objc class AppDelegate: FlutterAppDelegate { let locationManager = CLLocationManager() override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { // Now continue with the rest of the app initialization. FirebaseApp.configure() GeneratedPluginRegistrant.register(with: self) // التأكد من أن الجهاز غير مخترق قبل تشغيل التطبيق if SecurityChecks.isDeviceCompromised() { showSecurityAlert() return false } // تهيئة قنوات الاتصال مع Flutter setupMethodChannel() setupCarNavigationChannel() // ضبط مدير الموقع لمتابعة تغييرات الأذونات locationManager.delegate = self locationManager.requestWhenInUseAuthorization() return super.application(application, didFinishLaunchingWithOptions: launchOptions) } // MARK: - CarPlay Connection (Non-Scene API) override func application( _ application: UIApplication, didConnectCarInterfaceController interfaceController: CPInterfaceController, to window: CPWindow ) { let sceneDelegate = CarPlaySceneDelegate() sceneDelegate.interfaceController = interfaceController let mapTemplate = CPMapTemplate() sceneDelegate.mapTemplate = mapTemplate mapTemplate.guidanceBackgroundStyle = .light interfaceController.setRootTemplate(mapTemplate, animated: true) CarPlayState.shared.sceneDelegate = sceneDelegate } override func application( _ application: UIApplication, didDisconnectCarInterfaceController interfaceController: CPInterfaceController, from window: CPWindow ) { CarPlayState.shared.sceneDelegate?.stopNavigation() CarPlayState.shared.sceneDelegate = nil } // MARK: - تهيئة القناة بين Swift و Flutter func setupMethodChannel() { guard let controller = window?.rootViewController as? FlutterViewController else { return } let channel = FlutterMethodChannel(name: "com.siro.siro_driver/security", binaryMessenger: controller.binaryMessenger) channel.setMethodCallHandler { call, result in switch call.method { case "isNativeRooted": result(SecurityChecks.isDeviceCompromised()) default: result(FlutterMethodNotImplemented) } } } // MARK: - Car Navigation Method Channel func setupCarNavigationChannel() { guard let controller = window?.rootViewController as? FlutterViewController else { return } let channel = FlutterMethodChannel( name: "com.siro.siro_driver/car_navigation", binaryMessenger: controller.binaryMessenger ) channel.setMethodCallHandler { [weak self] call, result in guard let self = self else { return } switch call.method { case "updateNavState": let lat = (call.arguments as? [String: Any])?["lat"] as? Double ?? 0 let lng = (call.arguments as? [String: Any])?["lng"] as? Double ?? 0 let bearing = (call.arguments as? [String: Any])?["bearing"] as? Double ?? 0 let speed = (call.arguments as? [String: Any])?["speed"] as? Double ?? 0 let instruction = (call.arguments as? [String: Any])?["instruction"] as? String ?? "" let distanceToStep = (call.arguments as? [String: Any])?["distanceToStep"] as? Double ?? 0 let eta = (call.arguments as? [String: Any])?["eta"] as? Double ?? 0 let maneuver = (call.arguments as? [String: Any])?["maneuver"] as? Int ?? 0 let isNavigating = (call.arguments as? [String: Any])?["isNavigating"] as? Bool ?? false DispatchQueue.main.async { guard let delegate = CarPlayState.shared.sceneDelegate else { return } if isNavigating { if delegate.navigationSession == nil { delegate.startNavigation( instruction: instruction, distance: distanceToStep, eta: eta, maneuverType: maneuver ) } else { delegate.updateManeuver( instruction: instruction, distance: distanceToStep, maneuverType: maneuver ) delegate.updateArrivalEstimates(eta: eta) } delegate.updateLocation(lat: lat, lng: lng, bearing: bearing) } else { delegate.stopNavigation() } } result(true) case "updateLocation": let lat = (call.arguments as? [String: Any])?["lat"] as? Double ?? 0 let lng = (call.arguments as? [String: Any])?["lng"] as? Double ?? 0 let bearing = (call.arguments as? [String: Any])?["bearing"] as? Double ?? 0 DispatchQueue.main.async { CarPlayState.shared.sceneDelegate?.updateLocation( lat: lat, lng: lng, bearing: bearing ) } result(true) case "updateInstruction": let instruction = (call.arguments as? [String: Any])?["instruction"] as? String ?? "" let maneuver = (call.arguments as? [String: Any])?["maneuver"] as? Int ?? 0 let distanceToStep = (call.arguments as? [String: Any])?["distanceToStep"] as? Double ?? 0 DispatchQueue.main.async { CarPlayState.shared.sceneDelegate?.updateManeuver( instruction: instruction, distance: distanceToStep, maneuverType: maneuver ) } result(true) case "stopNavigation": DispatchQueue.main.async { CarPlayState.shared.sceneDelegate?.stopNavigation() } result(true) default: result(FlutterMethodNotImplemented) } } } // MARK: - عرض تنبيه عند اكتشاف جهاز مخترق func showSecurityAlert() { guard let rootVC = UIApplication.shared.keyWindow?.rootViewController else { exit(0) } let alert = UIAlertController( title: "Security Warning".localized, message: "Compromised device detected. Exiting.".localized, preferredStyle: .alert ) alert.addAction(UIAlertAction(title: "OK".localized, style: .destructive) { _ in self.obfuscatedExit() }) if #available(iOS 15.0, *) { alert.popoverPresentationController?.sourceView = rootVC.view alert.popoverPresentationController?.sourceRect = CGRect(x: rootVC.view.bounds.midX, y: rootVC.view.bounds.midY, width: 0, height: 0) alert.popoverPresentationController?.permittedArrowDirections = [] alert.presentationController?.delegate = self if let presentationController = alert.presentationController as? UISheetPresentationController { presentationController.detents = [.medium()] presentationController.preferredCornerRadius = 20 presentationController.prefersEdgeAttachedInCompactHeight = true presentationController.prefersGrabberVisible = false } } rootVC.present(alert, animated: true, completion: nil) } // MARK: - إخفاء عملية الخروج بطريقة مشفرة func obfuscatedExit() { let selector = NSSelectorFromString(String(format: "%@%@", "ex", "it:")) if responds(to: selector) { perform(selector, with: 0) } } } // MARK: - التعامل مع أذونات الموقع بطريقة آمنة extension AppDelegate: CLLocationManagerDelegate { func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { if #available(iOS 14.0, *) { let status = manager.authorizationStatus switch status { case .authorizedWhenInUse, .authorizedAlways: print("Authorization granted") case .denied, .restricted: print("Authorization denied") case .notDetermined: manager.requestWhenInUseAuthorization() @unknown default: break } } else { // لنظام iOS 13 وما قبله، نستخدم الطريقة القديمة let status = CLLocationManager.authorizationStatus() switch status { case .authorizedWhenInUse, .authorizedAlways: print("Authorization granted") case .denied, .restricted: print("Authorization denied") case .notDetermined: manager.requestWhenInUseAuthorization() @unknown default: break } } } } // MARK: - منع إغلاق التنبيهات الأمنية extension AppDelegate: UIAdaptivePresentationControllerDelegate { func presentationControllerShouldDismiss(_ presentationController: UIPresentationController) -> Bool { return false } } // MARK: - دعم الترجمة للنصوص extension String { var localized: String { return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "") } }