A comprehensive debugging and development toolkit for iOS applications, providing real-time insights into your app's behavior, network traffic, preferences, and performance metrics.
π― Perfect for development and debugging | π± Zero overhead in production builds
- Quick Start
- Features
- Installation
- Integration Guide
- Usage
- Advanced Configuration
- Demo Application
- Advanced Usage
- Architecture
- Troubleshooting
- Frequently Asked Questions
- License
- Changelog
Swift Package Manager (SPM):
// In Xcode: File > Add Package Dependencies
// URL: https://github.com/jdumasleon/jarvis-ios-sdkSwiftUI:
import SwiftUI
import Jarvis
@main
struct MyApp: App {
init() {
JarvisSDK.shared.initializeAsync()
}
var body: some Scene {
WindowGroup {
ContentView()
.jarvisSDK()
}
}
}UIKit:
import UIKit
import Jarvis
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
let window = UIWindow(windowScene: windowScene)
let viewController = ViewController()
window.rootViewController = viewController
self.window = window
window.makeKeyAndVisible()
// Initialize Jarvis SDK
JarvisSDK.shared.initialize(
config: JarvisConfig(enableShakeDetection: true),
window: window
)
}
}Configure your URLSession to enable network inspection:
import Jarvis
class HTTPClient {
private let session: URLSession
init() {
var config = URLSessionConfiguration.default
// Add Jarvis network interception
JarvisSDK.configureURLSession(&config)
self.session = URLSession(configuration: config)
}
func fetchData() async throws -> Data {
let url = URL(string: "https://api.example.com/data")!
let (data, _) = try await session.data(from: url)
// Request automatically captured by Jarvis β
return data
}
}- Shake your device (if enabled in config)
- Or call programmatically:
JarvisSDK.shared.activate()
That's it! π Jarvis will now provide debugging capabilities and network inspection.
- Real-time HTTP/HTTPS monitoring - Capture all network requests and responses
- Request/Response details - Headers, body, timing, and error information
- Automatic data redaction - Protects sensitive information (tokens, passwords)
- Search and filtering - Find specific requests quickly
- Duration tracking - Accurate millisecond timing for performance analysis
- Error tracking - Captures failed requests with detailed error information
- Multi-storage support - UserDefaults, Keychain, and Property Lists
- Real-time inspection - View all app preferences instantly
- Type-safe display - Proper formatting for all data types
- iOS Settings-style UI - Familiar interface for browsing preferences
- Search and filtering - Quickly find specific keys or values
- Secure data handling - Keychain items properly protected
- CPU Metrics - Real-time CPU usage monitoring with per-core breakdown
- Memory Tracking - Heap usage, footprint, and memory pressure detection
- FPS Monitoring - Frame rate tracking with jank detection
- Battery Monitoring - Battery level and thermal state tracking
- Performance Charts - Visual representation of system performance over time
- Historical Data - Track performance trends throughout your debugging session
- Dashboard - Comprehensive metrics dashboard with multiple views
- System Information - Device details, OS version, app version
- Health Scores - Overall app health metrics and indicators
- Network Activity Charts - Visual representation of network traffic
- Session Management - Track metrics across app sessions
- SwiftUI Native - Built entirely with SwiftUI for modern iOS
- Draggable FAB - Floating action button with smooth animations
- Expandable Mini-FABs - Quick access to all features
- Dark/Light Theme - Automatic theme switching based on system preferences
- Smooth Animations - Fluid transitions and micro-interactions
- Responsive Design - Optimized for all iOS device sizes
The Jarvis iOS SDK is available through multiple distribution channels:
- β Swift Package Manager (Recommended) - Native Xcode integration
- β Manual Integration - For advanced use cases
- Open your project in Xcode
- Go to File > Add Package Dependencies
- Enter the repository URL:
https://github.com/jdumasleon/jarvis-ios-sdk - Select version: 1.1.7 or "Up to Next Major Version"
- Click Add Package
- Select your target and click Add Package
Add to your Package.swift dependencies:
dependencies: [
.package(url: "https://github.com/jdumasleon/jarvis-ios-sdk", from: "1.0.0")
]Then add to your target:
.target(
name: "YourTarget",
dependencies: [
.product(name: "Jarvis", package: "jarvis-ios-sdk")
]
)The SDK provides a complete, all-in-one package:
// Complete SDK (recommended)
import Jarvis // All features includedFeatures included:
- β Network Inspection - URLSession interception and monitoring
- β Preferences Management - UserDefaults, Keychain, Property List support
- β Performance Monitoring - CPU, Memory, FPS tracking
- β Core Functionality - FAB, shake detection, configuration
- β Design System - Beautiful UI components and theme
- β Zero overhead in production - Automatically disabled in release builds
π§ Required:
- iOS 17.0+
- Xcode 15.0+
- Swift 5.9+
- SwiftUI or UIKit
π¦ Optional but Recommended:
- URLSession for network monitoring
- UserDefaults for preferences inspection
import SwiftUI
import Jarvis
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.jarvisSDK(config: createConfig())
}
}
private func createConfig() -> JarvisConfig {
return JarvisConfig(
preferences: PreferencesConfig(
configuration: PreferencesConfiguration(
autoDiscoverUserDefaults: true,
autoDiscoverKeychain: true
)
),
networkInspection: NetworkInspectionConfig(
enableNetworkLogging: true
),
enableDebugLogging: true,
enableShakeDetection: true
)
}
}import Jarvis
class NetworkManager {
static let shared = NetworkManager()
private let session: URLSession
init() {
var config = URLSessionConfiguration.default
config.timeoutIntervalForRequest = 30
// Add Jarvis network interception
JarvisSDK.configureURLSession(&config)
self.session = URLSession(configuration: config)
}
func request<T: Decodable>(_ endpoint: String) async throws -> T {
let url = URL(string: endpoint)!
let (data, _) = try await session.data(from: url)
return try JSONDecoder().decode(T.self, from: data)
}
}See UIKit Integration Guide for comprehensive UIKit setup instructions.
import UIKit
import Jarvis
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
let window = UIWindow(windowScene: windowScene)
let viewController = ViewController()
window.rootViewController = viewController
self.window = window
window.makeKeyAndVisible()
// Initialize Jarvis SDK
JarvisSDK.shared.initialize(
config: createConfig(),
window: window
)
}
private func createConfig() -> JarvisConfig {
return JarvisConfig(
preferences: PreferencesConfig(
configuration: PreferencesConfiguration(
autoDiscoverUserDefaults: true,
autoDiscoverKeychain: true
)
),
networkInspection: NetworkInspectionConfig(
enableNetworkLogging: true
),
enableDebugLogging: true,
enableShakeDetection: true
)
}
}import UIKit
import Jarvis
class ViewController: UIViewController {
override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
if motion == .motionShake {
JarvisSDK.shared.handleShake()
}
}
}Complete SwiftUI setup example:
import SwiftUI
import Jarvis
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.jarvisSDK(config: advancedConfig())
}
}
private func advancedConfig() -> JarvisConfig {
return JarvisConfig(
preferences: PreferencesConfig(
configuration: PreferencesConfiguration(
autoDiscoverUserDefaults: true,
autoDiscoverKeychain: true,
enablePreferenceEditing: false, // Read-only mode
showSystemPreferences: false // Hide system keys
)
),
networkInspection: NetworkInspectionConfig(
enableNetworkLogging: true,
useAggressiveInterception: true,
maxCachedRequests: 100
),
enableDebugLogging: true,
enableShakeDetection: true
)
}
}For UIKit apps, see the UIKit Integration Guide which covers:
- β Complete UIKit setup instructions
- β Window management and lifecycle
- β Navigation controller integration
- β Shake detection implementation
- β Working example code
- β Troubleshooting UIKit-specific issues
Full JarvisConfig Example:
import Jarvis
private func createAdvancedConfig() -> JarvisConfig {
return JarvisConfig(
// Preferences configuration
preferences: PreferencesConfig(
configuration: PreferencesConfiguration(
// Auto-discovery settings
autoDiscoverUserDefaults: true,
autoDiscoverKeychain: true,
// Security and behavior
enablePreferenceEditing: false, // Read-only mode for safety
showSystemPreferences: false, // Hide system keys
maxPreferencesCount: 1000 // Limit for performance
)
),
// Network inspection configuration
networkInspection: NetworkInspectionConfig(
enableNetworkLogging: true,
useAggressiveInterception: true, // Automatic URLSession interception
maxCachedRequests: 100, // Limit cached requests
enableBodyLogging: true, // Log request/response bodies
redactSensitiveData: true // Automatically redact passwords, tokens
),
// Performance monitoring
performanceMonitoring: PerformanceConfig(
enableCpuMonitoring: true,
enableMemoryMonitoring: true,
enableFpsMonitoring: true,
samplingIntervalMs: 1000, // Sample every 1 second
maxHistorySize: 300 // Keep 5 minutes of history
),
// Core features
enableDebugLogging: true,
enableShakeDetection: true
)
}Before deploying, verify:
For SwiftUI:
- β
.jarvisSDK()modifier added to root view - β Configuration created with desired features
- β URLSession configured for network monitoring
- β Shake detection tested on physical device
For UIKit:
- β
JarvisSDK.shared.initialize()called in SceneDelegate - β Window reference passed to SDK
- β Shake detection implemented in ViewController
- β URLSession configured for network monitoring
- β Lifecycle properly managed
Common Checklist:
- β SDK Initialization: Jarvis configured on app launch
- β
Network Configuration: URLSession configured with
JarvisSDK.configureURLSession() - β Build Variants: Debug-only integration confirmed
- β Physical Device Testing: Shake detection tested on real device
- β Performance: No noticeable impact on app performance
Simply shake your device to open Jarvis (if enabled in configuration).
Note: Shake detection only works on physical devices, not in the simulator.
import Jarvis
// In your ViewController or View
func openJarvis() {
// Activate Jarvis
JarvisSDK.shared.activate()
// Deactivate Jarvis
JarvisSDK.shared.deactivate()
// Toggle Jarvis state
let isActive = JarvisSDK.shared.toggle()
// Check if active
if JarvisSDK.shared.isActive {
print("Jarvis is currently active")
}
}When activated, the Jarvis FAB provides quick access to:
- Home - Main dashboard with metrics and overview
- Inspector - Network traffic analysis
- Preferences - App preferences management
The FAB can be dragged anywhere on the screen and remembers its position.
Jarvis automatically intercepts network traffic when your URLSession is configured:
import Jarvis
// Configure once in your networking layer
class APIClient {
private let session: URLSession
init() {
var config = URLSessionConfiguration.default
JarvisSDK.configureURLSession(&config)
self.session = URLSession(configuration: config)
}
// All requests through this session are automatically captured
func fetchUsers() async throws -> [User] {
let url = URL(string: "https://api.example.com/users")!
let (data, _) = try await session.data(from: url)
return try JSONDecoder().decode([User].self, from: data)
}
}Supported HTTP Clients:
- β URLSession - Full support (built-in)
- β Alamofire - Works automatically (uses URLSession)
- β Custom networking - Works if based on URLSession
- β Pure socket connections - Not supported
- Activate Jarvis - Shake device or call
JarvisSDK.shared.activate() - Tap Inspector FAB - Network icon in the FAB menu
- Browse Requests - See all captured requests in real-time
- View Details - Tap any request to see:
- Request: Method, URL, headers, body
- Response: Status code, headers, body
- Timing: Duration in milliseconds
- Errors: Detailed error information if failed
- Search by URL - Type in the search bar
- Filter by method - GET, POST, PUT, DELETE, etc.
- Filter by status - 2xx (success), 4xx (client error), 5xx (server error)
- Sort by time - Newest first or oldest first
- Sort by duration - Find slow requests
Jarvis automatically discovers and displays:
- UserDefaults - All standard and suite-based preferences
- Keychain - Securely stored credentials (with proper entitlements)
- Property Lists - App-specific .plist files
- Activate Jarvis
- Tap Preferences button in the FAB menu
- Browse by storage type - Filter by UserDefaults, Keychain, etc.
- Search for keys - Use search bar to find specific preferences
- View details - Tap any preference to see type, value, and metadata
Jarvis properly formats all data types:
- String - Plain text display
- Number - Integer, Float, Double formatting
- Boolean - True/False display
- Date - Formatted date and time
- Data - Hex dump or decoded string
- Array - List view with items
- Dictionary - Key-value pair display
Jarvis collects performance data automatically when enabled:
let config = JarvisConfig(
performanceMonitoring: PerformanceConfig(
enableCpuMonitoring: true,
enableMemoryMonitoring: true,
enableFpsMonitoring: true,
samplingIntervalMs: 1000
)
)- Activate Jarvis
- Open Dashboard - Tap Home in FAB menu
- View Performance Charts - See real-time metrics:
- CPU Usage - App and system CPU percentage
- Memory Usage - Heap, footprint, and total memory
- FPS Metrics - Frame rate and jank detection
- Battery Level - Current battery percentage
- Thermal State - Device temperature status
CPU Metrics:
- App CPU usage percentage
- System-wide CPU usage
- Number of cores
- Active thread count
Memory Metrics:
- Heap used/total/max (MB)
- Memory footprint (MB)
- Available memory
- Memory pressure state
FPS Metrics:
- Current frame rate
- Average FPS
- Frame drops count
- Jank frames detection
System Metrics:
- Battery level percentage
- Thermal state (normal, fair, serious, critical)
For advanced use cases, manually log network transactions:
import Jarvis
import JarvisInspectorDomain
// Custom network interceptor
class CustomNetworkLogger {
func logRequest(_ request: URLRequest, data: Data?) async {
let transaction = NetworkTransaction(
id: UUID().uuidString,
url: request.url?.absoluteString ?? "",
method: request.httpMethod ?? "GET",
requestHeaders: request.allHTTPHeaderFields,
requestBody: data,
startDate: Date()
)
// Log to Jarvis
JarvisSDK.shared.logNetworkTransaction(transaction)
}
func logResponse(_ response: URLResponse, data: Data?, error: Error?) {
// Create and log response
// See documentation for complete example
}
}Jarvis is designed for development only. In release builds, wrap initialization:
import SwiftUI
import Jarvis
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
#if DEBUG
.jarvisSDK(config: JarvisConfig(
enableShakeDetection: true,
enableDebugLogging: true
))
#endif
}
}
}This ensures zero overhead in production builds.
The SDK includes a comprehensive demo app showcasing all features:
# Clone the repository
git clone https://github.com/jdumasleon/jarvis-ios-sdk.git
cd jarvis-ios-sdk
# Open in Xcode
open JarvisDemo/JarvisDemo.xcodeproj
# Build and run on device or simulator
# (Shake detection requires physical device)The demo app demonstrates:
- β SwiftUI Integration - Complete setup example
- β Network Monitoring - Sample API calls with automatic capture
- β Preferences Management - Various UserDefaults examples
- β Performance Monitoring - Real-time metrics display
- β FAB Interactions - Draggable floating action button
- β Dashboard Views - Multiple chart and metric visualizations
- β Search and Filtering - Advanced request filtering
For non-URLSession networking or custom integrations:
import Jarvis
import JarvisInspectorDomain
// Create network transaction
let transaction = NetworkTransaction(
id: UUID().uuidString,
url: "https://api.example.com/data",
method: "POST",
requestHeaders: ["Content-Type": "application/json"],
requestBody: requestData,
startDate: Date()
)
// Log request
JarvisSDK.shared.logNetworkTransaction(transaction)
// Update with response
let updatedTransaction = transaction.withResponse(
statusCode: 200,
responseHeaders: responseHeaders,
responseBody: responseData,
endDate: Date()
)
JarvisSDK.shared.updateNetworkTransaction(updatedTransaction)Register custom preference storage:
import Jarvis
// Register custom preferences
JarvisSDK.shared.registerCustomPreferences(
storageName: "Custom Storage",
preferences: [
"api_key": "abc123...",
"user_id": "12345",
"is_premium": true,
"last_sync_date": Date()
]
)JarvisSDK/
βββ Sources/
β βββ Jarvis/ # Main SDK module
β β βββ Api/ # Public API interface
β β βββ Config/ # Configuration models
β β βββ Internal/ # Internal implementation
β β βββ Core/ # Common utilities
β β βββ Feature/ # Feature modules
β β β βββ Home/ # Dashboard & overview
β β β β βββ Data/ # Repositories
β β β β βββ Domain/ # Entities & use cases
β β β β βββ Presentation/ # ViewModels & Views
β β β βββ ...
β β βββ Presentation/ # Navigation & UI
β β
β βββ JarvisInspector/ # Network monitoring module
β β βββ Data/ # Network repositories
β β βββ Domain/ # Network entities
β β βββ Presentation/ # Inspector UI
β β
β βββ JarvisPreferences/ # Preferences module
β β βββ Data/ # Preferences repositories
β β βββ Domain/ # Preferences entities
β β βββ Presentation/ # Preferences UI
β β
β βββ JarvisDesignSystem/ # UI components
β βββ Components/ # Reusable components
β βββ Foundation/ # Colors, typography
β βββ Resources/ # Assets
β
βββ Tests/ # Unit tests
βββ Package.swift # SPM manifest
- JarvisSDK - Main SDK singleton and entry point
- JarvisSDKApplication - Core UI application with navigation
- PerformanceMonitorManager - Real-time performance tracking
- NetworkTransactionRepository - Network data persistence
- PreferenceRepository - Preferences data access
- DependencyContainer - Dependency injection system
Solutions:
- Check if
.jarvisSDK()modifier is applied to root view (SwiftUI) - Verify
JarvisSDK.shared.initialize()is called (UIKit) - Ensure shake detection is enabled:
enableShakeDetection: true - Try programmatic activation:
JarvisSDK.shared.activate() - Enable debug logging to see initialization logs
Reasons:
- Simulator doesn't support shake gestures
- Shake detection not enabled in config
- Physical device accelerometer issue
Solutions:
- Test on physical device (not simulator)
- Verify config:
JarvisConfig(enableShakeDetection: true) - Use programmatic activation as alternative
- Check device accelerometer in Settings > Privacy
Common Causes:
- URLSession not configured with Jarvis
- Using
URLSession.shared(cannot be configured) - Network logging disabled in config
- SDK not activated
Solutions:
// β Wrong - No configuration
let session = URLSession(configuration: .default)
// β Wrong - URLSession.shared cannot be configured
let (data, _) = try await URLSession.shared.data(from: url)
// β Correct - Configure custom URLSession
var config = URLSessionConfiguration.default
JarvisSDK.configureURLSession(&config)
let session = URLSession(configuration: config)
let (data, _) = try await session.data(from: url)Solutions:
- Enable auto-discovery:
autoDiscoverUserDefaults: true - Check UserDefaults access permissions
- Verify Keychain entitlements for Keychain items
- Try refreshing the preferences list
- Check debug logs for scanning errors
Impact:
- Network monitoring adds ~2-5ms per request
- Performance monitoring uses ~100KB memory
- Designed for development builds only
Best Practices:
// Wrap in DEBUG flag
#if DEBUG
.jarvisSDK(config: config)
#endif
// Reduce overhead
let config = JarvisConfig(
networkInspection: NetworkInspectionConfig(
maxCachedRequests: 50 // Lower cache limit
),
performanceMonitoring: PerformanceConfig(
samplingIntervalMs: 2000 // Sample less frequently
)
)
// Deactivate when not debugging
JarvisSDK.shared.deactivate()Enable verbose logging to diagnose issues:
let config = JarvisConfig(
enableDebugLogging: true // Enable detailed logs
)Check Xcode console for Jarvis log messages:
[Jarvis] SDK initialized successfully
[Jarvis] Network monitoring enabled
[Jarvis] Performance monitoring started
[Jarvis] Captured request: GET https://api.example.com/data
For issues and questions:
- GitHub Issues: Create an issue
- Email: jdumasleon@gmail.com
- Documentation: Check this README and code examples
- Demo App: Review the included demo application
Q: Does Jarvis work with Alamofire or other networking libraries?
A: Yes! Alamofire and most iOS networking libraries use URLSession internally. When you configure your URLSession with JarvisSDK.configureURLSession(), all requests are automatically captured. Any library built on URLSession will work seamlessly.
Q: Can I use Jarvis in production builds?
A: Jarvis is designed for development and debugging only. Always wrap initialization in #if DEBUG blocks:
#if DEBUG
.jarvisSDK(config: JarvisConfig(...))
#endifQ: Does Jarvis work on macOS, watchOS, or tvOS?
A: Currently iOS only (iOS 15.0+). Support for other Apple platforms is under consideration for future releases.
Q: Do I need to configure every URLSession instance?
A: Yes. Each URLSession you create needs to be configured with JarvisSDK.configureURLSession(). This is typically done once in your networking layer or HTTP client initialization.
Q: Why aren't my network requests appearing?
A: Most commonly:
- URLSession not configured with Jarvis interceptor
- Using
URLSession.shared(cannot be configured - create custom session) - SDK not activated (shake device or call
.activate()) - Network logging disabled in config
Q: Are my API keys and passwords safe?
A: Yes. Jarvis automatically redacts sensitive headers (Authorization, Cookie, API keys) and detects sensitive data in request/response bodies. All data stays on-device and is never transmitted externally.
Q: Can I export captured network logs?
A: Currently, Inspector provides in-app viewing only. Export functionality is planned for a future release. Network data is persisted locally using Core Data for the duration of your debug session.
Q: What is the performance impact of Jarvis?
A: Minimal in debug builds:
- Network monitoring: ~2-5ms overhead per request
- Performance monitoring: ~100KB memory + sampling overhead
- UI rendering: No noticeable impact when deactivated
In release builds with #if DEBUG wrapping: zero overhead.
Q: How do I reduce memory usage?
A: Configure lower limits:
let config = JarvisConfig(
networkInspection: NetworkInspectionConfig(
maxCachedRequests: 50 // Default: 100
),
performanceMonitoring: PerformanceConfig(
maxHistorySize: 150, // Default: 300
samplingIntervalMs: 2000 // Default: 1000
)
)Q: Does Jarvis support UIKit apps?
A: Yes! Jarvis supports both SwiftUI and UIKit. See the UIKit Integration Guide for detailed UIKit setup instructions.
Q: Can I disable specific features?
A: Yes, configure only the features you need:
let config = JarvisConfig(
preferences: nil, // Disable preferences
networkInspection: NetworkInspectionConfig(
enableNetworkLogging: true
),
performanceMonitoring: nil // Disable performance monitoring
)Copyright 2024 Jarvis SDK
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
- π Initial Release - Core SDK functionality
- π Network Monitoring - HTTP/HTTPS request interception via URLProtocol
- βοΈ Preferences Management - UserDefaults, Keychain, Property List support
- π¨ SwiftUI UI - Native SwiftUI interface with dark/light theme
- π± Shake Detection - Intuitive activation method
- π― Floating Action Button - Draggable FAB with expandable mini-FABs
- ποΈ Modular Architecture - Clean separation of concerns
- π Sensitive Data Protection - Automatic redaction of passwords and tokens
- π± iOS 15.0+ Support - Modern iOS compatibility
- π Network Activity Chart - Visual representation of network traffic over time
- π Dashboard Redesign - New card-based layout with multiple chart types
- π¨ Chart Animations - Smooth entry animations for all chart components
- π§ Enhanced Metrics - Expanded dashboard metrics with network and preferences analytics
- π± UIKit Support - Complete UIKit integration guide and documentation
- π Design System Updates - Improved components and visual consistency
- β‘ Performance Monitoring - Comprehensive system performance tracking (CPU, Memory, FPS)
- π Performance Charts - Visual performance metrics with PerformanceOverviewChart
- π Enhanced Dashboard - Integrated performance monitoring into main dashboard
- π§ Performance Manager - Real-time performance data collection and monitoring
- π Historical Metrics - Track performance trends over time with configurable sampling
- π― Battery & Thermal - Battery level and thermal state monitoring
- π Improved Documentation - Complete guides for all features and integrations
Built with β€οΈ for iOS developers