DebugSwift

A toolkit to make debugging iOS applications easier πŸš€

748
76
Swift

DebugSwift

DebugSwift is a comprehensive toolkit designed to simplify and enhance the debugging process for Swift-based applications. Whether you’re troubleshooting network issues, monitoring WebSocket connections, optimizing performance, or testing push notifications, DebugSwift provides a powerful set of features to make your debugging experience more efficient.

✨ New: Unified Network Inspector with WebSocket support
πŸš€ Swift 6 ready with strict concurrency checking<!/div>

image1
image2
image3
image4
image5
image6
image11

πŸ“‹ Table of Contents

πŸ“š Documentation

Requirements

  • iOS 14.0+
  • Swift 6.0+
  • Xcode 16.0+

πŸ†• What’s New

Version 2.0+ - Major Updates

  • 🌐 Unified Network Inspector: Combined HTTP and WebSocket monitoring in a single, powerful interface
  • ⚑ WebSocket Inspector: Automatic WebSocket monitoring with pure Swift method swizzling - zero configuration required
  • πŸ“Š Enhanced Floating Button: Now tracks both HTTP requests and WebSocket connections with custom animations
  • πŸš€ Swift 6 Compatibility: Full support for Swift 6 with strict concurrency checking
  • πŸ“± iOS 14+ Optimization: Removed legacy iOS 13.0 availability checks for cleaner, modern codebase
  • πŸ”§ Improved API: More intuitive configuration with .shared pattern across all singletons
  • πŸ“± Better UI/UX: Refined interface with better visual indicators and smoother animations
  • ⚠️ Memory Leak Detection: Enhanced leak detection with better reporting and analytics
  • 🎯 Smart Content Detection: Automatic JSON formatting and syntax highlighting in network inspector

Features

App Settings

  • Crash Reports: Access detailed crash reports for analysis and debugging.
  • Change Location: Simulate different locations for testing location-based features.
  • Console: Monitor and interact with the application’s console logs.
  • Custom Info: Add custom information for quick access during debugging.
  • Version: View the current application version.
  • Build: Identify the application’s build number.
  • Bundle Name: Retrieve the application’s bundle name.
  • Bundle ID: Display the unique bundle identifier for the application.
  • Device Infos: Access information about the device running the application.
  • APNS Device Token: View and copy the Apple Push Notification Service device token for debugging push notifications:
    • Real-time registration status tracking (not requested, pending, registered, failed, denied)
    • One-tap token copying to clipboard for manual testing
    • APNS environment detection (development/production)
    • Error details for failed registrations
    • Refresh mechanism to update token status
    • Direct integration with notification settings
  • Loaded Libraries: Explore all loaded libraries (frameworks, dylibs) with detailed information:
    • View public and private libraries with their file paths and memory addresses
    • Filter libraries by type (Public/Private) or search by name
    • Expand libraries to see all their Objective-C classes
    • Explore class details including properties, methods, and protocols
    • Create class instances to inspect their default state
    • Export comprehensive reports of all loaded libraries
Libraries List Class Explorer Class Details
Simulator Screenshot - iPhone 16 Pro - 2025-06-03 at 14 44 29 Simulator Screenshot - iPhone 16 Pro - 2025-06-03 at 14 44 37 Simulator Screenshot - iPhone 16 Pro - 2025-06-03 at 14 44 42

Interface

  • Grid: Overlay a grid on the interface to assist with layout alignment.
  • Slow Animations: Slow down animations for better visualization and debugging.
  • Showing Touches: Highlight touch events for easier interaction tracking.
  • Colorized View with Borders: Apply colorization and borders to views for improved visibility.

Network Inspector

Comprehensive network traffic monitoring with unified HTTP and WebSocket inspection:

HTTP Monitoring

  • All Response/Request Logs: Capture and review detailed logs of all network requests and responses
  • Request/Response Details: Full headers, body content, timing information, and status codes
  • Search & Filter: Find specific requests with powerful search and filtering capabilities
  • Copy & Share: Copy URLs, export request data, and share network logs
  • Threshold Request Limiter: Monitor and control network request rates with customizable thresholds:
    • Set global or endpoint-specific request limits
    • Configure time windows for rate limiting
    • Receive alerts when thresholds are exceeded
    • Optional request blocking when limits are reached
    • Detailed breach history and analytics

WebSocket Inspector (Enhanced!)

  • πŸ€– Automatic Detection: Zero-configuration WebSocket monitoring with method swizzling
  • Real-time Connection Monitoring: Track WebSocket connections with live status updates
  • Frame Inspection: Monitor sent and received frames with timestamp precision
  • Smart Content Detection: Automatic JSON formatting with syntax highlighting
  • Message Types: Support for text, binary, ping/pong, and control frames
  • Connection Management: Close connections, clear frame history, and connection info
  • Search & Resend: Search through frames and resend messages for testing
  • Channel Organization: Group connections by custom channel names
  • Pure Swift Implementation: Advanced method swizzling without Objective-C dependencies
HTTP Requests WebSocket Connections Frame Timeline
HTTP Inspector WebSocket Connections Frame Timeline

Performance

  • CPU, Memory, FPS, Memory Leak Detector: Monitor and analyze CPU usage, memory consumption, and frames per second in real-time.

Push Notifications

  • Push Notification Simulation: Test push notifications using local notifications without requiring a server setup. Features include:
    • Template System: Pre-built notification templates for common scenarios (messages, news, marketing, system alerts)
    • Custom Notifications: Create detailed notifications with title, body, subtitle, badge, sound, and custom user info
    • Scheduled Delivery: Support for immediate, delayed, and date-based notification triggers
    • Interaction Simulation: Simulate user taps, dismissals, and custom notification actions
    • Foreground/Background Testing: Test notification behavior in different app states
    • History Tracking: Complete history of sent notifications with status tracking
    • Test Scenarios: Pre-configured test flows for comprehensive notification testing
    • Configuration Options: Customize notification presentation, sounds, badges, and interaction behavior

Resources

  • Keychain: Inspect and manage data stored in the keychain.
  • User Defaults: View and modify user defaults for testing different application states.
  • Files: Access and analyze files stored by the application and app group containers:
    • Browse app sandbox directories with full navigation
    • Access shared app group containers with automatic detection
    • Switch between app sandbox and app groups with segmented control
    • View, delete, and export files from any accessible location
    • Smart detection of app group identifiers from entitlements
    • Professional UI with visual indicators for container types

Getting Started

Installation

Swift Package Manager (SPM)

Add the following dependency to your Package.swift file:

dependencies: [
    .package(url: "https://github.com/DebugSwift/DebugSwift.git", from: "1.0.0")
]

Then, add "DebugSwift" to your target’s dependencies.

Usage

import DebugSwift

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    
    let debugSwift = DebugSwift()
    
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        
        #if DEBUG
        debugSwift.setup()
        debugSwift.show()
        #endif
        
        return true
    }
}

Usage to show or hide with shake.

extension UIWindow {
    open override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
        super.motionEnded(motion, with: event)
        
        #if DEBUG
        if motion == .motionShake {
            // Assuming you have a reference to your DebugSwift instance
            if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
                appDelegate.debugSwift.toggle()
            }
        }
        #endif
    }
}

Quick Start with App Groups (Optional)

If your app uses shared app group containers (for extensions, widgets, etc.), you can configure them for debugging:

#if DEBUG
// Configure app groups for file browser access
DebugSwift.Resources.shared.configureAppGroups([
    "group.com.yourcompany.yourapp",
    "group.com.yourcompany.widgets"
])

debugSwift.setup()
debugSwift.show()
#endif

Note: App groups are automatically detected from your app’s entitlements if not manually configured.

Quick Examples

Complete WebSocket Chat Integration (Zero-Config!)

import DebugSwift

class ChatManager {
    private var webSocketTask: URLSessionWebSocketTask?
    
    func connect() {
        let url = URL(string: "wss://chat.example.com/websocket")!
        webSocketTask = URLSession.shared.webSocketTask(with: url)
        
        // Optional: Register with custom channel name for better organization
        DebugSwift.WebSocket.register(task: webSocketTask!, channelName: "Chat")
        
        webSocketTask?.resume()
        // βœ… Connection automatically monitored in DebugSwift!
        
        startListening()
    }
    
    func sendMessage(_ text: String) {
        let message = URLSessionWebSocketTask.Message.string(text)
        webSocketTask?.send(message) { error in
            if let error = error {
                print("Send failed: \(error)")
            }
        }
        // βœ… Sent message automatically captured with method swizzling!
        // No manual logging needed
    }
    
    private func startListening() {
        webSocketTask?.receive { result in
            switch result {
            case .success(let message):
                // Handle received message
                // βœ… Received message automatically captured!
                self.handleMessage(message)
                self.startListening() // Continue listening
            case .failure(let error):
                print("Receive failed: \(error)")
            }
        }
    }
    
    private func handleMessage(_ message: URLSessionWebSocketTask.Message) {
        switch message {
        case .string(let text):
            print("Received text: \(text)")
        case .data(let data):
            print("Received data: \(data.count) bytes")
        @unknown default:
            print("Unknown message type")
        }
    }
}

// ✨ That's it! Full WebSocket monitoring with zero configuration
// All frames, connections, and status changes are automatically tracked

Network + Performance Monitoring Setup

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    let debugSwift = DebugSwift()
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
        #if DEBUG
        // Configure network monitoring
        DebugSwift.Network.shared.ignoredURLs = [
            "https://analytics.example.com"  // Ignore analytics endpoints
        ]
        
        // Set request threshold monitoring
        DebugSwift.Network.shared.setThreshold(100, timeWindow: 60.0)
        DebugSwift.Network.shared.setRequestBlocking(true)
        
        // Setup memory leak detection
        DebugSwift.Performance.shared.onLeakDetected { leakData in
            print("πŸ”΄ Memory leak detected: \(leakData.message)")
            // Send to analytics or logging service
        }
        
        // Enable push notification testing
        DebugSwift.PushNotification.enableSimulation()
        
        // Setup and show DebugSwift
        debugSwift.setup()
        debugSwift.show()
        #endif
        
        return true
    }
}

Custom Actions & Info Integration

// Add custom debugging actions
DebugSwift.App.shared.customAction = {
    [
        .init(title: "Development Tools", actions: [
            .init(title: "Clear User Data") {
                UserDefaults.standard.removeObject(forKey: "userData")
                print("βœ… User data cleared")
            },
            .init(title: "Simulate Network Error") {
                // Trigger a test network error
                self.simulateNetworkError()
            },
            .init(title: "Test WebSocket Reconnection") {
                self.chatManager.reconnect()
            }
        ]),
        .init(title: "Feature Flags", actions: [
            .init(title: "Enable Beta Features") {
                FeatureFlags.shared.enableBetaFeatures()
            }
        ])
    ]
}

// Add custom development information
DebugSwift.App.shared.customInfo = {
    [
        .init(title: "Environment Info", infos: [
            .init(title: "API Environment", subtitle: Configuration.apiEnvironment),
            .init(title: "Feature Flags", subtitle: FeatureFlags.shared.enabledFlags.joined(separator: ", ")),
            .init(title: "Database", subtitle: CoreDataManager.shared.storeURL.lastPathComponent)
        ]),
        .init(title: "User Session", infos: [
            .init(title: "User ID", subtitle: UserSession.shared.userId ?? "Not logged in"),
            .init(title: "Session Token", subtitle: UserSession.shared.hasValidToken ? "Valid" : "Invalid")
        ])
    ]
}

APNS Device Token Integration

To enable APNS device token tracking in DebugSwift, integrate the following code into your AppDelegate:

import DebugSwift
import UserNotifications

class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Your existing DebugSwift setup
        #if DEBUG
        debugSwift.setup().show()
        #endif
        
        // Request push notification permissions
        requestPushNotificationPermissions()
        
        return true
    }
    
    private func requestPushNotificationPermissions() {
        Task { @MainActor in
            let center = UNUserNotificationCenter.current()
            
            // Inform DebugSwift that we're about to request permissions
            DebugSwift.APNSToken.willRequestPermissions()
            
            do {
                let granted = try await center.requestAuthorization(options: [.alert, .badge, .sound])
                if granted {
                    UIApplication.shared.registerForRemoteNotifications()
                } else {
                    DebugSwift.APNSToken.didDenyPermissions()
                }
            } catch {
                DebugSwift.APNSToken.didFailToRegister(error: error)
            }
        }
    }
    
    // MARK: - Push Notification Delegate Methods
    
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        // Register with DebugSwift for debugging
        DebugSwift.APNSToken.didRegister(deviceToken: deviceToken)
        
        // Your existing token handling code here
        let tokenString = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
        print("πŸ“± Device token: \(tokenString)")
    }
    
    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        // Register failure with DebugSwift
        DebugSwift.APNSToken.didFailToRegister(error: error)
        
        // Your existing error handling code here
        print("❌ Failed to register: \(error.localizedDescription)")
    }
}

APNS Token Features:

  • Status Tracking: View current registration state in Device Info section
  • Copy to Clipboard: Tap the Push Token row to copy the token for manual testing
  • Environment Detection: Automatically detects development vs production APNS environment
  • Error Details: Tap on failed registrations to see detailed error information
  • Refresh Button: Use the refresh button in the navigation bar to update token status
  • Settings Integration: Direct links to notification settings when permissions are denied

Programmatic Access:

// Get current device token
let token = DebugSwift.APNSToken.deviceToken

// Check registration state
let state = DebugSwift.APNSToken.registrationState

// Get APNS environment
let environment = DebugSwift.APNSToken.environment

// Copy token to clipboard programmatically
let copied = DebugSwift.APNSToken.copyToClipboard()

// Refresh registration status
await DebugSwift.APNSToken.refreshStatus()

Why This Matters:

When debugging push notification flows, developers often need the exact device token to:

  • Send test pushes from their server or testing tools
  • Verify token registration with their backend
  • Debug notification delivery issues
  • Test different APNS environments

DebugSwift eliminates the need for manual token logging and provides a convenient interface for accessing and copying tokens during development.

Customization

Network Configuration

If you want to ignore specific URLs, use the following code:

DebugSwift.Network.shared.ignoredURLs = ["https://reqres.in/api/users/23"]

If you want to capture only a specific URL, use the following code:

DebugSwift.Network.shared.onlyURLs = ["https://reqres.in/api/users/23"]

Adjust the URLs in the arrays according to your needs.

Network Threshold Configuration

Configure request rate limiting to prevent API abuse and monitor network usage:

// Basic threshold configuration
DebugSwift.Network.shared.threshold = 100  // 100 requests per minute
DebugSwift.Network.shared.enableRequestTracking()

// Advanced configuration with custom time window
DebugSwift.Network.shared.setThreshold(50, timeWindow: 30.0)  // 50 requests per 30 seconds

// Configure alert settings
DebugSwift.Network.shared.setThresholdAlert(
    emoji: "🚨", 
    message: "Too many requests!"
)

// Enable request blocking when threshold is exceeded
DebugSwift.Network.shared.setRequestBlocking(true)

// Set endpoint-specific limits
DebugSwift.Network.shared.setEndpointThreshold(
    "api/users", 
    limit: 50, 
    timeWindow: 60.0
)

// Monitor current request count
let currentCount = DebugSwift.Network.shared.getCurrentRequestCount()
print("Current requests: \(currentCount)")

// View breach history
let breaches = DebugSwift.Network.shared.getBreachHistory()
for breach in breaches {
    print("Breach at \(breach.timestamp): \(breach.message)")
}

All threshold configurations are automatically persisted using UserDefaults.

Results:

When the threshold is exceeded, you’ll see:

  • Visual alerts in the app with your configured emoji and message
  • Color-coded status in the Network tab header (green β†’ orange β†’ red)
  • Detailed breach history in the threshold configuration screen
  • Optional blocking of requests returning 429 errors

WebSocket Configuration

Monitor WebSocket connections in real-time with comprehensive frame inspection:

πŸ€– Automatic Setup (Recommended)

// WebSocket monitoring is AUTOMATIC with method swizzling
// No manual registration required - just create and use WebSocket as normal
let task = URLSession.shared.webSocketTask(with: url)
task.resume()
// βœ… Connection automatically detected and monitored in DebugSwift!

// Send messages - automatically logged
task.send(.string("Hello WebSocket!")) { error in
    if let error = error {
        print("Send failed: \(error)")
    }
}
// βœ… Sent frames automatically captured and displayed

Advanced Usage with Custom Channels

// Create WebSocket with custom channel name for organization
let webSocketURL = URL(string: "wss://api.example.com/websocket")!
let task = URLSession.shared.webSocketTask(with: webSocketURL)

// Optional: Register with custom channel name for better organization
DebugSwift.WebSocket.register(task: task, channelName: "Live Updates")

// Start the connection
task.resume()

// Send messages - automatically monitored with method swizzling
task.send(.string("Hello WebSocket!")) { error in
    if let error = error {
        print("Send failed: \(error)")
    }
}
// βœ… Sent frames automatically captured

// Receive messages - automatically monitored
task.receive { result in
    switch result {
    case .success(let message):
        // Handle message - automatically logged in DebugSwift
        self.handleMessage(message)
    case .failure(let error):
        print("Receive error: \(error)")
    }
}
// βœ… Received frames automatically captured

Configuration Options

// Enable/disable WebSocket monitoring
DebugSwift.WebSocket.enableMonitoring()
DebugSwift.WebSocket.disableMonitoring()

// Check monitoring status
let isEnabled = DebugSwift.WebSocket.isMonitoringEnabled

// Get connection statistics
let activeConnections = DebugSwift.WebSocket.activeConnectionCount
let totalUnreadFrames = DebugSwift.WebSocket.totalUnreadFrames

// Data management
DebugSwift.WebSocket.clearAllData()
DebugSwift.WebSocket.clearFrames(for: webSocketURL)

Results:

The WebSocket Inspector provides:

  • πŸ€– Zero Configuration: Automatic detection via pure Swift method swizzling
  • 🟒 Connected/🟠 Connecting/πŸ”΄ Error Status: Visual connection state indicators
  • πŸ“€πŸ“₯ Frame Direction: Clear sent/received frame identification with timestamps
  • 🟒 JSON/πŸ”΅ TEXT/🟑 BIN Labels: Smart content type detection and formatting
  • ⚑ Real-time Updates: Live frame monitoring as they’re sent/received
  • πŸ” Search & Filter: Find specific frames by content, type, or direction
  • πŸ”„ Resend Capability: Replay frames for testing and debugging
  • πŸ“Š Connection Info: Detailed connection metadata and statistics
  • πŸ›‘οΈ Non-Intrusive Monitoring: No interference with WebSocket handshake or performance

Perfect for debugging:

  • WebSocket connection lifecycle (automatic detection)
  • Message formatting and content (zero setup required)
  • Real-time data synchronization (comprehensive frame capture)
  • Chat and live update features (automatic frame logging)
  • API communication protocols (method swizzling captures everything)

Push Notification Simulation

Test push notifications without setting up a push notification service or server. Perfect for development and testing scenarios.

Basic Usage

// Enable push notification simulation
DebugSwift.PushNotification.enableSimulation()

// Simple notification
DebugSwift.PushNotification.simulate(
    title: "New Message",
    body: "You have a new message"
)

// Detailed notification with all options
DebugSwift.PushNotification.simulate(
    title: "Special Offer! πŸŽ‰",
    body: "Get 50% off your next purchase",
    subtitle: "Limited time offer",
    badge: 1,
    sound: "default",
    userInfo: ["type": "marketing", "discount": "50"],
    delay: 5.0  // Show after 5 seconds
)

Using Templates

// Use predefined templates
DebugSwift.PushNotification.simulateFromTemplate("Message")
DebugSwift.PushNotification.simulateFromTemplate("News Update", delay: 3.0)

// Quick convenience methods
DebugSwift.PushNotification.simulateMessage(from: "John", message: "Hey, how are you?")
DebugSwift.PushNotification.simulateReminder("Meeting at 3 PM", in: 60.0)
DebugSwift.PushNotification.simulateNews(headline: "Breaking: New iOS version released", category: "Technology")
DebugSwift.PushNotification.simulateMarketing(title: "Flash Sale!", offer: "50% off everything", discount: "50")

Test Scenarios

// Run comprehensive test scenarios
DebugSwift.PushNotification.runTestScenario(.messageFlow)      // 3 message-related notifications
DebugSwift.PushNotification.runTestScenario(.newsUpdates)     // News, sports, weather updates
DebugSwift.PushNotification.runTestScenario(.marketingCampaign) // Welcome, cart reminder, flash sale
DebugSwift.PushNotification.runTestScenario(.systemAlerts)    // Security, backup, update notifications

// Create custom scenarios
let customNotifications = [
    SimulatedNotification(title: "Step 1", body: "First notification"),
    SimulatedNotification(title: "Step 2", body: "Second notification"),
    SimulatedNotification(title: "Step 3", body: "Final notification")
]
DebugSwift.PushNotification.runTestScenario(.customFlow(customNotifications))

Interaction Simulation

// Simulate user interactions
DebugSwift.PushNotification.simulateInteraction(identifier: "notification-id")
DebugSwift.PushNotification.simulateForegroundNotification(identifier: "notification-id")
DebugSwift.PushNotification.simulateBackgroundNotification(identifier: "notification-id")

Template Management

// Add custom templates
let customTemplate = NotificationTemplate(
    name: "Custom Alert",
    title: "System Alert",
    body: "{{message}}",
    sound: "alarm",
    userInfo: ["type": "system"]
)
DebugSwift.PushNotification.addTemplate(customTemplate)

// Get all templates
let templates = DebugSwift.PushNotification.templates

// Remove template
DebugSwift.PushNotification.removeTemplate(id: "template-id")

Configuration

// Configure notification behavior
var config = DebugSwift.PushNotification.configuration
config.showInForeground = true      // Show notifications while app is active
config.playSound = true             // Enable notification sounds
config.showBadge = true             // Show badge numbers
config.autoInteraction = false      // Automatically interact with notifications
config.interactionDelay = 3.0       // Delay before auto-interaction
config.maxHistoryCount = 100        // Maximum notifications to keep in history

DebugSwift.PushNotification.updateConfiguration(config)

History Management

// Get notification history
let history = DebugSwift.PushNotification.history

// Clear all history
DebugSwift.PushNotification.clearHistory()

// Remove specific notification
DebugSwift.PushNotification.removeNotification(id: "notification-id")

Results:

The push notification simulator provides:

  • Real Notifications: Actual system notifications that appear like real push notifications
  • Status Tracking: Monitor delivery, interaction, and dismissal status
  • Template Library: Pre-built templates for common notification types
  • Test Scenarios: Comprehensive flows for thorough testing
  • History Management: Complete tracking of all simulated notifications
  • Configuration Options: Fine-tune notification behavior and presentation

Perfect for testing:

  • Notification handling logic
  • UI responses to notifications
  • Different notification content types
  • User interaction patterns
  • Foreground vs background behavior

Floating Button Indicators

The DebugSwift floating button provides real-time feedback about your app’s network activity:

  • πŸ“Š Count Display: Shows total count of HTTP requests + WebSocket connections
  • πŸš€ HTTP Success: Green rocket animation for successful HTTP requests
  • ❌ HTTP Error: Red X animation for failed HTTP requests
  • ⚑ WebSocket Activity: Lightning bolt animation for WebSocket connections
  • ⚠️ Memory Leaks: Warning animations for detected memory leaks

The floating button count combines both HTTP requests and active WebSocket connections, giving you a comprehensive view of your app’s network activity at a glance.

App Group Container Configuration

Configure shared app group containers for file system debugging across app extensions and related apps:

// Configure app group identifiers for file browser access
DebugSwift.Resources.shared.configureAppGroups([
    "group.com.yourcompany.yourapp",
    "group.com.yourcompany.shared"
])

// Add individual app groups
DebugSwift.Resources.shared.addAppGroup("group.com.yourcompany.widgets")

// Remove specific app groups
DebugSwift.Resources.shared.removeAppGroup("group.com.yourcompany.old")

// Get accessible app group containers
let accessibleGroups = DebugSwift.Resources.shared.getAccessibleAppGroups()
for (identifier, url) in accessibleGroups {
    print("App Group: \(identifier) at \(url.path)")
}

Automatic Detection:

If no app groups are configured, DebugSwift will automatically:

  1. Try to read your app’s entitlements plist
  2. Extract app group identifiers from com.apple.security.application-groups
  3. Auto-configure detected app groups for immediate use

File Browser Features:

  • Segmented Control: Switch between β€œApp Sandbox” and β€œApp Groups”
  • Visual Indicators: App group containers show clear labels
  • Full Navigation: Browse deep into app group directory structures
  • File Operations: View, delete, and export files from shared containers
  • Error Handling: Clear messages when app groups are inaccessible

Results:

The Files browser will show a segmented control allowing you to switch between:

  • App Sandbox: Traditional app documents, library, and tmp directories
  • App Groups: Shared containers accessible by your app and extensions

App Custom Data

DebugSwift.App.shared.customInfo = {
    [
        .init(
            title: "Info 1",
            infos: [
                .init(title: "title 1", subtitle: "title 2")
            ]
        )
    ]
}

Results:

image5


App Custom Action

DebugSwift.App.shared.customAction = {
    [
        .init(
            title: "Action 1",
            actions: [
                .init(title: "action 1") { [weak self] in // Important if use self
                    print("Action 1")
                }
            ]
        )
    ]
}

Results:

image6


App Custom ViewControllers in Tab Bar

DebugSwift.App.shared.customControllers = {
    let controller1 = UITableViewController()
    controller1.title = "Custom TableVC 1"

    let controller2 = UITableViewController()
    controller2.title = "Custom TableVC 2"
    return [controller1, controller2]
}

Hide or disable Some Features

If you prefer to selectively disable certain features, DebugSwift can now deactivate unnecessary functionalities. This can assist you in development across various environments.

Usage

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    
    let debugSwift = DebugSwift()
    
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        
        #if DEBUG
        debugSwift.setup(
            // Main features - WebSocket is now part of .network
            hideFeatures: [
                .network,      // Includes both HTTP and WebSocket inspectors
                .resources, 
                .performance, 
                .interface, 
                .app
            ],
            // Swizzle features - Fine-grained control over monitoring
            disable: [
                .network,           // HTTP request monitoring
                .webSocket,         // WebSocket connection monitoring  
                .location,          // Location simulation
                .views,             // UI view debugging
                .crashManager,      // Crash report collection
                .leaksDetector,     // Memory leak detection
                .console,           // Console log capture
                .pushNotifications  // Push notification simulation
            ]
        )
        debugSwift.show()
        #endif
        
        return true
    }
}

Results:

image9


Collect Memory Leaks

Get the data from memory leaks in the app.

Usage

DebugSwift.Performance.shared.onLeakDetected { data in
    // If you want to send data to some analytics

    print(data.message) // Returns the name of the class and the error
    print(data.controller) // If is a controller leak
    print(data.view) // If is a view leak
    print(data.isDeallocation) // If is a deallocation of leak (good for false/positive)
}

Results:

image12


Enhanced Hierarchy Tree for Deeper Application Insights (Beta)

Harness the Power of Visual Information within the iOS Hierarchy Tree to Uncover Intricate Layouts and Element Relationships in Your Application.

How to Use

Simply press and hold the circle button to reveal the Snapshot and Hierarchy for a comprehensive overview.

Results:

image8

Explore Additional Details

Enhance your understanding by pressing and holding on a specific view to reveal information such as:

  • Class
  • Subviews
  • Background Color
  • Specific attributes based on the type (e.g., UILabel: Text, Font, and TextColor).

Results:

image10


Migration from Previous Versions

Breaking Changes in Swift 6 Version

  1. Minimum iOS Version: Now requires iOS 14.0+ (previously iOS 12.0+)
  2. Swift Version: Requires Swift 6.0+ with strict concurrency checking
  3. API Changes:
    • DebugSwift is now a class, not an enum
    • All singletons now use .shared pattern
    • Methods that access UI must be called from MainActor

Migration Examples

// Before (old version)
DebugSwift.setup()
DebugSwift.show()
DebugSwift.App.customInfo = { ... }
DebugSwift.Network.ignoredURLs = [...]

// After (Swift 6 version)
let debugSwift = DebugSwift()
debugSwift.setup()
debugSwift.show()
DebugSwift.App.shared.customInfo = { ... }
DebugSwift.Network.shared.ignoredURLs = [...]

Fixing Errors

Alamofire

Not called uploadProgress

In the AppDelegate.

class AppDelegate {
    let debugSwift = DebugSwift()
    
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
    ) -> Bool {
        debugSwift.setup()
        debugSwift.show()

        // Call this method
        DebugSwift.Network.shared.delegate = self
        return true
    }
}

And conform with the protocol:

extension AppDelegate: CustomHTTPProtocolDelegate {
    func urlSession(
        _ protocol: URLProtocol,
        _ session: URLSession,
        task: URLSessionTask,
        didSendBodyData bytesSent: Int64,
        totalBytesSent: Int64,
        totalBytesExpectedToSend: Int64
    ) {

        Session.default.session.getAllTasks { tasks in
            let uploadTask = tasks.first(where: { $0.taskIdentifier == task.taskIdentifier }) ?? task
            Session.default.rootQueue.async {
                Session.default.delegate.urlSession(
                    session,
                    task: uploadTask,
                    didSendBodyData: bytesSent,
                    totalBytesSent: totalBytesSent,
                    totalBytesExpectedToSend: totalBytesExpectedToSend
                )
            }
        }
    }
}

⭐ Support the Project by Leaving a Star!

Thank you for visiting our project! If you find our work helpful and would like to support us, please consider giving us a ⭐ star on GitHub. Your support is crucial for us to continue improving and adding new features.

Why Should You Star the Project?

  • Show Your Support: Let us know that you appreciate our efforts.
  • Increase Visibility: Help others discover this project.
  • Stay Updated: Get notifications on updates and new releases.
  • Motivate Us: Encouragement from the community keeps us going!

How to Leave a Star

  1. Log in to your GitHub account.
  2. Navigate to the top of this repository page.
  3. Click on the β€œStar” button located at the top-right corner.

Every star counts and makes a difference. Thank you for your support! 😊

GitHub stars


Contributors

Our contributors have made this project possible. Thank you!

Contributing

Contributions are welcome! If you have suggestions, improvements, or bug fixes, please submit a pull request. Let’s make DebugSwift even more powerful together!


Repo Activity

Alt

Star History

Star History Chart


License

DebugSwift is licensed under the MIT License - see the LICENSE file for details.

References