From 05962d07ed2c34908d563792b1fc44e48d94f0e9 Mon Sep 17 00:00:00 2001 From: pavel-kuznetsov-hypertrack <78730314+pavel-kuznetsov-hypertrack@users.noreply.github.com> Date: Mon, 2 Oct 2023 18:42:05 +0300 Subject: [PATCH] Use the new SDK with static API (#38) Update SDK iOS to 5.0.2 Update SDK Android to 7.0.3 Add .editorconfig --- .editorconfig | 3 + .justfile | 5 +- CHANGELOG.md | 132 +++++- CONTRIBUTING.md | 32 +- README.md | 15 +- android/build.gradle | 7 +- .../sdk/flutter/FlutterSerialization.kt | 19 +- .../sdk/flutter/HyperTrackPlugin.kt | 291 ++++++------ .../sdk/flutter/common/GeotagData.kt | 2 +- .../sdk/flutter/common/HyperTrackError.kt | 28 -- .../flutter/common/HyperTrackSdkWrapper.kt | 306 ++++-------- .../sdk/flutter/common/LocationError.kt | 9 - .../sdk/flutter/common/SdkInitParams.kt | 44 -- .../sdk/flutter/common/SdkMethod.kt | 20 +- .../sdk/flutter/common/Serialization.kt | 371 +++++++++------ .../common/{Result.kt => WrapperResult.kt} | 18 +- docs/__404error.html | 2 +- .../HyperTrackError.html | 162 +++---- .../HyperTrackError/HyperTrackError.html | 28 +- .../HyperTrackError/values-constant.html | 28 +- .../data_types_hypertrack_error-library.html | 2 +- docs/data_types_json/JSON-class.html | 240 ++++++++++ docs/data_types_json/JSON/JSON.html | 131 ++++++ docs/data_types_json/JSON/fromMap.html | 146 ++++++ docs/data_types_json/JSON/fromString.html | 146 ++++++ docs/data_types_json/JSON/serialize.html | 139 ++++++ docs/data_types_json/JSONArray-class.html | 35 +- docs/data_types_json/JSONArray/JSONArray.html | 10 +- docs/data_types_json/JSONArray/items.html | 6 +- docs/data_types_json/JSONArray/serialize.html | 8 +- docs/data_types_json/JSONBool-class.html | 29 +- docs/data_types_json/JSONBool/JSONBool.html | 2 +- docs/data_types_json/JSONBool/serialize.html | 4 +- docs/data_types_json/JSONBool/value.html | 2 +- docs/data_types_json/JSONNull-class.html | 29 +- docs/data_types_json/JSONNull/JSONNull.html | 2 +- docs/data_types_json/JSONNull/serialize.html | 4 +- docs/data_types_json/JSONNumber-class.html | 29 +- .../JSONNumber/JSONNumber.html | 2 +- .../data_types_json/JSONNumber/serialize.html | 4 +- docs/data_types_json/JSONNumber/value.html | 2 +- docs/data_types_json/JSONObject-class.html | 33 +- .../JSONObject/JSONObject.html | 4 +- docs/data_types_json/JSONObject/fields.html | 6 +- .../data_types_json/JSONObject/serialize.html | 4 +- docs/data_types_json/JSONString-class.html | 29 +- .../JSONString/JSONString.html | 2 +- .../data_types_json/JSONString/serialize.html | 4 +- docs/data_types_json/JSONString/value.html | 2 +- .../data_types_json-library.html | 34 +- docs/data_types_json/fromMap.html | 160 +++++++ docs/data_types_location/Location-class.html | 2 +- .../Location/Location.html | 2 +- .../Location/latitude.html | 2 +- .../Location/longitude.html | 2 +- .../data_types_location-library.html | 2 +- .../Errors-class.html | 2 +- .../Errors/Errors.html | 2 +- .../LocationError-class.html | 2 +- .../LocationError/LocationError.errors.html | 2 +- .../LocationError.notRunning.html | 2 +- .../LocationError/LocationError.starting.html | 2 +- .../NotRunning-class.html | 2 +- .../NotRunning/NotRunning.html | 2 +- .../Starting-class.html | 2 +- .../Starting/Starting.html | 2 +- .../data_types_location_error-library.html | 2 +- .../LocationWithDeviation-class.html | 2 +- .../LocationWithDeviation.html | 2 +- .../LocationWithDeviation/deviation.html | 2 +- .../LocationWithDeviation/location.html | 2 +- ...types_location_with_deviation-library.html | 2 +- docs/data_types_result/Failure-class.html | 198 ++++++++ docs/data_types_result/Failure/Failure.html | 135 ++++++ docs/data_types_result/Result-class.html | 6 +- .../Result/Result.error.html | 4 +- .../Result/Result.success.html | 2 +- docs/data_types_result/Success-class.html | 4 +- docs/data_types_result/Success/Success.html | 4 +- docs/data_types_result/Success/value.html | 2 +- .../data_types_result-library.html | 8 +- docs/hypertrack/HyperTrack-class.html | 214 +++++---- docs/hypertrack/HyperTrack/HyperTrack.html | 146 ++++++ docs/hypertrack/HyperTrack/addGeotag.html | 50 +- .../addGeotagWithExpectedLocation.html | 50 +- docs/hypertrack/HyperTrack/deviceId.html | 45 +- docs/hypertrack/HyperTrack/errors.html | 162 +++++++ .../HyperTrack/errorsSubscription.html | 162 +++++++ docs/hypertrack/HyperTrack/isAvailable.html | 47 +- .../HyperTrack/isAvailableSubscription.html | 162 +++++++ docs/hypertrack/HyperTrack/isTracking.html | 45 +- .../HyperTrack/isTrackingSubscription.html | 162 +++++++ docs/hypertrack/HyperTrack/locate.html | 158 +++++++ docs/hypertrack/HyperTrack/location.html | 45 +- .../HyperTrack/locationSubscription.html | 162 +++++++ docs/hypertrack/HyperTrack/metadata.html | 163 +++++++ docs/hypertrack/HyperTrack/name.html | 163 +++++++ .../hypertrack/HyperTrack/setIsAvailable.html | 158 +++++++ docs/hypertrack/HyperTrack/setIsTracking.html | 158 +++++++ docs/hypertrack/HyperTrack/setMetadata.html | 48 +- docs/hypertrack/HyperTrack/setName.html | 50 +- docs/hypertrack/hypertrack-library.html | 4 +- docs/index.html | 18 +- docs/index.json | 2 +- docs/search.html | 2 +- ...andler.swift => ErrorsStreamHandler.swift} | 7 +- ios/Classes/HyperTrackPluginSwift.swift | 158 ++++--- ...r.swift => IsAvailableStreamHandler.swift} | 7 +- ...er.swift => IsTrackingStreamHandler.swift} | 7 +- ios/Classes/LocateStreamHandler.swift | 21 + ios/Classes/LocationStreamHandler.swift | 19 + ios/Classes/common/DictionaryDecoder.swift | 10 +- ios/Classes/common/HyperTrackError.swift | 20 - ios/Classes/common/HyperTrackSDKWrapper.swift | 126 ++--- ios/Classes/common/SDKInitParams.swift | 13 - ios/Classes/common/SDKMethod.swift | 25 +- ios/Classes/common/Serialization.swift | 445 ++++++++---------- ios/hypertrack_plugin.podspec | 4 +- lib/data_types/hypertrack_error.dart | 55 ++- lib/data_types/json.dart | 76 ++- lib/data_types/result.dart | 13 +- lib/hypertrack.dart | 193 ++++---- lib/src/sdk_method.dart | 25 +- lib/src/serialization.dart | 243 ++++++++++ lib/src/serialization/availability.dart | 19 - lib/src/serialization/common.dart | 2 - lib/src/serialization/device_id.dart | 12 - lib/src/serialization/device_name.dart | 10 - lib/src/serialization/geotag_data.dart | 20 - lib/src/serialization/hypertrack_error.dart | 49 -- lib/src/serialization/location.dart | 23 - lib/src/serialization/location_error.dart | 27 -- lib/src/serialization/location_result.dart | 22 - .../location_with_deviation.dart | 21 - .../location_with_deviation_result.dart | 20 - lib/src/serialization/metadata.dart | 5 - lib/src/serialization/result.dart | 22 - lib/src/serialization/tracking_state.dart | 12 - pubspec.yaml | 2 +- 139 files changed, 5250 insertions(+), 2036 deletions(-) create mode 100644 .editorconfig delete mode 100644 android/src/main/kotlin/com/hypertrack/sdk/flutter/common/HyperTrackError.kt delete mode 100644 android/src/main/kotlin/com/hypertrack/sdk/flutter/common/LocationError.kt delete mode 100644 android/src/main/kotlin/com/hypertrack/sdk/flutter/common/SdkInitParams.kt rename android/src/main/kotlin/com/hypertrack/sdk/flutter/common/{Result.kt => WrapperResult.kt} (78%) create mode 100644 docs/data_types_json/JSON-class.html create mode 100644 docs/data_types_json/JSON/JSON.html create mode 100644 docs/data_types_json/JSON/fromMap.html create mode 100644 docs/data_types_json/JSON/fromString.html create mode 100644 docs/data_types_json/JSON/serialize.html create mode 100644 docs/data_types_json/fromMap.html create mode 100644 docs/data_types_result/Failure-class.html create mode 100644 docs/data_types_result/Failure/Failure.html create mode 100644 docs/hypertrack/HyperTrack/HyperTrack.html create mode 100644 docs/hypertrack/HyperTrack/errors.html create mode 100644 docs/hypertrack/HyperTrack/errorsSubscription.html create mode 100644 docs/hypertrack/HyperTrack/isAvailableSubscription.html create mode 100644 docs/hypertrack/HyperTrack/isTrackingSubscription.html create mode 100644 docs/hypertrack/HyperTrack/locate.html create mode 100644 docs/hypertrack/HyperTrack/locationSubscription.html create mode 100644 docs/hypertrack/HyperTrack/metadata.html create mode 100644 docs/hypertrack/HyperTrack/name.html create mode 100644 docs/hypertrack/HyperTrack/setIsAvailable.html create mode 100644 docs/hypertrack/HyperTrack/setIsTracking.html rename ios/Classes/{ErrorsEventStreamHandler.swift => ErrorsStreamHandler.swift} (67%) rename ios/Classes/{AvailabilityEventStreamHandler.swift => IsAvailableStreamHandler.swift} (64%) rename ios/Classes/{TrackingEventStreamHandler.swift => IsTrackingStreamHandler.swift} (65%) create mode 100644 ios/Classes/LocateStreamHandler.swift create mode 100644 ios/Classes/LocationStreamHandler.swift delete mode 100644 ios/Classes/common/HyperTrackError.swift delete mode 100644 ios/Classes/common/SDKInitParams.swift create mode 100644 lib/src/serialization.dart delete mode 100644 lib/src/serialization/availability.dart delete mode 100644 lib/src/serialization/common.dart delete mode 100644 lib/src/serialization/device_id.dart delete mode 100644 lib/src/serialization/device_name.dart delete mode 100644 lib/src/serialization/geotag_data.dart delete mode 100644 lib/src/serialization/hypertrack_error.dart delete mode 100644 lib/src/serialization/location.dart delete mode 100644 lib/src/serialization/location_error.dart delete mode 100644 lib/src/serialization/location_result.dart delete mode 100644 lib/src/serialization/location_with_deviation.dart delete mode 100644 lib/src/serialization/location_with_deviation_result.dart delete mode 100644 lib/src/serialization/metadata.dart delete mode 100644 lib/src/serialization/result.dart delete mode 100644 lib/src/serialization/tracking_state.dart diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..fe66b0a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,3 @@ +[android/src/main/kotlin/com/hypertrack/sdk/flutter/**/*.kt] +ktlint_standard_enum-entry-name-case = disabled +ktlint_standard_no-wildcard-imports = disabled diff --git a/.justfile b/.justfile index 7726414..26e6249 100644 --- a/.justfile +++ b/.justfile @@ -1,10 +1,13 @@ alias r := release alias d := docs +lint: + ktlint --format . + release: docs flutter pub publish --dry-run -docs: +docs: lint dart doc cp -R doc/api/ docs rm -r doc diff --git a/CHANGELOG.md b/CHANGELOG.md index 3bfcd40..799d6de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,57 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.0.0] - 2023-10-02 + +### Added + +- `locate()` to ask for one-time user location +- `locationSubcription` to subscribe to user location updates +- `errors` getter +- `name` getter +- `metadata` getter +- HyperTrackError types: + - `noExemptionFromBackgroundStartRestrictions` + - `permissionsNotificationsDenied` + +### Changed + +- Updated HyperTrack Android SDK + to [7.0.3](https://github.com/hypertrack/sdk-android/blob/master/CHANGELOG.md#703---2023-09-28) +- Add Android SDK plugins (`location-services-google` and `push-service-firebase`) +- Updated HyperTrack iOS SDK to [5.0.2](https://github.com/hypertrack/sdk-ios/releases/tag/5.0.2) +- The whole HyperTrack API is now static +- Changed the way to provide publishableKey ( + - You need to add `HyperTrackPublishableKey` `meta-data` item to your `AndroidManifest.xml` and + the same entry to `Info.plist`) +- Renamed HyperTrackError types: + - `gpsSignalLost` to `locationSignalLost` + - `locationPermissionsDenied` to `permissionsLocationDenied` + - `locationPermissionsInsufficientForBackground` + to `permissionsLocationInsufficientForBackground` + - `locationPermissionsNotDetermined` to `permissionsLocationNotDetermined` + - `locationPermissionsProvisional` to `locationPermissionsProvisional` + - `locationPermissionsReducedAccuracy` to `permissionsLocationReducedAccuracy` + - `locationPermissionsRestricted` to `permissionsLocationRestricted` +- Renamed `setAvailability()` to `setIsAvailable(boolean)` +- Changed `startTracking()` and `stopTracking()` to `setIsTracking(boolean)` +- Renamed `onTrackingChanged` to `isTrackingSubscription` +- Renamed `onAvailabilityChanged` to `isAvailableSubscription` +- Renamed `onError` to `errorsSubscription` +- Renamed `JSONValue` to `JSON` + +### Removed + +- `initialize()` method (the API is now static) +- Motion Activity permissions are not required for tracking anymore +- HyperTrackError types: + - `motionActivityPermissionsDenied` + - `motionActivityServicesDisabled` + - `motionActivityServicesUnavailable` + - `motionActivityPermissionsRestricted` + - `networkConnectionUnavailable` +- `sync()` method + ## [1.1.3] - 2023-06-16 ### Changed @@ -12,30 +63,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [1.1.2] - 2023-06-14 ### Changed + - Updated HyperTrack Android SDK to 6.4.2 - Updated Kotlin to 1.6.21 ## [1.1.1] - 2023-06-01 ### Changed + - Updated HyperTrack iOS SDK to 4.16.0 ## [1.1.0] - 2023-05-18 ### Added + - `addGeotag` with expected location - `automaticallyRequestPermissions` param to SDK initialization - JSONNull type to JSONValue ### Changed + - Updated HyperTrack iOS SDK to 4.15.0 ### Fixed + - String representation of errors in subscribeToErrors result ## [1.0.0] - 2023-02-17 ### Changed + - Updated HyperTrack iOS SDK to 4.14.0 - Updated HyperTrack Android SDK to 6.4.0 - `syncDeviceSettings()` renamed to `sync()` @@ -45,15 +102,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `stop()` renamed to `stopTracking()` ### Added + - `initialize()` configuration params for - - Debug logging - - Background location permissions request for Android - - Mock locations + - Debug logging + - Background location permissions request for Android + - Mock locations - `onAvailabilityChanged` stream - `onError` stream - Location result for `addGeotag` ### Removed + - `getLatestLocation()` - `allowMockLocations()` (use `initialize()` param `allowMockLocations` instead) - `enableDebugLogging()` (use `initialize()` param `loggingEnabled` instead) @@ -61,107 +120,170 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 'expectedLocation' param from 'addGeotag()' ## [0.4.3] - 2022-09-16 + #### Changed + - Android SDK updated to 6.3.0 ## [0.4.2] - 2022-08-30 + #### Changed + - Android SDK updated to 6.2.2 ## [0.4.1] - 2022-07-19 + #### Changed + - Android SDK updated to 6.2.0 - iOS SDK updated to 4.12.3 ## [0.4.0] - 2022-07-07 + #### Changed + - Android SDK updated to 6.1.4 ## [0.3.1] - 2022-07-05 + #### Fixed + - Android null type safety plugin fixes ## [0.3.0] - 2021-11-17 + #### Changed + - Android SDK updated to 5.4.5 ## [0.2.1] - 2021-07-07 + #### Changed + - No code changes. Package metadata was updated to improve scoring. ## [0.2.0] - 2021-07-07 + #### Added + - Dart nullability support added to comply with Flutter 2 requirements + #### Changed + - Android SDK updated to 5.2.5 ## [0.1.9] - 2021-05-07 + #### Changed + - Android SDK updated to 4.12.0 ## [0.1.8] - 2021-04-07 + #### Changed + - Android SDK updated to 4.11.0 ## [0.1.7] - 2020-12-24 + #### Changed + - Android SDK updated to 4.9.0 - Firebase conflicts were fixed. ## [0.1.6] - 2020-12-23 + #### Fixed + - iOS plugin runtime error notification. + #### Changed -- iOS SDK version updated to 4.7.0 +- iOS SDK version updated to 4.7.0 ## [0.1.5] - 2020-12-16 + #### Fixed + - iOS plugin, incorrect `permissions_error` notification. ## [0.1.4] - 2020-11-20 + #### Fixed + - Firebase tokens and messages forwarding. + #### Changed + - iOS SDK version updated to 4.6.0 ## [0.1.3] - 2020-11-02 + #### Changed + - Android SDK version updated to 4.8.0 ## [0.1.2] - 2020-09-28 + #### Changed + - Android SDK version updated to 4.6.0 ## [0.1.1] - 2020-06-18 + #### Changed + - Android SDK version updated to 4.4.1 -- setTripMarker` replaced with `addGeotag` +- setTripMarker` replaced with `addGeotag` ## [0.1.0] - 2020-03-24 + #### Added + - Initial release. [1.1.3]: https://github.com/hypertrack/sdk-flutter/releases/tag/1.1.3 + [1.1.2]: https://github.com/hypertrack/sdk-flutter/releases/tag/1.1.2 + [1.1.1]: https://github.com/hypertrack/sdk-flutter/releases/tag/1.1.1 + [1.1.0]: https://github.com/hypertrack/sdk-flutter/releases/tag/1.1.0 + [1.0.0]: https://github.com/hypertrack/sdk-flutter/releases/tag/1.0.0 + [0.4.3]: https://github.com/hypertrack/sdk-flutter/releases/tag/0.4.3 + [0.4.2]: https://github.com/hypertrack/sdk-flutter/releases/tag/0.4.2 + [0.4.1]: https://github.com/hypertrack/sdk-flutter/releases/tag/0.4.1 + [0.4.0]: https://github.com/hypertrack/sdk-flutter/releases/tag/0.4.0 + [0.3.1]: https://github.com/hypertrack/sdk-flutter/releases/tag/0.3.1 + [0.3.0]: https://github.com/hypertrack/sdk-flutter/releases/tag/0.3.0 + [0.2.1]: https://github.com/hypertrack/sdk-flutter/releases/tag/0.2.1 + [0.2.0]: https://github.com/hypertrack/sdk-flutter/releases/tag/0.2.0 + [0.1.9]: https://github.com/hypertrack/sdk-flutter/releases/tag/0.1.9 + [0.1.8]: https://github.com/hypertrack/sdk-flutter/releases/tag/0.1.8 + [0.1.7]: https://github.com/hypertrack/sdk-flutter/releases/tag/0.1.7 + [0.1.6]: https://github.com/hypertrack/sdk-flutter/releases/tag/0.1.6 + [0.1.5]: https://github.com/hypertrack/sdk-flutter/releases/tag/0.1.5 + [0.1.4]: https://github.com/hypertrack/sdk-flutter/releases/tag/0.1.4 + [0.1.3]: https://github.com/hypertrack/sdk-flutter/releases/tag/0.1.3 + [0.1.2]: https://github.com/hypertrack/sdk-flutter/releases/tag/0.1.2 + [0.1.1]: https://github.com/hypertrack/sdk-flutter/releases/tag/0.1.1 + [0.1.0]: https://github.com/hypertrack/sdk-flutter/releases/tag/0.1.0 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b599307..367333a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,7 +11,7 @@ - implementation 'com.hypertrack:hypertrack:**version** - ios - [ios/hypertrack_plugin.podspec](ios/hypertrack_plugin.podspec) - - s.dependency 'HyperTrack/Objective-C', '**version**' + - s.dependency 'HyperTrack', '**version**' 2. Increment wrapper version - [pubspec.yaml](pubspec.yaml) @@ -20,17 +20,17 @@ 3. Update [CHANGELOG](CHANGELOG.md) - - **Add the release link to the bottom** - + - **Add the release link to the bottom** + 4. Update badge in [README](README.md) - + 5. Run `just release` to do a release dry-run and is everything OK - + 6. Merge changes and create a version tag - + 7. Create a release - Release title - version - + 8. Publish Flutter package with `flutter pub publish` ### How to change build config @@ -38,16 +38,16 @@ #### Android - compileSdkVersion - - android/build.gradle - - `android {}` - - compileSdkVersion + - android/build.gradle + - `android {}` + - compileSdkVersion - minSdkVersion - - android/build.gradle - - `defaultConfig {}` - - minSdkVersion + - android/build.gradle + - `defaultConfig {}` + - minSdkVersion - platform version (flutter) - - pubspec.yaml - - environment: - - sdk: + - pubspec.yaml + - environment: + - sdk: diff --git a/README.md b/README.md index 282e346..787451c 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,19 @@ - # Flutter HyperTrack SDK [![GitHub](https://img.shields.io/github/license/hypertrack/sdk-flutter?color=orange)](./LICENSE) [![Pub Version](https://img.shields.io/pub/v/hypertrack_plugin?color=blueviolet)](https://pub.dev/packages/hypertrack_plugin) -[![iOS SDK](https://img.shields.io/badge/iOS%20SDK-4.16.1-brightgreen.svg)](https://github.com/hypertrack/sdk-ios) -[![Android SDK](https://img.shields.io/badge/Android%20SDK-6.4.2-brightgreen.svg)](https://github.com/hypertrack/sdk-android) +[![iOS SDK](https://img.shields.io/badge/iOS%20SDK-5.0.2-brightgreen.svg)](https://github.com/hypertrack/sdk-ios) +[![Android SDK](https://img.shields.io/badge/Android%20SDK-7.0.3-brightgreen.svg)](https://github.com/hypertrack/sdk-android) -[HyperTrack](https://www.hypertrack.com) lets you add live location tracking to your mobile app. Live location is made available along with ongoing activity, tracking controls and tracking outage with reasons. +[HyperTrack](https://www.hypertrack.com) lets you add live location tracking to your mobile app. +Live location is made available along with ongoing activity, tracking controls and tracking outage +with reasons. -Flutter HyperTrack SDK is a wrapper around native iOS and Android SDKs that allows to integrate HyperTrack into Flutter apps. +Flutter HyperTrack SDK is a wrapper around native iOS and Android SDKs that allows to integrate +HyperTrack into Flutter apps. -For information about how to get started with Flutter HyperTrack SDK check this [Guide](https://hypertrack.com/docs/install-sdk-flutter). +For information about how to get started with Flutter HyperTrack SDK check +this [Guide](https://hypertrack.com/docs/install-sdk-flutter). ## Installation diff --git a/android/build.gradle b/android/build.gradle index 884b09a..11c0cac 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -21,7 +21,7 @@ rootProject.allprojects { mavenLocal() maven { name 'hypertrack' - url 'https://s3-us-west-2.amazonaws.com/m2.hypertrack.com/' + url 'https://s3-us-west-2.amazonaws.com/m2.hypertrack.com/' } } } @@ -43,7 +43,10 @@ android { disable 'InvalidPackage' } dependencies { - implementation 'com.hypertrack:hypertrack:6.4.2' + def hyperTrackVersion = "7.0.3" + implementation "com.hypertrack:sdk-android:${hyperTrackVersion}" + implementation "com.hypertrack:location-services-google:${hyperTrackVersion}" + implementation "com.hypertrack:push-service-firebase:${hyperTrackVersion}" } } diff --git a/android/src/main/kotlin/com/hypertrack/sdk/flutter/FlutterSerialization.kt b/android/src/main/kotlin/com/hypertrack/sdk/flutter/FlutterSerialization.kt index d03b343..69e9277 100644 --- a/android/src/main/kotlin/com/hypertrack/sdk/flutter/FlutterSerialization.kt +++ b/android/src/main/kotlin/com/hypertrack/sdk/flutter/FlutterSerialization.kt @@ -1,18 +1,18 @@ package com.hypertrack.sdk.flutter -import android.util.Log -import com.hypertrack.sdk.flutter.HyperTrackPlugin.Companion.ERROR_CODE_METHOD_CALL import com.hypertrack.sdk.flutter.common.* import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel +private const val ERROR_CODE_METHOD_CALL = "METHOD_CALL" + internal fun Unit.sendAsFlutterResult(call: MethodCall, flutterResult: MethodChannel.Result) { return flutterResult.success(null) } -internal fun Result.sendAsFlutterResult( +internal fun WrapperResult.sendAsFlutterResult( call: MethodCall, - flutterResult: MethodChannel.Result + flutterResult: MethodChannel.Result, ) { when (this) { is Success -> { @@ -20,30 +20,35 @@ internal fun Result.sendAsFlutterResult( is Unit -> { flutterResult.success(null) } + is String -> { flutterResult.success(this.success) } + is Map<*, *> -> { flutterResult.success(this.success) } + is NotImplemented -> { flutterResult.notImplemented() } + else -> { flutterResult.error( ERROR_CODE_METHOD_CALL, "onMethodCall(${call.method}) - Invalid response ${this.success}", - null + null, ) } } } + is Failure -> { if (this.failure is Exception) { flutterResult.error( ERROR_CODE_METHOD_CALL, this.failure.toString(), - null + null, ) } else { throw this.failure @@ -52,7 +57,7 @@ internal fun Result.sendAsFlutterResult( } } -internal fun Result.crashAppIfError() { +internal fun WrapperResult.crashAppIfError() { if (this is Failure) { throw Throwable(this.failure.toString(), this.failure) } diff --git a/android/src/main/kotlin/com/hypertrack/sdk/flutter/HyperTrackPlugin.kt b/android/src/main/kotlin/com/hypertrack/sdk/flutter/HyperTrackPlugin.kt index 1d354a9..ebc7235 100644 --- a/android/src/main/kotlin/com/hypertrack/sdk/flutter/HyperTrackPlugin.kt +++ b/android/src/main/kotlin/com/hypertrack/sdk/flutter/HyperTrackPlugin.kt @@ -1,11 +1,15 @@ package com.hypertrack.sdk.flutter -import com.hypertrack.sdk.* +import com.hypertrack.sdk.android.* import com.hypertrack.sdk.flutter.common.* -import com.hypertrack.sdk.flutter.common.Result +import com.hypertrack.sdk.flutter.common.Serialization.deserializeGeotagData +import com.hypertrack.sdk.flutter.common.Serialization.serializeErrors import com.hypertrack.sdk.flutter.common.Serialization.serializeIsAvailable import com.hypertrack.sdk.flutter.common.Serialization.serializeIsTracking +import com.hypertrack.sdk.flutter.common.Serialization.serializeLocateResult +import com.hypertrack.sdk.flutter.common.Serialization.serializeLocationResult import com.hypertrack.sdk.flutter.common.Success +import com.hypertrack.sdk.flutter.common.WrapperResult import io.flutter.embedding.engine.plugins.FlutterPlugin import io.flutter.plugin.common.BinaryMessenger import io.flutter.plugin.common.EventChannel @@ -23,15 +27,17 @@ public class HyperTrackPlugin : FlutterPlugin, MethodCallHandler { private var methodChannel: MethodChannel? = null // send events from the SDK to plugin clients - private var trackingStateEventChannel: EventChannel? = null - private var availabilityEventChannel: EventChannel? = null - private var errorEventChannel: EventChannel? = null + private var errorsEventChannel: EventChannel? = null + private var isTrackingEventChannel: EventChannel? = null + private var isAvailableEventChannel: EventChannel? = null + private var locateEventChannel: EventChannel? = null + private var locationEventChannel: EventChannel? = null - private var trackingStateListener: TrackingStateObserver.OnTrackingStateChangeListener? = null - private var errorChannelTrackingStateListener: TrackingStateObserver.OnTrackingStateChangeListener? = - null - private var availabilityListener: AvailabilityStateObserver.OnAvailabilityStateChangeListener? = - null + private var errorsCancellable: HyperTrack.Cancellable? = null + private var isTrackingCancellable: HyperTrack.Cancellable? = null + private var isAvailableCancellable: HyperTrack.Cancellable? = null + private var locateCancellable: HyperTrack.Cancellable? = null + private var locationCancellable: HyperTrack.Cancellable? = null override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { val messenger = flutterPluginBinding.binaryMessenger @@ -43,10 +49,24 @@ public class HyperTrackPlugin : FlutterPlugin, MethodCallHandler { override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { methodChannel?.setMethodCallHandler(null) methodChannel = null - trackingStateEventChannel?.setStreamHandler(null) - trackingStateEventChannel = null - availabilityEventChannel?.setStreamHandler(null) - availabilityEventChannel = null + + errorsCancellable?.cancel() + isTrackingCancellable?.cancel() + isAvailableCancellable?.cancel() + locateCancellable?.cancel() + locationCancellable?.cancel() + + errorsEventChannel?.setStreamHandler(null) + isTrackingEventChannel?.setStreamHandler(null) + isAvailableEventChannel?.setStreamHandler(null) + locateEventChannel?.setStreamHandler(null) + locationEventChannel?.setStreamHandler(null) + + errorsEventChannel = null + isTrackingEventChannel = null + isAvailableEventChannel = null + locateEventChannel = null + locationEventChannel = null } override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { @@ -54,8 +74,8 @@ public class HyperTrackPlugin : FlutterPlugin, MethodCallHandler { } private fun invokeSdkMethod( - call: MethodCall - ): Result<*> { + call: MethodCall, + ): WrapperResult<*> { val method = SdkMethod .values() .firstOrNull { it.name == call.method } @@ -63,60 +83,77 @@ public class HyperTrackPlugin : FlutterPlugin, MethodCallHandler { return Success(NotImplemented) } return when (method) { - SdkMethod.initialize -> { - withArgs(call) { args -> - HyperTrackSdkWrapper - .initializeSdk(args) - .mapSuccess { - Unit - } + SdkMethod.addGeotag -> { + withArgs>(call) { args -> + deserializeGeotagData(args).flatMapSuccess { + HyperTrackSdkWrapper.addGeotag(args) + } } } + SdkMethod.getDeviceID -> { HyperTrackSdkWrapper.getDeviceId() } - SdkMethod.isTracking -> { - HyperTrackSdkWrapper.isTracking() + + SdkMethod.getErrors -> { + HyperTrackSdkWrapper.getErrors() } - SdkMethod.isAvailable -> { - HyperTrackSdkWrapper.isAvailable() + + SdkMethod.getIsAvailable -> { + HyperTrackSdkWrapper.getIsAvailable() } - SdkMethod.setAvailability -> { - withArgs(call) { args -> - HyperTrackSdkWrapper.setAvailability(args) - } + + SdkMethod.getIsTracking -> { + HyperTrackSdkWrapper.getIsTracking() } + SdkMethod.getLocation -> { HyperTrackSdkWrapper.getLocation() } - SdkMethod.startTracking -> { - HyperTrackSdkWrapper.startTracking() + + SdkMethod.getMetadata -> { + HyperTrackSdkWrapper.getMetadata() } - SdkMethod.stopTracking -> { - HyperTrackSdkWrapper.stopTracking() + + SdkMethod.getName -> { + HyperTrackSdkWrapper.getName() } - SdkMethod.addGeotag -> { - withArgs>(call) { args -> - HyperTrackSdkWrapper.addGeotag(args) + + SdkMethod.locate -> { + // locate is implemented as a EventChannel + Success(NotImplemented) + } + + SdkMethod.setIsAvailable -> { + withArgs(call) { args -> + HyperTrackSdkWrapper.setIsAvailable(args) } } - SdkMethod.setName -> { + + SdkMethod.setIsTracking -> { withArgs(call) { args -> - HyperTrackSdkWrapper.setName(args) + HyperTrackSdkWrapper.setIsTracking(args) } } + SdkMethod.setMetadata -> { withArgs(call) { args -> HyperTrackSdkWrapper.setMetadata(args) } } - SdkMethod.sync -> { - HyperTrackSdkWrapper.sync() + + SdkMethod.setName -> { + withArgs(call) { args -> + HyperTrackSdkWrapper.setName(args) + } } } } - private fun withArgs(call: MethodCall, block: (Map) -> Result): Result { + private fun withArgs( + call: MethodCall, + block: (Map) -> WrapperResult, + ): WrapperResult { return call .arguments>() ?.let { block.invoke(it) } @@ -124,122 +161,110 @@ public class HyperTrackPlugin : FlutterPlugin, MethodCallHandler { } private fun initEventChannels(messenger: BinaryMessenger) { - trackingStateEventChannel = EventChannel(messenger, TRACKING_STATE_EVENT_CHANNEL_NAME) - trackingStateEventChannel?.setStreamHandler(object : StreamHandler { + errorsEventChannel = EventChannel(messenger, ERRORS_EVENT_CHANNEL_NAME) + errorsEventChannel?.setStreamHandler(object : StreamHandler { override fun onListen(arguments: Any?, events: EventSink) { - Result + WrapperResult .tryAsResult { - val sdk = HyperTrackSdkWrapper.sdkInstance - trackingStateListener = - object : TrackingStateObserver.OnTrackingStateChangeListener { - override fun onTrackingStart() { - events.success(serializeIsTracking(true)) - } - - override fun onTrackingStop() { - events.success(serializeIsTracking(false)) - } - - override fun onError(p0: TrackingError) { - // ignored, errors are handled by errorEventChannel - } - } - sdk.addTrackingListener(trackingStateListener) - events.success(serializeIsTracking(sdk.isTracking)) - } - .crashAppIfError() + errorsCancellable = HyperTrack.subscribeToErrors { errors -> + events.success(serializeErrors(errors)) + } + }.crashAppIfError() } override fun onCancel(arguments: Any?) { - HyperTrackSdkWrapper.sdkInstance - .let { sdk -> - sdk.removeTrackingListener(trackingStateListener) - trackingStateListener = null - } + errorsCancellable?.cancel() + errorsCancellable = null } }) - errorEventChannel = EventChannel(messenger, ERROR_EVENT_CHANNEL_NAME) - errorEventChannel?.setStreamHandler(object : StreamHandler { - override fun onListen(arguments: Any?, events: EventSink) { - Result - .tryAsResult { - val sdk = HyperTrackSdkWrapper.sdkInstance - errorChannelTrackingStateListener = - object : TrackingStateObserver.OnTrackingStateChangeListener { - override fun onTrackingStart() { - // ignored, trackingState is handled by trackingStateEventChannel - } + isTrackingEventChannel = EventChannel(messenger, IS_TRACKING_STATE_EVENT_CHANNEL_NAME) + isTrackingEventChannel?.setStreamHandler( + object : StreamHandler { + override fun onListen(arguments: Any?, events: EventSink) { + WrapperResult + .tryAsResult { + isTrackingCancellable = HyperTrack.subscribeToIsTracking { isTracking -> + events.success(serializeIsTracking(isTracking)) + } + }.crashAppIfError() + } - override fun onTrackingStop() { - // ignored, trackingState is handled by trackingStateEventChannel - } + override fun onCancel(arguments: Any?) { + isTrackingCancellable?.cancel() + isTrackingCancellable = null + } + }, + ) - override fun onError(error: TrackingError) { - events.success(HyperTrackSdkWrapper.getErrors(error)) + isAvailableEventChannel = EventChannel(messenger, IS_AVAILABLE_EVENT_CHANNEL_NAME) + isAvailableEventChannel?.setStreamHandler( + object : StreamHandler { + override fun onListen(arguments: Any?, events: EventSink) { + WrapperResult + .tryAsResult { + isAvailableCancellable = + HyperTrack.subscribeToIsAvailable { isAvailable -> + events.success(serializeIsAvailable(isAvailable)) } - } - sdk.addTrackingListener(errorChannelTrackingStateListener) - events.success(HyperTrackSdkWrapper.getInitialErrors()) - } - .crashAppIfError() - } + }.crashAppIfError() + } - override fun onCancel(arguments: Any?) { - HyperTrackSdkWrapper.sdkInstance - .let { sdk -> - sdk.removeTrackingListener(errorChannelTrackingStateListener) - errorChannelTrackingStateListener = null - } - } - }) + override fun onCancel(arguments: Any?) { + isAvailableCancellable?.cancel() + isAvailableCancellable = null + } + }, + ) - availabilityEventChannel = EventChannel(messenger, AVAILABILTY_EVENT_CHANNEL_NAME) - availabilityEventChannel?.setStreamHandler( + locationEventChannel = EventChannel(messenger, LOCATION_EVENT_CHANNEL_NAME) + locationEventChannel?.setStreamHandler( object : StreamHandler { override fun onListen(arguments: Any?, events: EventSink) { - Result.tryAsResult { - val sdk = HyperTrackSdkWrapper.sdkInstance - availabilityListener = - object : - AvailabilityStateObserver.OnAvailabilityStateChangeListener { - override fun onError(p0: AvailabilityError) { - // ignored, errors are handled by errorEventChannel + WrapperResult + .tryAsResult { + locationCancellable = + HyperTrack.subscribeToLocation { locationResult -> + events.success(serializeLocationResult(locationResult)) } + }.crashAppIfError() + } - override fun onAvailable() { - events.success(serializeIsAvailable(true)) - } + override fun onCancel(arguments: Any?) { + locationCancellable?.cancel() + locationCancellable = null + } + }, + ) - override fun onUnavailable() { - events.success(serializeIsAvailable(false)) - } + locateEventChannel = EventChannel(messenger, LOCATE_EVENT_CHANNEL_NAME) + locateEventChannel?.setStreamHandler( + object : StreamHandler { + override fun onListen(arguments: Any?, events: EventSink) { + WrapperResult + .tryAsResult { + locateCancellable?.cancel() + locateCancellable = HyperTrack.locate { locateResult -> + events.success(serializeLocateResult(locateResult)) } - sdk.addAvailabilityListener(availabilityListener) - events.success( - serializeIsAvailable(sdk.availability.equals(Availability.AVAILABLE)) - ) - } - .crashAppIfError() + }.crashAppIfError() } override fun onCancel(arguments: Any?) { - HyperTrackSdkWrapper.sdkInstance - .let { sdk -> - sdk.removeAvailabilityListener(availabilityListener) - availabilityListener = null - } + locateCancellable?.cancel() + locateCancellable = null } - } + }, ) } companion object { - private const val METHOD_CHANNEL_NAME = "sdk.hypertrack.com/methods" - private const val TRACKING_STATE_EVENT_CHANNEL_NAME = "sdk.hypertrack.com/tracking" - private const val ERROR_EVENT_CHANNEL_NAME = "sdk.hypertrack.com/errors" - private const val AVAILABILTY_EVENT_CHANNEL_NAME = "sdk.hypertrack.com/availability" - - internal const val ERROR_CODE_METHOD_CALL = "method_call_error" + private const val PREFIX = "sdk.hypertrack.com" + private const val METHOD_CHANNEL_NAME = "$PREFIX/methods" + private const val ERRORS_EVENT_CHANNEL_NAME = "$PREFIX/errors" + private const val IS_TRACKING_STATE_EVENT_CHANNEL_NAME = "$PREFIX/isTracking" + private const val IS_AVAILABLE_EVENT_CHANNEL_NAME = "$PREFIX/isAvailable" + private const val LOCATION_EVENT_CHANNEL_NAME = "$PREFIX/location" + private const val LOCATE_EVENT_CHANNEL_NAME = "$PREFIX/locate" } } diff --git a/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/GeotagData.kt b/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/GeotagData.kt index 082b301..0069ce9 100644 --- a/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/GeotagData.kt +++ b/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/GeotagData.kt @@ -9,5 +9,5 @@ import android.location.Location */ internal data class GeotagData( val data: Map, - val expectedLocation: Location? + val expectedLocation: Location?, ) diff --git a/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/HyperTrackError.kt b/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/HyperTrackError.kt deleted file mode 100644 index 6c8df3e..0000000 --- a/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/HyperTrackError.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.hypertrack.sdk.flutter.common - -/** - * Check HyperTrack SDK docs for HyperTrackError. - * Enum naming convention is ignored to make datatype sync across platforms easier. - * Using Swift naming convention. - */ -@Suppress("EnumEntryName") -internal enum class HyperTrackError { - gpsSignalLost, - locationMocked, - locationPermissionsDenied, - locationPermissionsInsufficientForBackground, - locationPermissionsNotDetermined, - locationPermissionsReducedAccuracy, - locationPermissionsProvisional, - locationPermissionsRestricted, - locationServicesDisabled, - locationServicesUnavailable, - motionActivityPermissionsNotDetermined, - motionActivityPermissionsDenied, - motionActivityServicesDisabled, - motionActivityServicesUnavailable, - motionActivityPermissionsRestricted, - networkConnectionUnavailable, - invalidPublishableKey, - blockedFromRunning -} diff --git a/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/HyperTrackSdkWrapper.kt b/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/HyperTrackSdkWrapper.kt index cc31dcb..ad32339 100644 --- a/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/HyperTrackSdkWrapper.kt +++ b/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/HyperTrackSdkWrapper.kt @@ -1,19 +1,27 @@ package com.hypertrack.sdk.flutter.common import com.hypertrack.sdk.* -import com.hypertrack.sdk.GeotagResult -import com.hypertrack.sdk.flutter.common.Serialization.deserializeAvailability -import com.hypertrack.sdk.flutter.common.Serialization.deserializeDeviceName +import com.hypertrack.sdk.android.HyperTrack +import com.hypertrack.sdk.android.HyperTrack.metadata +import com.hypertrack.sdk.android.Json +import com.hypertrack.sdk.android.Result import com.hypertrack.sdk.flutter.common.Serialization.deserializeGeotagData +import com.hypertrack.sdk.flutter.common.Serialization.deserializeIsAvailable +import com.hypertrack.sdk.flutter.common.Serialization.deserializeIsTracking +import com.hypertrack.sdk.flutter.common.Serialization.deserializeMetadata +import com.hypertrack.sdk.flutter.common.Serialization.deserializeName import com.hypertrack.sdk.flutter.common.Serialization.serializeDeviceId import com.hypertrack.sdk.flutter.common.Serialization.serializeErrors import com.hypertrack.sdk.flutter.common.Serialization.serializeIsAvailable import com.hypertrack.sdk.flutter.common.Serialization.serializeIsTracking import com.hypertrack.sdk.flutter.common.Serialization.serializeLocationErrorFailure +import com.hypertrack.sdk.flutter.common.Serialization.serializeLocationResult import com.hypertrack.sdk.flutter.common.Serialization.serializeLocationSuccess import com.hypertrack.sdk.flutter.common.Serialization.serializeLocationWithDeviationSuccess -import java.lang.IllegalStateException -import java.lang.RuntimeException +import com.hypertrack.sdk.flutter.common.Serialization.serializeMetadata +import com.hypertrack.sdk.flutter.common.Serialization.serializeName + +typealias Serialized = Map /** * This class stores SDK instance, calls HyperTrack SDK methods and serializes responses. @@ -21,257 +29,115 @@ import java.lang.RuntimeException */ internal object HyperTrackSdkWrapper { - // initialize method is guaranteed to be called (by non-native side) - // prior to any access to the SDK instance - private lateinit var _sdkInstance: HyperTrack - val sdkInstance: HyperTrack - get() = _sdkInstance - - // method is named to align with 'initializeSDK' in iOS - fun initializeSdk( - args: Map - ): Result { - return try { - SdkInitParams.fromMap(args) - .flatMapSuccess { initParams -> - _sdkInstance = HyperTrack.getInstance(initParams.publishableKey) - if (initParams.loggingEnabled) { - HyperTrack.enableDebugLogging() - } - if (initParams.allowMockLocations) { - sdkInstance.allowMockLocations() - } - sdkInstance.backgroundTrackingRequirement( - initParams.requireBackgroundTrackingPermission - ) - Success(sdkInstance) - } - } catch (exception: Exception) { - Failure(Exception("Hypertrack SDK initialization failed.", exception)) - } - } - - fun getDeviceId(): Result> { - return Success(serializeDeviceId(sdkInstance.deviceID)) - } - - fun startTracking(): Result { - sdkInstance.start() - return Success(Unit) - } - - fun stopTracking(): Result { - sdkInstance.stop() - return Success(Unit) - } - - fun sync(): Result { - sdkInstance.syncDeviceSettings() - return Success(Unit) - } - - fun addGeotag(args: Map): Result> { + fun addGeotag(args: Serialized): WrapperResult { return deserializeGeotagData(args) .flatMapSuccess { geotag -> - sdkInstance - .addGeotag(geotag.data, geotag.expectedLocation) - .let { result -> - if(geotag.expectedLocation == null) { - when (result) { - is GeotagResult.SuccessWithDeviation -> { - // not supposed to happen - serializeLocationSuccess(result.deviceLocation) - } - - is GeotagResult.Success -> { - serializeLocationSuccess(result.deviceLocation) - } - - is GeotagResult.Error -> { - serializeLocationErrorFailure(getLocationError(result.reason)) - } - - else -> { - throw IllegalArgumentException() - } - } - } else { - when (result) { - is GeotagResult.SuccessWithDeviation -> { - serializeLocationWithDeviationSuccess(result.deviceLocation, result.deviationDistance.toDouble()) - } - - is GeotagResult.Success -> { - // not supposed to happen - serializeLocationWithDeviationSuccess(result.deviceLocation, 0.0) - } - - is GeotagResult.Error -> { - serializeLocationErrorFailure(getLocationError(result.reason)) + // TODO: return proper error if JSON is wrong + val geotagMetadata = Json.fromMap(geotag.data)!! + val expectedLocation = geotag + .expectedLocation + ?.let { + HyperTrack.Location( + latitude = it.latitude, + longitude = it.longitude, + ) + } + if (expectedLocation != null) { + HyperTrack + .addGeotag(geotagMetadata, expectedLocation) + .let { + when (it) { + is Result.Failure -> { + serializeLocationErrorFailure(it.failure) } - else -> { - throw IllegalArgumentException() + is Result.Success -> { + serializeLocationWithDeviationSuccess(it.success) } } } - } - .let { - Success(it) - } + } else { + HyperTrack + .addGeotag(geotagMetadata) + .let { serializeLocationResult(it) } + }.let { + Success(it) + } } } - fun isTracking(): Result> { - return Success(serializeIsTracking(sdkInstance.isTracking)) + fun getDeviceId(): WrapperResult { + return Success(serializeDeviceId(HyperTrack.deviceID)) } - fun isAvailable(): Result> { - return Success( - serializeIsAvailable(sdkInstance.availability.equals(Availability.AVAILABLE)) - ) - } - - fun setAvailability(args: Map): Result { - return deserializeAvailability(args) - .mapSuccess { isAvailable -> - if (isAvailable) { - sdkInstance.availability = Availability.AVAILABLE - } else { - sdkInstance.availability = Availability.UNAVAILABLE - } - } + fun getErrors(): WrapperResult> { + return Success(serializeErrors(HyperTrack.errors)) } - fun setName(args: Map): Result { - return deserializeDeviceName(args) - .mapSuccess { name -> - sdkInstance.setDeviceName(name) - } + fun getIsAvailable(): WrapperResult { + return Success( + serializeIsAvailable(HyperTrack.isAvailable), + ) } - fun setMetadata(metadata: Map): Result { - return Result.tryAsResult { - sdkInstance.setDeviceMetadata(metadata) - Unit - } + fun getIsTracking(): WrapperResult { + return Success( + serializeIsTracking(HyperTrack.isTracking), + ) } - fun getLocation(): Result> { - return sdkInstance.latestLocation - .let { result -> - if (result.isSuccess) { - serializeLocationSuccess(result.value) - } else { - serializeLocationErrorFailure(getLocationError(result.error)) + fun getLocation(): WrapperResult { + return HyperTrack + .location + .let { + when (it) { + is Result.Failure -> serializeLocationErrorFailure(it.failure) + is Result.Success -> serializeLocationSuccess(it.success) } } .let { Success(it) } } - fun getInitialErrors(): List> { - return serializeErrors(getHyperTrackErrorsFromBlockers()) + fun getMetadata(): WrapperResult { + return Success( + serializeMetadata(HyperTrack.metadata.toMap()), + ) } - fun getErrors(error: TrackingError): List> { - return serializeErrors(getTrackingErrors((error))) + fun getName(): WrapperResult { + return Success( + serializeName(HyperTrack.name), + ) } - private fun getTrackingErrors(error: TrackingError): Set { - return when (error.code) { - TrackingError.INVALID_PUBLISHABLE_KEY_ERROR -> { - HyperTrackError.invalidPublishableKey - } - TrackingError.PERMISSION_DENIED_ERROR -> { - null - } - TrackingError.AUTHORIZATION_ERROR -> { - HyperTrackError.blockedFromRunning - } - TrackingError.GPS_PROVIDER_DISABLED_ERROR -> { - HyperTrackError.locationServicesDisabled - } - TrackingError.UNKNOWN_NETWORK_ERROR -> { - HyperTrackError.blockedFromRunning - } - else -> { - throw RuntimeException("Unknown tracking error") - } - } - .let { hyperTrackError -> - (hyperTrackError?.let { setOf(it) } ?: setOf()) + getHyperTrackErrorsFromBlockers() + fun setIsAvailable(args: Serialized): WrapperResult { + return deserializeIsAvailable(args) + .mapSuccess { isAvailable -> + HyperTrack.isAvailable = isAvailable } } - private fun getLocationError(error: OutageReason): LocationError { - val blockersErrors = getHyperTrackErrorsFromBlockers() - return when (error) { - OutageReason.NO_GPS_SIGNAL -> { - Errors(setOf(HyperTrackError.gpsSignalLost) + blockersErrors) + fun setIsTracking(args: Serialized): WrapperResult { + return deserializeIsTracking(args) + .mapSuccess { isTracking -> + HyperTrack.isTracking = isTracking } - OutageReason.MISSING_LOCATION_PERMISSION -> { - Errors(setOf(HyperTrackError.locationPermissionsDenied) + blockersErrors) - } - OutageReason.LOCATION_SERVICE_DISABLED -> { - Errors(setOf(HyperTrackError.locationServicesDisabled) + blockersErrors) - } - OutageReason.MISSING_ACTIVITY_PERMISSION -> { - Errors(setOf(HyperTrackError.motionActivityPermissionsDenied) + blockersErrors) - } - OutageReason.NOT_TRACKING -> { - NotRunning - } - OutageReason.START_HAS_NOT_FINISHED -> { - Starting - } - OutageReason.RESTART_REQUIRED -> { - throw IllegalStateException("RESTART_REQUIRED must not be returned") - } - } } - private fun getLocationError(error: GeotagResult.Error.Reason): LocationError { - val blockersErrors = getHyperTrackErrorsFromBlockers() - return when (error) { - GeotagResult.Error.Reason.NO_GPS_SIGNAL -> { - Errors(setOf(HyperTrackError.gpsSignalLost) + blockersErrors) - } - GeotagResult.Error.Reason.MISSING_LOCATION_PERMISSION -> { - Errors(setOf(HyperTrackError.locationPermissionsDenied) + blockersErrors) - } - GeotagResult.Error.Reason.LOCATION_SERVICE_DISABLED -> { - Errors(setOf(HyperTrackError.locationServicesDisabled) + blockersErrors) - } - GeotagResult.Error.Reason.MISSING_ACTIVITY_PERMISSION -> { - Errors(setOf(HyperTrackError.motionActivityPermissionsDenied) + blockersErrors) - } - GeotagResult.Error.Reason.NOT_TRACKING -> { - NotRunning - } - GeotagResult.Error.Reason.START_HAS_NOT_FINISHED -> { - Starting + fun setMetadata(args: Serialized): WrapperResult { + return deserializeMetadata(args) + .flatMapSuccess { metadata -> + WrapperResult.tryAsResult { + // TODO: return proper error if JSON is wrong + HyperTrack.metadata = Json.fromMap(metadata)!! + } } - } } - private fun getHyperTrackErrorsFromBlockers(): Set { - return HyperTrack.getBlockers() - .map { - when (it) { - Blocker.LOCATION_PERMISSION_DENIED -> { - HyperTrackError.locationPermissionsDenied - } - Blocker.LOCATION_SERVICE_DISABLED -> { - HyperTrackError.locationServicesDisabled - } - Blocker.ACTIVITY_PERMISSION_DENIED -> { - HyperTrackError.motionActivityPermissionsDenied - } - Blocker.BACKGROUND_LOCATION_DENIED -> { - HyperTrackError.locationPermissionsInsufficientForBackground - } - } + fun setName(args: Serialized): WrapperResult { + return deserializeName(args) + .mapSuccess { name -> + HyperTrack.name = name } - .toSet() } } diff --git a/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/LocationError.kt b/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/LocationError.kt deleted file mode 100644 index 422b3b8..0000000 --- a/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/LocationError.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.hypertrack.sdk.flutter.common - -/** - * Check HyperTrack SDK docs for LocationError - */ -internal sealed class LocationError -internal object NotRunning : LocationError() -internal object Starting : LocationError() -internal data class Errors(val errors: Set) : LocationError() diff --git a/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/SdkInitParams.kt b/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/SdkInitParams.kt deleted file mode 100644 index d81bf09..0000000 --- a/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/SdkInitParams.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.hypertrack.sdk.flutter.common - -import com.hypertrack.sdk.flutter.common.Serialization.parse - -/** - * SDK config params - */ -internal data class SdkInitParams( - val publishableKey: String, - val requireBackgroundTrackingPermission: Boolean, - val loggingEnabled: Boolean, - val allowMockLocations: Boolean -) { - - companion object { - fun fromMap(map: Map): Result { - return parse(map) { - SdkInitParams( - publishableKey = it - .get(KEY_PUBLISHABLE_KEY) - .getOrThrow(), - requireBackgroundTrackingPermission = it - .get(KEY_REQUIRE_BACKGROUND_TRACKING_PERMISSION) - .getOrThrow(), - loggingEnabled = it - .get(KEY_LOGGING_ENABLED) - .getOrThrow(), - allowMockLocations = it - .get(KEY_ALLOW_MOCK_LOCATIONS) - .getOrThrow() - ) - } - } - - private const val KEY_PUBLISHABLE_KEY = - "publishableKey" - private const val KEY_REQUIRE_BACKGROUND_TRACKING_PERMISSION = - "requireBackgroundTrackingPermission" - private const val KEY_LOGGING_ENABLED = - "loggingEnabled" - private const val KEY_ALLOW_MOCK_LOCATIONS = - "allowMockLocations" - } -} diff --git a/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/SdkMethod.kt b/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/SdkMethod.kt index 673d6c8..cff122e 100644 --- a/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/SdkMethod.kt +++ b/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/SdkMethod.kt @@ -2,20 +2,22 @@ package com.hypertrack.sdk.flutter.common /** * The list of available methods in the SDK API. + * It is used to match method calls in some wrappers (like Flutter) * Enum naming convention is ignored to make datatype sync across platforms easier. * Using Swift naming convention. */ internal enum class SdkMethod { - initialize, + addGeotag, getDeviceID, + getErrors, + getIsAvailable, + getIsTracking, getLocation, - startTracking, - stopTracking, - setAvailability, - setName, + getMetadata, + getName, + locate, + setIsAvailable, + setIsTracking, setMetadata, - isTracking, - isAvailable, - addGeotag, - sync + setName, } diff --git a/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/Serialization.kt b/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/Serialization.kt index 1481081..f1a1460 100644 --- a/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/Serialization.kt +++ b/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/Serialization.kt @@ -1,6 +1,8 @@ package com.hypertrack.sdk.flutter.common import android.location.Location +import com.hypertrack.sdk.android.HyperTrack +import com.hypertrack.sdk.android.Result /** * Platform-independent serialization code that converts HyperTrack data types @@ -8,93 +10,249 @@ import android.location.Location */ internal object Serialization { - fun serializeErrors(errors: Set): List> { - return errors.map { - serializeHypertrackError(it) + fun deserializeIsAvailable(isAvailable: Map): WrapperResult { + return parse(isAvailable) { + it.assertValue(key = KEY_TYPE, value = TYPE_IS_AVAILABLE) + it + .get(KEY_VALUE) + .getOrThrow() } } - fun serializeLocationSuccess(location: Location): Map { - return serializeSuccess(serializeLocation(location)) + fun deserializeIsTracking(isTracking: Map): WrapperResult { + return parse(isTracking) { + it.assertValue(key = KEY_TYPE, value = TYPE_IS_TRACKING) + it + .get(KEY_VALUE) + .getOrThrow() + } } - fun serializeLocationWithDeviationSuccess( - location: Location, - deviation: Double - ): Map { - return serializeSuccess(serializeLocationWithDeviation( - location, - deviation - )) + fun deserializeMetadata(metadata: Map): WrapperResult> { + return parse(metadata) { + it.assertValue(key = KEY_TYPE, value = TYPE_METADATA) + it + .get>(KEY_VALUE) + .getOrThrow() + } } - fun serializeLocationErrorFailure(locationError: LocationError): Map { - return serializeFailure(serializeLocationError(locationError)) + fun deserializeName(name: Map): WrapperResult { + return parse(name) { + it.assertValue(key = KEY_TYPE, value = TYPE_NAME) + it + .get(KEY_VALUE) + .getOrThrow() + } } - fun serializeIsTracking(isTracking: Boolean): Map { + fun deserializeGeotagData(map: Map): WrapperResult { + return parse(map) { + val data = it + .get>(KEY_GEOTAG_DATA) + .getOrThrow() + val locationData = it + .getOptional>(KEY_GEOTAG_EXPECTED_LOCATION) + .getOrThrow() + val location = locationData?.let { deserializeLocation(it).getOrThrow() } + GeotagData(data, location) + } + } + + fun serializeDeviceId(deviceId: String): Map { return mapOf( - KEY_TYPE to TYPE_IS_TRACKING, - KEY_VALUE to isTracking + KEY_TYPE to TYPE_DEVICE_ID, + KEY_VALUE to deviceId, ) } + fun serializeError(error: HyperTrack.Error): Map { + return mapOf( + KEY_TYPE to TYPE_ERROR, + KEY_VALUE to when (error) { + HyperTrack.Error.BlockedFromRunning -> "blockedFromRunning" + HyperTrack.Error.InvalidPublishableKey -> "invalidPublishableKey" + HyperTrack.Error.Location.Mocked -> "location.mocked" + HyperTrack.Error.Location.ServicesDisabled -> "location.servicesDisabled" + HyperTrack.Error.Location.ServicesUnavailable -> "location.servicesUnavailable" + HyperTrack.Error.Location.SignalLost -> "location.signalLost" + HyperTrack.Error.NoExemptionFromBackgroundStartRestrictions -> "noExemptionFromBackgroundStartRestrictions" + HyperTrack.Error.Permissions.Location.Denied -> "permissions.location.denied" + HyperTrack.Error.Permissions.Location.InsufficientForBackground -> "permissions.location.insufficientForBackground" + HyperTrack.Error.Permissions.Location.ReducedAccuracy -> "permissions.location.reducedAccuracy" + HyperTrack.Error.Permissions.Notifications.Denied -> "permissions.notifications.denied" + }, + ) + } + + fun serializeErrors(errors: Set): List> { + return errors.map { + serializeError(it) + } + } + fun serializeIsAvailable(isAvailable: Boolean): Map { return mapOf( - KEY_TYPE to TYPE_AVAILABILITY, - KEY_VALUE to isAvailable + KEY_TYPE to TYPE_IS_AVAILABLE, + KEY_VALUE to isAvailable, ) } - fun serializeHypertrackError(error: HyperTrackError): Map { + fun serializeIsTracking(isTracking: Boolean): Map { return mapOf( - KEY_TYPE to TYPE_HYPERTRACK_ERROR, - KEY_VALUE to error.name + KEY_TYPE to TYPE_IS_TRACKING, + KEY_VALUE to isTracking, ) } - fun serializeDeviceId(deviceId: String): Map { + fun serializeMetadata(metadata: Map): Map { return mapOf( - KEY_TYPE to TYPE_DEVICE_ID, - KEY_VALUE to deviceId + KEY_TYPE to TYPE_METADATA, + KEY_VALUE to metadata, ) } - fun deserializeDeviceName(name: Map): Result { - return parse(name) { - it.assertValue(key = KEY_TYPE, value = TYPE_DEVICE_NAME) - it - .get(KEY_VALUE) - .getOrThrow() + fun serializeName(name: String): Map { + return mapOf( + KEY_TYPE to TYPE_NAME, + KEY_VALUE to name, + ) + } + + fun serializeLocateResult( + locationResult: Result>, + ): Map { + return when (locationResult) { + is Result.Failure -> { + serializeFailure(serializeErrors(locationResult.failure)) + } + + is Result.Success -> { + serializeLocationSuccess(locationResult.success) + } } } - fun deserializeAvailability(isAvailable: Map): Result { - return parse(isAvailable) { - it.assertValue(key = KEY_TYPE, value = TYPE_AVAILABILITY) - it - .get(KEY_VALUE) - .getOrThrow() + fun serializeLocationResult( + locationResult: Result, + ): Map { + return when (locationResult) { + is Result.Failure -> { + serializeLocationErrorFailure(locationResult.failure) + } + + is Result.Success -> { + serializeLocationSuccess(locationResult.success) + } } } - fun deserializeGeotagData(map: Map): Result { + fun serializeLocationErrorFailure(locationError: HyperTrack.LocationError): Map { + return serializeFailure(serializeLocationError(locationError)) + } + + fun serializeLocationSuccess(location: HyperTrack.Location): Map { + return serializeSuccess(serializeLocation(location)) + } + + fun serializeLocationWithDeviationSuccess( + locationWithDeviation: HyperTrack.LocationWithDeviation, + ): Map { + return serializeSuccess( + serializeLocationWithDeviation( + locationWithDeviation, + ), + ) + } + + private fun serializeLocationWithDeviation( + locationWithDeviation: HyperTrack.LocationWithDeviation, + ): Map { + return mapOf( + KEY_TYPE to TYPE_LOCATION_WITH_DEVIATION, + KEY_VALUE to mapOf( + KEY_LOCATION to serializeLocation(locationWithDeviation.location), + KEY_DEVIATION to locationWithDeviation.deviation, + ), + ) + } + + private fun deserializeLocation(map: Map): WrapperResult { return parse(map) { - val data = it - .get>(KEY_GEOTAG_DATA) - .getOrThrow() - val locationData = it - .getOptional>(KEY_GEOTAG_EXPECTED_LOCATION) + it.assertValue(key = KEY_TYPE, value = TYPE_LOCATION) + val value = it + .get>(KEY_VALUE) .getOrThrow() - val location = locationData?.let { deserializeLocation(it).getOrThrow() } - GeotagData(data, location) + parse(value) { parser -> + val latitude = parser + .get(KEY_LATITUDE) + .getOrThrow() + val longitude = parser + .get(KEY_LONGITUDE) + .getOrThrow() + Location("api").also { + it.latitude = latitude + it.longitude = longitude + } + }.getOrThrow() + } + } + + private fun serializeFailure(failure: List>): Map { + return mapOf( + KEY_TYPE to TYPE_RESULT_FAILURE, + KEY_VALUE to failure, + ) + } + + private fun serializeFailure(failure: Map): Map { + return mapOf( + KEY_TYPE to TYPE_RESULT_FAILURE, + KEY_VALUE to failure, + ) + } + + private fun serializeSuccess(success: Map): Map { + return mapOf( + KEY_TYPE to TYPE_RESULT_SUCCESS, + KEY_VALUE to success, + ) + } + + fun serializeLocation(location: HyperTrack.Location): Map { + return mapOf( + KEY_TYPE to TYPE_LOCATION, + KEY_VALUE to mapOf( + KEY_LATITUDE to location.latitude, + KEY_LONGITUDE to location.longitude, + ), + ) + } + + private fun serializeLocationError(locationError: HyperTrack.LocationError): Map { + return when (locationError) { + HyperTrack.LocationError.NotRunning -> { + mapOf(KEY_TYPE to TYPE_LOCATION_ERROR_NOT_RUNNING) + } + + HyperTrack.LocationError.Starting -> { + mapOf(KEY_TYPE to TYPE_LOCATION_ERROR_STARTING) + } + + is HyperTrack.LocationError.Errors -> { + mapOf( + KEY_TYPE to TYPE_LOCATION_ERROR_ERRORS, + KEY_VALUE to locationError.errors + .map { serializeError(it) }, + ) + } } } fun parse( source: Map, - parseFunction: (Parser) -> T - ): Result { + parseFunction: (Parser) -> T, + ): WrapperResult { val parser = Parser(source) return try { if (parser.exceptions.isEmpty()) { @@ -108,20 +266,20 @@ internal object Serialization { ParsingExceptions(source, parser.exceptions + e) } else { e - } + }, ) } } internal class Parser( - private val source: Map + private val source: Map, ) { private val _exceptions = mutableListOf() val exceptions: List = _exceptions inline fun get( - key: String - ): Result { + key: String, + ): WrapperResult { return try { Success(source[key]!! as T) } catch (e: Exception) { @@ -129,14 +287,14 @@ internal object Serialization { ParsingException(key, e) .also { _exceptions.add(it) - } + }, ) } } inline fun getOptional( - key: String - ): Result { + key: String, + ): WrapperResult { return try { Success(source[key] as T?) } catch (e: Exception) { @@ -144,14 +302,14 @@ internal object Serialization { ParsingException(key, e) .also { _exceptions.add(it) - } + }, ) } } inline fun assertValue( key: String, - value: Any + value: Any, ) { if (source[key] != value) { _exceptions.add(Exception("Assertion failed: $key != $value")) @@ -161,118 +319,43 @@ internal object Serialization { internal data class ParsingExceptions( val source: Any, - val exceptions: List + val exceptions: List, ) : Throwable( exceptions.joinToString("\n") .let { "Invalid input:\n\n${source}\n\n$it" - } + }, ) internal class ParsingException( key: String, - exception: Exception + exception: Exception, ) : Exception("Invalid value for '$key': $exception", exception) - private fun deserializeLocation(map: Map): Result { - return parse(map) { - it.assertValue(key = KEY_TYPE, value = TYPE_LOCATION) - val value = it - .get>(KEY_VALUE) - .getOrThrow() - parse(value) { parser -> - val latitude = parser - .get(KEY_LATITUDE) - .getOrThrow() - val longitude = parser - .get(KEY_LONGITUDE) - .getOrThrow() - Location("api").also { - it.latitude = latitude - it.longitude = longitude - } - }.getOrThrow() - } - } - - private fun serializeLocationWithDeviation( - location: Location, - deviation: Double - ): Map { - return mapOf( - KEY_TYPE to TYPE_LOCATION, - KEY_VALUE to mapOf( - KEY_LOCATION to serializeLocation(location), - KEY_DEVIATION to deviation - ) - ) - } - - private fun serializeFailure(failure: Map): Map { - return mapOf( - KEY_TYPE to TYPE_RESULT_FAILURE, - KEY_VALUE to failure - ) - } - - private fun serializeSuccess(success: Map): Map { - return mapOf( - KEY_TYPE to TYPE_RESULT_SUCCESS, - KEY_VALUE to success - ) - } - - private fun serializeLocation(location: Location): Map { - return mapOf( - KEY_TYPE to TYPE_LOCATION, - KEY_VALUE to mapOf( - KEY_LATITUDE to location.latitude, - KEY_LONGITUDE to location.longitude - ) - ) - } - - private fun serializeLocationError(locationError: LocationError): Map { - return when (locationError) { - NotRunning -> { - mapOf(KEY_TYPE to TYPE_LOCATION_ERROR_NOT_RUNNING) - } - Starting -> { - mapOf(KEY_TYPE to TYPE_LOCATION_ERROR_STARTING) - } - is Errors -> { - mapOf( - KEY_TYPE to TYPE_LOCATION_ERROR_ERRORS, - KEY_VALUE to locationError.errors - .map { serializeHypertrackError(it) } - ) - } - } - } - private const val KEY_TYPE = "type" private const val KEY_VALUE = "value" - private const val TYPE_RESULT_SUCCESS = "success" private const val TYPE_RESULT_FAILURE = "failure" + private const val TYPE_RESULT_SUCCESS = "success" - private const val TYPE_LOCATION = "location" - private const val TYPE_LOCATION_WITH_DEVIATION = "locationWithDeviation" - private const val TYPE_AVAILABILITY = "isAvailable" - private const val TYPE_DEVICE_NAME = "deviceName" private const val TYPE_DEVICE_ID = "deviceID" - private const val TYPE_HYPERTRACK_ERROR = "hyperTrackError" + private const val TYPE_ERROR = "error" + private const val TYPE_IS_AVAILABLE = "isAvailable" private const val TYPE_IS_TRACKING = "isTracking" + private const val TYPE_METADATA = "metadata" + private const val TYPE_NAME = "name" + private const val TYPE_LOCATION = "location" + private const val TYPE_LOCATION_WITH_DEVIATION = "locationWithDeviation" + private const val TYPE_LOCATION_ERROR_ERRORS = "errors" private const val TYPE_LOCATION_ERROR_NOT_RUNNING = "notRunning" private const val TYPE_LOCATION_ERROR_STARTING = "starting" - private const val TYPE_LOCATION_ERROR_ERRORS = "errors" private const val KEY_LATITUDE = "latitude" private const val KEY_LONGITUDE = "longitude" + const val KEY_DEVIATION = "deviation" const val KEY_GEOTAG_DATA = "data" const val KEY_GEOTAG_EXPECTED_LOCATION = "expectedLocation" - const val KEY_DEVIATION = "deviation" const val KEY_LOCATION = "location" } diff --git a/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/Result.kt b/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/WrapperResult.kt similarity index 78% rename from android/src/main/kotlin/com/hypertrack/sdk/flutter/common/Result.kt rename to android/src/main/kotlin/com/hypertrack/sdk/flutter/common/WrapperResult.kt index 77b9077..1918b38 100644 --- a/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/Result.kt +++ b/android/src/main/kotlin/com/hypertrack/sdk/flutter/common/WrapperResult.kt @@ -1,24 +1,26 @@ package com.hypertrack.sdk.flutter.common -internal sealed class Result { +internal sealed class WrapperResult { fun flatMapSuccess( - onSuccess: (SuccessType) -> Result - ): Result { + onSuccess: (SuccessType) -> WrapperResult, + ): WrapperResult { return when (this) { is Success -> { onSuccess.invoke(this.success) } + is Failure -> { Failure(this.failure) } } } - fun mapSuccess(onSuccess: (SuccessType) -> MappedSuccess): Result { + fun mapSuccess(onSuccess: (SuccessType) -> MappedSuccess): WrapperResult { return when (this) { is Success -> { Success(onSuccess.invoke(this.success)) } + is Failure -> { Failure(this.failure) } @@ -30,13 +32,13 @@ internal sealed class Result { is Success -> this.success is Failure -> throw Exception( "Result unwrapping failed: ${this.failure}", - this.failure + this.failure, ) } } companion object { - fun tryAsResult(block: () -> SuccessType): Result { + fun tryAsResult(block: () -> SuccessType): WrapperResult { return try { Success(block.invoke()) } catch (e: Exception) { @@ -46,5 +48,5 @@ internal sealed class Result { } } -internal data class Success(val success: SuccessType) : Result() -internal data class Failure(val failure: Throwable) : Result() +internal data class Success(val success: SuccessType) : WrapperResult() +internal data class Failure(val failure: Throwable) : WrapperResult() diff --git a/docs/__404error.html b/docs/__404error.html index cc773fe..ee40566 100644 --- a/docs/__404error.html +++ b/docs/__404error.html @@ -95,7 +95,7 @@
hypertrack_plugin hypertrack_plugin - 1.1.3 + 2.0.0 diff --git a/docs/data_types_hypertrack_error/HyperTrackError.html b/docs/data_types_hypertrack_error/HyperTrackError.html index 1594ea4..5bee28f 100644 --- a/docs/data_types_hypertrack_error/HyperTrackError.html +++ b/docs/data_types_hypertrack_error/HyperTrackError.html @@ -101,218 +101,170 @@

Constructors

Values

-
- gpsSignalLost - → const HyperTrackError - - -
-
- - - -
- -
- locationMocked - → const HyperTrackError - - -
-
- - - -
- -
- locationPermissionsDenied - → const HyperTrackError - - -
-
- - - -
- -
- locationPermissionsInsufficientForBackground - → const HyperTrackError - - -
-
- - - -
- -
- locationPermissionsNotDetermined +
+ blockedFromRunning → const HyperTrackError
- +

The SDK was remotely blocked from running.

-
- locationPermissionsReducedAccuracy +
+ invalidPublishableKey → const HyperTrackError
- +

The publishable key is invalid.

-
- locationPermissionsProvisional +
+ locationMocked → const HyperTrackError
- +

The user enabled mock location app while mocking locations is prohibited.

-
- locationPermissionsRestricted +
+ locationServicesDisabled → const HyperTrackError
- +

The user disabled location services systemwide.

-
- locationServicesDisabled +
+ locationServicesUnavailable → const HyperTrackError
- +

Android only The device doesn't have location services.

-
- locationServicesUnavailable +
+ locationSignalLost → const HyperTrackError
- +

GPS satellites are not in view.

-
- motionActivityPermissionsNotDetermined +
+ noExemptionFromBackgroundStartRestrictions → const HyperTrackError
- +

Android only The SDK wasn't able to start tracking because of the limitations imposed by the OS.

-
- motionActivityPermissionsDenied +
+ permissionsLocationDenied → const HyperTrackError
- +

The user denied location permissions.

-
- motionActivityServicesDisabled +
+ permissionsLocationInsufficientForBackground → const HyperTrackError
- +

Can’t start tracking in background with When In Use location permissions.

-
- motionActivityPermissionsRestricted +
+ permissionsLocationNotDetermined → const HyperTrackError
- +

iOS only The user has not chosen whether the app can use location services.

-
- motionActivityServicesUnavailable +
+ permissionsLocationProvisional → const HyperTrackError
- +

iOS only The app is in Provisional Always authorization state, which stops sending locations when app is in background.

-
- networkConnectionUnavailable +
+ permissionsLocationReducedAccuracy → const HyperTrackError
- +

The user didn't grant precise location permissions or downgraded permissions to imprecise.

-
- invalidPublishableKey +
+ permissionsLocationRestricted → const HyperTrackError
- +

iOS only The app is not authorized to use location services.

-
- blockedFromRunning +
+ permissionsNotificationsDenied → const HyperTrackError
- +

Android only The user denied notification permissions needed to display a persistent notification

@@ -394,7 +346,7 @@

Constants

- [gpsSignalLost, locationMocked, locationPermissionsDenied, locationPermissionsInsufficientForBackground, locationPermissionsNotDetermined, locationPermissionsReducedAccuracy, locationPermissionsProvis… + [blockedFromRunning, invalidPublishableKey, locationMocked, locationServicesDisabled, locationServicesUnavailable, locationSignalLost, noExemptionFromBackgroundStartRestrictions, permissionsLocationDe…
@@ -439,24 +391,20 @@
hypertrack_error library
  • HyperTrackError
  • Values
  • -
  • gpsSignalLost
  • +
  • blockedFromRunning
  • +
  • invalidPublishableKey
  • locationMocked
  • -
  • locationPermissionsDenied
  • -
  • locationPermissionsInsufficientForBackground
  • -
  • locationPermissionsNotDetermined
  • -
  • locationPermissionsReducedAccuracy
  • -
  • locationPermissionsProvisional
  • -
  • locationPermissionsRestricted
  • locationServicesDisabled
  • locationServicesUnavailable
  • -
  • motionActivityPermissionsNotDetermined
  • -
  • motionActivityPermissionsDenied
  • -
  • motionActivityServicesDisabled
  • -
  • motionActivityPermissionsRestricted
  • -
  • motionActivityServicesUnavailable
  • -
  • networkConnectionUnavailable
  • -
  • invalidPublishableKey
  • -
  • blockedFromRunning
  • +
  • locationSignalLost
  • +
  • noExemptionFromBackgroundStartRestrictions
  • +
  • permissionsLocationDenied
  • +
  • permissionsLocationInsufficientForBackground
  • +
  • permissionsLocationNotDetermined
  • +
  • permissionsLocationProvisional
  • +
  • permissionsLocationReducedAccuracy
  • +
  • permissionsLocationRestricted
  • +
  • permissionsNotificationsDenied
  • Properties @@ -482,7 +430,7 @@
    hypertrack_error library
  • @@ -131,7 +131,7 @@
    hypertrack library