diff --git a/CHANGELOG.md b/CHANGELOG.md index 68cbb8c..7b5a3a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,21 @@ # Changelog -## 0.1.1 +## 0.1.2 + +##### New Features +- **Isolate-Based Data Processing:** + - Integrated Dart's `Isolate` to handle data processing in network responses, offloading CPU-intensive tasks to separate threads, which improves app performance, particularly in scenarios involving large datasets. +- **Sentry Dio Integration:** + - Added the Sentry Dio package to automatically capture and report errors in network requests to Sentry. This integration provides better monitoring and error tracking for network-related issues. + +##### Improvements +- **Updated `JsonMapper` Signature:** + - The `JsonMapper` signature has been updated from `T Function(dynamic json)` to `FutureOr Function(dynamic json)` to support both synchronous and asynchronous JSON processing. This allows for more flexible and efficient handling of JSON data. -- Updated +##### Bug Fixes +- Fixed an issue where `getList` and `postList` methods did not return results when the API response was not a list. Now, proper error handling ensures that non-list responses are processed correctly, preventing potential runtime errors. + +## 0.1.1 - Update packages. ## 0.1.0 diff --git a/README.md b/README.md index 5a7e017..43b9b81 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Wrapper around [`Dio`](https://pub.dev/packages/dio) that can perform API reques In `pubspec.yaml` add these lines to `dependencies` ```yaml -playx_network: ^0.0.9 +playx_network: ^0.1.2 ``` ## Usage diff --git a/example/lib/model/weather.dart b/example/lib/model/weather.dart index caea10c..fea7c7c 100644 --- a/example/lib/model/weather.dart +++ b/example/lib/model/weather.dart @@ -19,18 +19,6 @@ class Weather { this.currentWeather, }); - Weather.fromJson(dynamic json) { - latitude = json['latitude']; - longitude = json['longitude']; - generationtimeMs = json['generationtime_ms']; - utcOffsetSeconds = json['utc_offset_seconds']; - timezone = json['timezone']; - timezoneAbbreviation = json['timezone_abbreviation']; - elevation = json['elevation']; - currentWeather = json['current_weather'] != null - ? CurrentWeather.fromJson(json['current_weather']) - : null; - } num? latitude; num? longitude; num? generationtimeMs; @@ -40,6 +28,37 @@ class Weather { num? elevation; CurrentWeather? currentWeather; + factory Weather.fromJson(dynamic json) { + return Weather( + latitude: json['latitude'], + longitude: json['longitude'], + generationtimeMs: json['generationtime_ms'], + utcOffsetSeconds: json['utc_offset_seconds'], + timezone: json['timezone'], + timezoneAbbreviation: json['timezone_abbreviation'], + elevation: json['elevation'], + currentWeather: json['current_weather'] != null + ? CurrentWeather.fromJson(json['current_weather']) + : null, + ); + } + + static Future fromJsonAsync(dynamic json) async { + await Future.delayed(const Duration(seconds: 3)); + return Weather( + latitude: json['latitude'], + longitude: json['longitude'], + generationtimeMs: json['generationtime_ms'], + utcOffsetSeconds: json['utc_offset_seconds'], + timezone: json['timezone'], + timezoneAbbreviation: json['timezone_abbreviation'], + elevation: json['elevation'], + currentWeather: json['current_weather'] != null + ? CurrentWeather.fromJson(json['current_weather']) + : null, + ); + } + Map toJson() { final map = {}; map['latitude'] = latitude; diff --git a/example/pubspec.lock b/example/pubspec.lock index 16e7c91..1fabefe 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -41,6 +41,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.18.0" + crypto: + dependency: transitive + description: + name: crypto + sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27 + url: "https://pub.dev" + source: hosted + version: "3.0.5" cupertino_icons: dependency: "direct main" description: @@ -53,10 +61,10 @@ packages: dependency: transitive description: name: dio - sha256: e17f6b3097b8c51b72c74c9f071a605c47bcc8893839bd66732457a5ebe73714 + sha256: "0dfb6b6a1979dac1c1245e17cef824d7b452ea29bd33d3467269f9bef3715fb0" url: "https://pub.dev" source: hosted - version: "5.5.0+1" + version: "5.6.0" dio_web_adapter: dependency: transitive description: @@ -73,6 +81,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + url: "https://pub.dev" + source: hosted + version: "1.1.0" flutter: dependency: "direct main" description: flutter @@ -91,6 +107,14 @@ packages: description: flutter source: sdk version: "0.0.0" + http: + dependency: transitive + description: + name: http + sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 + url: "https://pub.dev" + source: hosted + version: "1.2.2" http_parser: dependency: transitive description: @@ -103,18 +127,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" url: "https://pub.dev" source: hosted - version: "10.0.4" + version: "10.0.5" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.5" leak_tracker_testing: dependency: transitive description: @@ -143,18 +167,18 @@ packages: dependency: transitive description: name: material_color_utilities - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.8.0" + version: "0.11.1" meta: dependency: transitive description: name: meta - sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.dev" source: hosted - version: "1.12.0" + version: "1.15.0" path: dependency: transitive description: @@ -169,15 +193,31 @@ packages: path: ".." relative: true source: path - version: "0.1.0" + version: "0.1.2" pretty_dio_logger: dependency: transitive description: name: pretty_dio_logger - sha256: "00b80053063935cf9a6190da344c5373b9d0e92da4c944c878ff2fbef0ef6dc2" + sha256: "36f2101299786d567869493e2f5731de61ce130faa14679473b26905a92b6407" url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.4.0" + sentry: + dependency: transitive + description: + name: sentry + sha256: "0f787e27ff617e4f88f7074977240406a9c5509444bac64a4dfa5b3200fb5632" + url: "https://pub.dev" + source: hosted + version: "8.7.0" + sentry_dio: + dependency: transitive + description: + name: sentry_dio + sha256: "1577428b1f03d65f077cb0e667061f9ae8c2df0cc9c6e77f2616200abaf28d86" + url: "https://pub.dev" + source: hosted + version: "8.7.0" sky_engine: dependency: transitive description: flutter @@ -191,6 +231,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.10.0" + sprintf: + dependency: transitive + description: + name: sprintf + sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" + url: "https://pub.dev" + source: hosted + version: "7.0.0" stack_trace: dependency: transitive description: @@ -227,10 +275,10 @@ packages: dependency: transitive description: name: test_api - sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" url: "https://pub.dev" source: hosted - version: "0.7.0" + version: "0.7.2" typed_data: dependency: transitive description: @@ -239,6 +287,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.2" + uuid: + dependency: transitive + description: + name: uuid + sha256: "83d37c7ad7aaf9aa8e275490669535c8080377cfa7a7004c24dfac53afffaa90" + url: "https://pub.dev" + source: hosted + version: "4.4.2" vector_math: dependency: transitive description: @@ -251,10 +307,18 @@ packages: dependency: transitive description: name: vm_service - sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" + sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc + url: "https://pub.dev" + source: hosted + version: "14.2.4" + web: + dependency: transitive + description: + name: web + sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062 url: "https://pub.dev" source: hosted - version: "14.2.1" + version: "1.0.0" sdks: - dart: ">=3.3.0 <4.0.0" + dart: ">=3.4.0 <4.0.0" flutter: ">=3.18.0-18.0.pre.54" diff --git a/lib/playx_network.dart b/lib/playx_network.dart index b45ebe7..7002e90 100644 --- a/lib/playx_network.dart +++ b/lib/playx_network.dart @@ -1,11 +1,12 @@ library playx_network; -export 'package:playx_network/src/playx_network_client.dart'; -export 'package:playx_network/src/models/network_result.dart'; -export 'package:playx_network/src/models/logger/logger_settings.dart'; -export 'package:playx_network/src/models/exceptions/network_exception.dart'; -export 'package:playx_network/src/models/exceptions/message/english_exception_message.dart'; -export 'package:playx_network/src/models/exceptions/message/exception_message.dart'; -export 'package:playx_network/src/models/error/api_error.dart'; export 'package:dio/dio.dart'; export 'package:dio/io.dart'; +export 'package:playx_network/src/models/error/api_error.dart'; +export 'package:playx_network/src/models/exceptions/message/english_exception_message.dart'; +export 'package:playx_network/src/models/exceptions/message/exception_message.dart'; +export 'package:playx_network/src/models/exceptions/network_exception.dart'; +export 'package:playx_network/src/models/logger/logger_settings.dart'; +export 'package:playx_network/src/models/network_result.dart'; +export 'package:playx_network/src/playx_network_client.dart'; +export 'package:sentry_dio/sentry_dio.dart'; diff --git a/lib/src/handler/api_handler.dart b/lib/src/handler/api_handler.dart index b74df0f..35cdac6 100644 --- a/lib/src/handler/api_handler.dart +++ b/lib/src/handler/api_handler.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'package:dio/dio.dart'; +import 'package:flutter/foundation.dart'; import 'package:playx_network/src/models/exceptions/message/english_exception_message.dart'; import 'package:playx_network/src/models/exceptions/message/exception_message.dart'; import 'package:playx_network/src/utils/utils.dart'; @@ -10,6 +11,20 @@ import '../models/exceptions/network_exception.dart'; import '../models/network_result.dart'; import '../playx_network_client.dart'; +/// parses json to object in isolate. +Future _parseJsonInIsolate(List args) async { + final data = args[0]; + final JsonMapper fromJson = args[1]; + return fromJson(data); +} + +/// parses json list to list of objects in isolate. +Future> _parseJsonListInIsolate(List args) async { + final data = args[0] as List; + final JsonMapper fromJson = args[1]; + return await Future.wait(data.map((item) async => await fromJson(item))); +} + // ignore: avoid_classes_with_only_static_members /// This class is responsible for handling the network response and extract error from it. /// and return the result whether it was successful or not. @@ -75,7 +90,7 @@ class ApiHandler { } try { - final result = fromJson(data); + final result = await compute(_parseJsonInIsolate, [data, fromJson]); return NetworkResult.success(result); // ignore: avoid_catches_without_on_clauses } on Exception catch (e, s) { @@ -147,19 +162,31 @@ class ApiHandler { } try { - final List result = - (data as List).map((item) => fromJson(item)).toList(); - if (result.isEmpty) { + if (data is List) { + final result = + await compute(_parseJsonListInIsolate, [data, fromJson]); + + if (result.isEmpty) { + _printError( + header: 'Playx Network Error :', + text: exceptionMessages.emptyResponse, + ); + return NetworkResult.error(EmptyResponseException( + errorMessage: exceptionMessages.emptyResponse, + shouldShowApiError: shouldShowApiErrors, + statusCode: -1)); + } + return NetworkResult.success(result); + } else { _printError( header: 'Playx Network Error :', - text: exceptionMessages.emptyResponse, + text: exceptionMessages.unableToProcess, ); - return NetworkResult.error(EmptyResponseException( - errorMessage: exceptionMessages.emptyResponse, + return NetworkResult.error(UnableToProcessException( + errorMessage: exceptionMessages.unableToProcess, shouldShowApiError: shouldShowApiErrors, statusCode: -1)); } - return NetworkResult.success(result); // ignore: avoid_catches_without_on_clauses } on Exception catch (e, s) { _printError( diff --git a/lib/src/playx_network_client.dart b/lib/src/playx_network_client.dart index 1e7eb0e..6244a00 100644 --- a/lib/src/playx_network_client.dart +++ b/lib/src/playx_network_client.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:dio/dio.dart'; import 'package:flutter/foundation.dart'; import 'package:playx_network/src/models/exceptions/message/english_exception_message.dart'; @@ -10,11 +12,12 @@ import 'handler/api_handler.dart'; import 'models/network_result.dart'; ///Function that converts json response to the required model. -typedef JsonMapper = T Function(dynamic json); +typedef JsonMapper = FutureOr Function(dynamic json); ///Function that converts json error response from api to error message. typedef ErrorMapper = String? Function(dynamic json); +/// Function that handles unauthorized request. typedef UnauthorizedRequestHandler = void Function(Response? response); /// PlayxNetworkClient is a Wrapper around [Dio] that can perform api request diff --git a/pubspec.yaml b/pubspec.yaml index fa0f272..94defba 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: playx_network description: playx_network is a Wrapper around Dio that can perform api request with better error handling and easily get the result of any api request. -version: 0.1.1 +version: 0.1.2 homepage: https://sourcya.com/ repository: https://github.com/playx-flutter/playx_network issue_tracker: https://github.com/playx-flutter/playx_network/issues @@ -18,9 +18,9 @@ topics: dependencies: flutter: sdk: flutter - dio: ^5.5.0+1 - pretty_dio_logger: ^1.3.1 - + dio: ^5.6.0 + pretty_dio_logger: ^1.4.0 + sentry_dio: ^8.7.0 dev_dependencies: flutter_test: