diff --git a/iOS/Delegates/AppDelegate+PhasedInitialization.swift b/iOS/Delegates/AppDelegate+PhasedInitialization.swift index a16acca..48843a2 100644 --- a/iOS/Delegates/AppDelegate+PhasedInitialization.swift +++ b/iOS/Delegates/AppDelegate+PhasedInitialization.swift @@ -87,23 +87,55 @@ extension AppDelegate { func initializeComponentsWithCrashProtection() { Debug.shared.log(message: "Initializing components with crash protection", type: .info) - // Phase 1 - safe to run immediately - setupPhaseOne() - - // Phase 2 - defer slightly - DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { [weak self] in - self?.setupPhaseTwo() - } - - // Phase 3 - defer significantly - DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) { [weak self] in - self?.setupPhaseThree() - } - - // Post initialization complete notification after all phases - DispatchQueue.main.asyncAfter(deadline: .now() + 4.0) { - NotificationCenter.default.post(name: .appInitializationCompleted, object: nil) - Debug.shared.log(message: "App initialization complete", type: .success) + // Use try-catch blocks to prevent crashes during initialization + do { + // Phase 1 - safe to run immediately + setupPhaseOne() + + // Phase 2 - defer slightly + DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { [weak self] in + guard let self = self else { return } + + // Use try-catch to prevent crashes in Phase 2 + do { + self.setupPhaseTwo() + } catch { + Debug.shared.log(message: "Error in Phase 2 initialization: \(error.localizedDescription)", type: .error) + } + } + + // Phase 3 - defer significantly and only if memory allows + DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) { [weak self] in + guard let self = self else { return } + + // Check memory before heavy operations + if self.shouldProceedWithMemoryCheck() { + // Use try-catch to prevent crashes in Phase 3 + do { + self.setupPhaseThree() + } catch { + Debug.shared.log(message: "Error in Phase 3 initialization: \(error.localizedDescription)", type: .error) + } + } else { + Debug.shared.log(message: "Skipping Phase 3 due to high memory usage", type: .warning) + } + } + + // Post initialization complete notification after all phases + DispatchQueue.main.asyncAfter(deadline: .now() + 4.0) { + NotificationCenter.default.post(name: .appInitializationCompleted, object: nil) + Debug.shared.log(message: "App initialization complete", type: .success) + } + } catch { + // Log error but continue app launch with minimal functionality + Debug.shared.log(message: "Critical error during initialization: \(error.localizedDescription)", type: .error) + + // Ensure UI is still responsive even if initialization fails + DispatchQueue.main.async { + if let rootVC = UIApplication.shared.windows.first?.rootViewController { + rootVC.view.isUserInteractionEnabled = true + } + } } } diff --git a/iOS/Delegates/AppDelegate.swift b/iOS/Delegates/AppDelegate.swift index bd60340..15afeca 100644 --- a/iOS/Delegates/AppDelegate.swift +++ b/iOS/Delegates/AppDelegate.swift @@ -762,8 +762,17 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UIOnboardingViewControlle } private func setupMainUI() { - let tabBarController = UIHostingController(rootView: TabbarView()) + // Create TabbarView with proper initialization + let tabBarView = TabbarView() + + // Create hosting controller with the view + let tabBarController = UIHostingController(rootView: tabBarView) + + // Set as root view controller window?.rootViewController = tabBarController + + // Log successful UI setup + Debug.shared.log(message: "Main UI setup completed successfully", type: .info) } private func logDeviceInfo() { diff --git a/iOS/Utilities/SafeModeLauncher.swift b/iOS/Utilities/SafeModeLauncher.swift index 80efad3..9fb5f0b 100644 --- a/iOS/Utilities/SafeModeLauncher.swift +++ b/iOS/Utilities/SafeModeLauncher.swift @@ -58,12 +58,33 @@ class SafeModeLauncher { /// Disable safe mode and reset launch attempts func disableSafeMode() { + // Reset all relevant UserDefaults to ensure a clean state UserDefaults.standard.set(false, forKey: safeModeFlagKey) UserDefaults.standard.set(0, forKey: launchAttemptsKey) + + // Reset the selected tab to home to avoid potential issues + UserDefaults.standard.set("home", forKey: "selectedTab") + + // Clear any cached data that might be causing issues + clearProblemCaches() + UserDefaults.standard.synchronize() print("🔄 Safe mode disabled, app will restart with full functionality") } + + /// Clear caches that might be causing crashes + private func clearProblemCaches() { + // Clear image cache + try? FileManager.default.removeItem(at: FileManager.default.temporaryDirectory.appendingPathComponent("com.backdoor.imagecache")) + + // Reset any problematic flags + UserDefaults.standard.set(false, forKey: "isShowingStartupPopup") + UserDefaults.standard.set(false, forKey: "HasShownStartupPopup") + + // Reset any animation flags + UserDefaults.standard.set(false, forKey: "animateIcon") + } /// Present a safe mode alert to inform the user func showSafeModeAlert(on viewController: UIViewController, completion: (() -> Void)? = nil) { diff --git a/iOS/Views/Home/Extensions/HomeViewExtras.swift b/iOS/Views/Home/Extensions/HomeViewExtras.swift index 619d492..b399ef6 100644 --- a/iOS/Views/Home/Extensions/HomeViewExtras.swift +++ b/iOS/Views/Home/Extensions/HomeViewExtras.swift @@ -89,12 +89,5 @@ extension HomeViewController { } // Extension to add layer effects -public extension CALayer { - @objc func applyFuturisticShadow() { - shadowColor = UIColor.black.cgColor - shadowOffset = CGSize(width: 0, height: 2) - shadowOpacity = 0.2 - shadowRadius = 5 - masksToBounds = false - } -} +// Removed duplicate implementation of applyFuturisticShadow to avoid conflicts +// The implementation in UIView+UIHelpers.swift will be used instead diff --git a/iOS/Views/TabbarView.swift b/iOS/Views/TabbarView.swift index 49182f6..c2fa30c 100644 --- a/iOS/Views/TabbarView.swift +++ b/iOS/Views/TabbarView.swift @@ -97,43 +97,6 @@ struct TabbarView: View { // Add subtle blur effect for a more modern look appearance.backgroundEffect = UIBlurEffect(style: .systemMaterial) - // Set up observer to add LED effects after tab bar is ready - NotificationCenter.default.addObserver( - forName: UIApplication.didBecomeActiveNotification, - object: nil, - queue: .main - ) { _ in - DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { - // Apply flowing LED effect to all tab bars - if #available(iOS 15.0, *) { - // Use UIWindowScene.windows on iOS 15+ - UIApplication.shared.connectedScenes - .compactMap { $0 as? UIWindowScene } - .flatMap { $0.windows } - .compactMap { $0.rootViewController as? UITabBarController } - .forEach { tabController in - tabController.tabBar.addFlowingLEDEffect( - color: UIColor(hex: "#FF6482"), - intensity: 0.5, - width: 2, - speed: 5.0 - ) - } - } else { - // Use deprecated windows property on older iOS versions - UIApplication.shared.windows.compactMap { $0.rootViewController as? UITabBarController } - .forEach { tabController in - tabController.tabBar.addFlowingLEDEffect( - color: UIColor(hex: "#FF6482"), - intensity: 0.5, - width: 2, - speed: 5.0 - ) - } - } - } - } - // Configure selected item appearance let itemAppearance = UITabBarItemAppearance() @@ -155,6 +118,9 @@ struct TabbarView: View { if #available(iOS 15.0, *) { UITabBar.appearance().scrollEdgeAppearance = appearance } + + // Set up observer to add LED effects after tab bar is ready - moved to onAppear for safety + // This prevents potential crashes during initialization } // Handle tab change notification from other parts of the app with enhanced animations @@ -279,6 +245,47 @@ struct TabbarView: View { type: .debug ) } + + // Set up LED effects after a delay to ensure tab bar is ready + DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { + // Apply flowing LED effect to all tab bars - safely + do { + if #available(iOS 15.0, *) { + // Use UIWindowScene.windows on iOS 15+ + UIApplication.shared.connectedScenes + .compactMap { $0 as? UIWindowScene } + .flatMap { $0.windows } + .compactMap { $0.rootViewController as? UITabBarController } + .forEach { tabController in + // Check if the method exists before calling it + if tabController.tabBar.responds(to: #selector(UITabBar.addFlowingLEDEffect)) { + tabController.tabBar.addFlowingLEDEffect( + color: UIColor(hex: "#FF6482"), + intensity: 0.3, // Reduced intensity + width: 2, + speed: 5.0 + ) + } + } + } else { + // Use deprecated windows property on older iOS versions + UIApplication.shared.windows.compactMap { $0.rootViewController as? UITabBarController } + .forEach { tabController in + // Check if the method exists before calling it + if tabController.tabBar.responds(to: #selector(UITabBar.addFlowingLEDEffect)) { + tabController.tabBar.addFlowingLEDEffect( + color: UIColor(hex: "#FF6482"), + intensity: 0.3, // Reduced intensity + width: 2, + speed: 5.0 + ) + } + } + } + } catch { + Debug.shared.log(message: "Error applying LED effect: \(error.localizedDescription)", type: .error) + } + } } }