flutter_chuck_inspection 1.0.7 copy "flutter_chuck_inspection: ^1.0.7" to clipboard
flutter_chuck_inspection: ^1.0.7 copied to clipboard

A powerful HTTP inspector for Flutter — monitor, debug, and analyze requests in real-time with a sleek dark UI and persistent notifications.

Flutter Chuck Inspection #

A powerful HTTP inspector for Flutter — monitor, debug, and analyze all network requests and responses in real-time with a sleek dark UI and persistent notifications.

pub version Flutter Dart MIT License Platform: Android | iOS


Features #

  • Real-time HTTP Monitoring — Track every request and response as it happens
  • Export — Save logs as JSON or CSV for offline analysis
  • Persistent Notifications — Live request statistics in your notification tray
  • Beautiful Dark UI — Modern interface with smooth animations
  • Detailed Request Inspector — View headers, body, response, and error details
  • Multiple HTTP Clients:
    • http package via ChuckHttpClient
    • dio package via ChuckDioInterceptor
  • Smart Filtering — Filter by All, Success, or Error requests
  • Share Logs — Export and share HTTP call reports instantly
  • Zero Configuration — Simple setup, works out of the box
  • Notification Permission Handling — Automatic permission management on Android 13+ and iOS
  • Statistics Dashboard — Total, success, and error counts at a glance

Screenshots #

Notification
Notification
Inspector List
Inspector List
Success Filter
Success Filter
Overview Tab
Overview Tab
Request Tab
Request Tab
Response Tab
Response Tab
Error Tab
Error Tab

Installation #

Add to your pubspec.yaml:

dependencies:
  flutter_chuck_inspection: ^1.0.7

Then run:

flutter pub get

Platform Setup #

Android #

Add the following permissions to android/app/src/main/AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

    <application
        android:label="your_app_name"
        android:icon="@mipmap/ic_launcher">

        <receiver android:exported="false"
            android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver" />
        <receiver android:exported="false"
            android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
                <action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
                <action android:name="android.intent.action.QUICKBOOT_POWERON" />
                <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
            </intent-filter>
        </receiver>

        <activity android:name=".MainActivity">
            <!-- your activity configuration -->
        </activity>
    </application>
</manifest>

Ensure your android/app/build.gradle targets SDK 33 or higher:

android {
    compileSdkVersion 34

    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 34
    }
}

iOS #

No additional configuration required.


Usage #

Basic Setup #

Initialize ChuckInspector in your main() and pass the same NavigatorKey to your MaterialApp:

import 'package:flutter/material.dart';
import 'package:flutter_chuck_inspection/flutter_chuck_inspection.dart';

final _navigatorKey = GlobalKey<NavigatorState>();

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await ChuckInspector().init(
    navKey: _navigatorKey,
    enableNotifications: true,
  );

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorKey: _navigatorKey,
      title: 'My App',
      home: const HomeScreen(),
    );
  }
}

Using with the http Package #

import 'package:http/http.dart' as http;
import 'package:flutter_chuck_inspection/flutter_chuck_inspection.dart';

final client = ChuckHttpClient(http.Client());

final response = await client.get(
  Uri.parse('https://jsonplaceholder.typicode.com/posts'),
);
// All requests are automatically tracked.

Using with Dio #

import 'package:dio/dio.dart';
import 'package:flutter_chuck_inspection/flutter_chuck_inspection.dart';

final dio = Dio();
dio.interceptors.add(ChuckDioInterceptor());

final response = await dio.get('https://jsonplaceholder.typicode.com/posts');
// All requests are automatically tracked.

Opening the Inspector Screen #

// Programmatically
ChuckInspector().showInspector();

// Via a FloatingActionButton
FloatingActionButton(
  onPressed: () => ChuckInspector().showInspector(),
  child: const Icon(Icons.bug_report),
)

// Tapping the persistent notification also opens the inspector automatically.

Managing Notifications #

final inspector = ChuckInspector();

// Check current state
bool enabled = inspector.notificationsEnabled;

// Request permissions at runtime
bool granted = await inspector.requestNotificationPermissions();

// Check if permissions are granted
bool hasPermission = await inspector.checkNotificationPermissions();

// Toggle notifications
inspector.enableNotifications();
inspector.disableNotifications();

// Manually refresh the notification badge
await inspector.refreshNotification();

// Cancel the persistent notification
await inspector.cancelNotifications();

// Clear all recorded calls and cancel the notification
inspector.clear();

UI Overview #

Inspector Screen #

Element Description
Statistics bar Total requests, success count, and error count
Filter chips Filter by All, Success, or Errors
Request cards Method badge, status code, duration, URL path, and host
Export button Export logs as JSON or CSV, or share a text summary
Delete button Clear all recorded calls

Request Details Screen #

Four tabs with full request/response information:

Tab Content
Overview Method, URL, status code, duration, timestamp, response size
Request Request headers and body (formatted JSON)
Response Response headers and body (formatted JSON)
Error Error message and exception details

Both the Request and Response tabs include a copy-to-clipboard button.


API Reference #

ChuckInspector #

Singleton class — access it anywhere via ChuckInspector().

Properties

Property Type Description
calls List<HttpCall> Unmodifiable list of all tracked HTTP calls
totalCalls int Total number of calls
successCount int Number of successful calls (status < 400, no error)
errorCount int Number of failed calls (status >= 400 or error set)
notificationsEnabled bool Whether notifications are currently enabled
navigationKey GlobalKey<NavigatorState>? Navigator key used to push the inspector screen

Methods

Method Returns Description
init({navKey, enableNotifications, ...}) Future<void> Initialize the inspector and notification channel
showInspector() void Push the inspector screen onto the navigator stack
clear() void Clear all tracked calls and cancel the notification
enableNotifications() void Re-enable notification updates
disableNotifications() void Disable and cancel the notification
requestNotificationPermissions() Future<bool> Prompt the user to grant notification permissions
checkNotificationPermissions() Future<bool> Check whether notification permissions are granted
refreshNotification() Future<void> Manually update the notification with current stats
cancelNotifications() Future<void> Cancel the persistent notification
cancelAllNotifications() Future<void> Cancel all notifications shown by the plugin

HttpCall #

Immutable model representing a single HTTP request/response cycle.

class HttpCall {
  final String id;               // UUID
  final String method;           // GET, POST, PUT, DELETE, PATCH, ...
  final String url;              // Full request URL
  final DateTime createdAt;      // Request start time
  final Map<String, dynamic>? requestHeaders;
  final dynamic requestBody;
  final HttpResponse? response;
  final String? error;
  final Duration? duration;

  bool get isError;    // true if error != null || status >= 400
  bool get isSuccess;  // true if !isError && response != null
}

HttpResponse #

class HttpResponse {
  final int statusCode;
  final Map<String, dynamic>? headers;
  final dynamic body;
  final int? contentLength;
}

ExportUtils #

Utility class used internally by the inspector screen.

Method Description
exportToJson(calls) Serializes calls to JSON and opens the system share sheet
exportToCsv(calls) Serializes calls to CSV and opens the system share sheet

Advanced Configuration #

Custom Notification Channel #

await ChuckInspector().init(
  navKey: _navigatorKey,
  enableNotifications: true,
  notificationChannelId: 'my_api_monitor',
  notificationChannelName: 'API Monitor',
  notificationChannelDescription: 'Tracks all outgoing API calls',
);

Disable in Production #

import 'package:flutter/foundation.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  if (kDebugMode) {
    await ChuckInspector().init(
      navKey: _navigatorKey,
      enableNotifications: true,
    );
  }

  runApp(const MyApp());
}

Settings Screen Example #

class SettingsScreen extends StatefulWidget {
  const SettingsScreen({super.key});

  @override
  State<SettingsScreen> createState() => _SettingsScreenState();
}

class _SettingsScreenState extends State<SettingsScreen> {
  final _inspector = ChuckInspector();
  bool _notificationsEnabled = true;

  @override
  void initState() {
    super.initState();
    _loadPermissionState();
  }

  Future<void> _loadPermissionState() async {
    final enabled = await _inspector.checkNotificationPermissions();
    setState(() => _notificationsEnabled = enabled);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Inspector Settings')),
      body: ListView(
        children: [
          SwitchListTile(
            title: const Text('Enable Notifications'),
            subtitle: const Text('Show live HTTP request statistics'),
            value: _notificationsEnabled,
            onChanged: (value) async {
              if (value) {
                final granted =
                    await _inspector.requestNotificationPermissions();
                if (granted) {
                  _inspector.enableNotifications();
                  setState(() => _notificationsEnabled = true);
                }
              } else {
                _inspector.disableNotifications();
                setState(() => _notificationsEnabled = false);
              }
            },
          ),
          ListTile(
            leading: const Icon(Icons.delete),
            title: const Text('Clear All Data'),
            onTap: () {
              _inspector.clear();
              ScaffoldMessenger.of(context).showSnackBar(
                const SnackBar(content: Text('All HTTP calls cleared')),
              );
            },
          ),
          ListTile(
            leading: const Icon(Icons.bug_report),
            title: const Text('Open Inspector'),
            trailing: const Icon(Icons.arrow_forward_ios, size: 16),
            onTap: () => _inspector.showInspector(),
          ),
        ],
      ),
    );
  }
}

Troubleshooting #

Notifications Not Appearing #

  1. Verify POST_NOTIFICATIONS permission is in AndroidManifest.xml
  2. Ensure compileSdkVersion is 33 or higher
  3. Call requestNotificationPermissions() explicitly before the first request
  4. Check the device notification settings for your app
  5. Run flutter run --verbose and look for ChuckInspector: log lines

Inspector Screen Not Opening #

  1. Confirm navigationKey is assigned both to ChuckInspector().init() and to MaterialApp.navigatorKey
  2. Ensure init() is awaited before runApp()

HTTP Calls Not Being Tracked #

  1. Verify you are using ChuckHttpClient (not a plain http.Client) or that ChuckDioInterceptor is added to your Dio instance
  2. Make sure init() completes before the first network request
  3. When using Dio, ensure the interceptor is added before any requests are made

Example App #

See the /example folder for a complete working demo covering:

  • HTTP client integration
  • Dio interceptor integration
  • Notification permission handling
  • Settings screen with toggle
  • Programmatic inspector launch

Contributing #

Contributions are welcome!

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/your-feature
  3. Commit your changes: git commit -m 'Add your feature'
  4. Push the branch: git push origin feature/your-feature
  5. Open a Pull Request

Please follow the existing code style and add tests where applicable.


License #

This project is licensed under the MIT License. See the LICENSE file for details.


Acknowledgments #

  • Inspired by Chuck for Android
  • Built with love for the Flutter community

Support #


If this package helps you, please give it a star on pub.dev and GitHub!

0
likes
140
points
145
downloads

Documentation

API reference

Publisher

verified publishersanjaysharma.info

Weekly Downloads

A powerful HTTP inspector for Flutter — monitor, debug, and analyze requests in real-time with a sleek dark UI and persistent notifications.

Repository (GitHub)
View/report issues

License

BSD-3-Clause (license)

Dependencies

dio, flutter, flutter_local_notifications, http, path_provider, plugin_platform_interface, share_plus, uuid

More

Packages that depend on flutter_chuck_inspection

Packages that implement flutter_chuck_inspection