Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 49 additions & 17 deletions iOS/Delegates/AppDelegate+PhasedInitialization.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
}
}

Expand Down
11 changes: 10 additions & 1 deletion iOS/Delegates/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
21 changes: 21 additions & 0 deletions iOS/Utilities/SafeModeLauncher.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
11 changes: 2 additions & 9 deletions iOS/Views/Home/Extensions/HomeViewExtras.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
81 changes: 44 additions & 37 deletions iOS/Views/TabbarView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand All @@ -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
Expand Down Expand Up @@ -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)
}
}
}
}

Expand Down
Loading