diff --git a/README.md b/README.md index 18e0ccd..5dd082c 100644 --- a/README.md +++ b/README.md @@ -149,7 +149,41 @@ final connection = InternetConnection.createInstance( ); ``` -### 7. Pause and Resume on App Lifecycle Changes +### 7. Using a custom connectivity check method + +For advanced use cases, you can completely customize how connectivity checks are performed by providing your own connectivity checker: + +```dart +final connection = InternetConnection.createInstance( + customConnectivityCheck: (option) async { + // Example: Use the Dio http client + try { + final dio = Dio(); + final response = await dio.head( + option.uri, + options: Options(headers: option.headers, receiveTimeout: option.timeout, validateStatus: (_) => true), + ); + + return InternetCheckResult( + option: option, + isSuccess: response.statusCode == 200, + ); + } catch (_) { + return InternetCheckResult(option: option, isSuccess: false); + } + }, +); +``` + +This customization gives you full control over the connectivity detection process, allowing you to: + +- Implement platform-specific network detection +- Use alternate connectivity checking strategies +- Implement custom fallback mechanisms +- Add detailed logging or metrics for connectivity checks +- Integrate with other network monitoring tools + +### 8. Pause and Resume on App Lifecycle Changes For situation where you want to pause any network requests when the app goes into the background and resume them when the app comes back into the foreground diff --git a/lib/src/internet_connection.dart b/lib/src/internet_connection.dart index 60deb4a..b49e4cf 100644 --- a/lib/src/internet_connection.dart +++ b/lib/src/internet_connection.dart @@ -1,5 +1,17 @@ part of '../internet_connection_checker_plus.dart'; +/// A callback function for checking if a specific internet endpoint is +/// reachable. +/// +/// Takes a single [InternetCheckOption] and returns a +/// [Future] that completes with an [InternetCheckResult]. +/// +/// This allows for complete customization of how connectivity is checked for +/// each endpoint. +typedef ConnectivityCheckCallback = Future Function( + InternetCheckOption option, +); + /// A utility class for checking internet connectivity status. /// /// This class provides functionality to monitor and verify internet @@ -70,11 +82,17 @@ class InternetConnection { /// /// - If [useDefaultOptions] is `false`, you must provide a non-empty /// [customCheckOptions] list. + /// + /// The [customConnectivityCheck] allows you to provide a custom method for + /// checking endpoint reachability. If provided, it will be used for all + /// connectivity checks instead of the default HTTP HEAD request + /// implementation. InternetConnection.createInstance({ Duration? checkInterval, List? customCheckOptions, bool useDefaultOptions = true, this.enableStrictCheck = false, + this.customConnectivityCheck, }) : _checkInterval = checkInterval ?? _defaultCheckInterval, assert( useDefaultOptions || customCheckOptions?.isNotEmpty == true, @@ -128,6 +146,12 @@ class InternetConnection { /// Defaults to `false`. final bool enableStrictCheck; + /// Function to check reachability of a single network endpoint. + /// + /// This can be customized to allow for different ways of checking + /// connectivity. + final ConnectivityCheckCallback? customConnectivityCheck; + /// The last known internet connection status result. InternetStatus? _lastStatus; @@ -142,6 +166,10 @@ class InternetConnection { InternetCheckOption option, ) async { try { + if (customConnectivityCheck != null) { + return customConnectivityCheck!.call(option); + } + final response = await http .head(option.uri, headers: option.headers) .timeout(option.timeout); diff --git a/test/internet_connection_test.dart b/test/internet_connection_test.dart index e216403..aed2d8f 100644 --- a/test/internet_connection_test.dart +++ b/test/internet_connection_test.dart @@ -70,6 +70,52 @@ void main() { expect(await checker.hasInternetAccess, expectedStatus); }); }); + + test( + 'creates and uses default HTTP client when none is provided', + () async { + // This test verifies default behavior, which is hard to test directly + // So we test that the checker works without explicitly providing a client + final checker = InternetConnection.createInstance( + customCheckOptions: [ + InternetCheckOption(uri: Uri.parse('https://www.example.com')), + ], + useDefaultOptions: false, + ); + + // Since we can't mock the global HTTP client in this test, + // we just verify that no exception is thrown when executing this + // This inherently tests that a default client was created and used + // Successfully checking internet access means the internal client works + expect(checker.hasInternetAccess, isA>()); + }, + ); + + test('uses custom reachability checker when provided', () async { + var reachabilityCheckerCalled = false; + + customReachabilityChecker(InternetCheckOption option) async { + reachabilityCheckerCalled = true; + expect(option.uri.host, 'example.com'); + // Return success for this test + return InternetCheckResult( + option: option, + isSuccess: true, + ); + } + + final checker = InternetConnection.createInstance( + customCheckOptions: [ + InternetCheckOption(uri: Uri.parse('https://example.com')), + ], + useDefaultOptions: false, + customConnectivityCheck: customReachabilityChecker, + ); + + final result = await checker.hasInternetAccess; + expect(reachabilityCheckerCalled, true); + expect(result, true); + }); }); group('enableStrictCheck', () {