diff --git a/lib/networkApiServices/network_api_services.dart b/lib/networkApiServices/network_api_services.dart new file mode 100644 index 0000000..33ceba7 --- /dev/null +++ b/lib/networkApiServices/network_api_services.dart @@ -0,0 +1,192 @@ +import 'package:dio/dio.dart'; +import 'package:flutter/foundation.dart'; + +class NetworkApiService { + static final NetworkApiService _instance = NetworkApiService._internal(); + late Dio _dio; + + factory NetworkApiService() { + return _instance; + } + + NetworkApiService._internal() { + _dio = Dio( + BaseOptions( + connectTimeout: const Duration(seconds: 30), + receiveTimeout: const Duration(seconds: 30), + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }, + ), + ); + + // Add interceptors + _dio.interceptors.add( + InterceptorsWrapper( + onRequest: (options, handler) { + // Add token if available + // String? token = "use token here from local shared preference"; + // if (token != null) { + // options.headers['Authorization'] = 'Bearer $token'; + // } + + if (kDebugMode) { + print('REQUEST[${options.method}] => URL: ${options.uri}'); + } + return handler.next(options); + }, + onResponse: (response, handler) { + if (kDebugMode) { + print('RESPONSE[${response.statusCode}] => DATA: ${response.data}'); + } + return handler.next(response); + }, + onError: (error, handler) { + if (kDebugMode) { + print('ERROR[${error.response?.statusCode}] => MESSAGE: ${error.message}'); + } + return handler.next(error); + }, + ), + ); + + // Add logging interceptor in debug mode + if (kDebugMode) { + _dio.interceptors.add(LogInterceptor( + request: true, + requestHeader: true, + requestBody: true, + responseHeader: false, + responseBody: true, + error: true, + )); + } + } + + // GET API Request + Future getApi({ + required String url, + Map? queryParameters, + Options? options, + CancelToken? cancelToken, + }) async { + try { + final response = await _dio.get( + url, + queryParameters: queryParameters, + options: options, + cancelToken: cancelToken, + ); + return response; + } on DioException catch (e) { + throw _handleError(e); + } + } + + // POST API Request + Future postApi({ + required String url, + dynamic data, + Map? queryParameters, + Options? options, + CancelToken? cancelToken, + ProgressCallback? onSendProgress, + }) async { + try { + final response = await _dio.post( + url, + data: data, + queryParameters: queryParameters, + options: options, + cancelToken: cancelToken, + onSendProgress: onSendProgress, + ); + return response; + } on DioException catch (e) { + throw _handleError(e); + } + } + + // PUT API Request (Bonus) + Future putApi({ + required String url, + dynamic data, + Map? queryParameters, + Options? options, + CancelToken? cancelToken, + }) async { + try { + final response = await _dio.put( + url, + data: data, + queryParameters: queryParameters, + options: options, + cancelToken: cancelToken, + ); + return response; + } on DioException catch (e) { + throw _handleError(e); + } + } + + // DELETE API Request (Bonus) + Future deleteApi({ + required String url, + dynamic data, + Map? queryParameters, + Options? options, + CancelToken? cancelToken, + }) async { + try { + final response = await _dio.delete( + url, + data: data, + queryParameters: queryParameters, + options: options, + cancelToken: cancelToken, + ); + return response; + } on DioException catch (e) { + throw _handleError(e); + } + } + + // Error Handler + String _handleError(DioException error) { + String errorDescription = ""; + switch (error.type) { + case DioExceptionType.connectionTimeout: + errorDescription = "Connection timeout. Please try again."; + break; + case DioExceptionType.sendTimeout: + errorDescription = "Send timeout. Please try again."; + break; + case DioExceptionType.receiveTimeout: + errorDescription = "Receive timeout. Please try again."; + break; + case DioExceptionType.badCertificate: + errorDescription = "Bad certificate."; + break; + case DioExceptionType.badResponse: + errorDescription = error.response?.data['message'] ?? + "Received invalid status code: ${error.response?.statusCode}"; + break; + case DioExceptionType.cancel: + errorDescription = "Request was cancelled."; + break; + case DioExceptionType.connectionError: + errorDescription = "No internet connection."; + break; + case DioExceptionType.unknown: + errorDescription = "Something went wrong. Please try again."; + break; + } + return errorDescription; + } + + // Update headers (e.g., add token) + void updateHeaders(Map headers) { + _dio.options.headers.addAll(headers); + } +} diff --git a/pubspec.lock b/pubspec.lock index 3010dd2..ee72c53 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -129,6 +129,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.11" + dio: + dependency: "direct main" + description: + name: dio + sha256: d90ee57923d1828ac14e492ca49440f65477f4bb1263575900be731a3dac66a9 + url: "https://pub.dev" + source: hosted + version: "5.9.0" + dio_web_adapter: + dependency: transitive + description: + name: dio_web_adapter + sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78" + url: "https://pub.dev" + source: hosted + version: "2.1.1" dylib: dependency: transitive description: @@ -609,10 +625,10 @@ packages: dependency: transitive description: name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.17.0" mime: dependency: transitive description: @@ -910,10 +926,10 @@ packages: dependency: transitive description: name: test_api - sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" + sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 url: "https://pub.dev" source: hosted - version: "0.7.6" + version: "0.7.7" three_js: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index ba1f021..285cd0d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -52,6 +52,7 @@ dependencies: lottie: ^3.3.2 flutter_native_splash: ^2.4.7 video_player: ^2.10.1 + dio: ^5.9.0 dev_dependencies: flutter_test: