Coder Social home page Coder Social logo

kvs-coder / health_kit_reporter Goto Github PK

View Code? Open in Web Editor NEW
34.0 3.0 30.0 321 KB

A Flutter wrapper for the HealthKitReporter library

Home Page: https://pub.dev/packages/health_kit_reporter

License: MIT License

Ruby 0.95% Swift 27.26% Objective-C 0.28% Dart 71.51%
dart flutter healthkit ios swift health cocoapods apple-health apple

health_kit_reporter's Introduction

health_kit_reporter

Features

A Flutter wrapper for HealthKitReporter

  • iOS only usage, since AppleHealth is not available on Android devices.

  • The library supports reading, writing, observing values from HealthKit repository.

  • All methods from HealthKitReporter original library are wrapped in Method and Event channels provided by FlutterPlugin

Getting Started

  • Go inside pubspec.yaml file
  • Add this to your package's pubspec.yaml file:
dependencies:
     health_kit_reporter: ^2.1.0
  • Get dependencies
flutter pub get

How to use

Preparation

At first in your app's entitlements select HealthKit and in your app's info.plist file add permissions:

<key>NSHealthShareUsageDescription</key>
<string>WHY_YOU_NEED_TO_SHARE_DATA</string>
<key>NSHealthUpdateUsageDescription</key>
<string>WHY_YOU_NEED_TO_USE_DATA</string>

If you plan to use WorkoutRoute Series please provide additionally CoreLocation permissions:

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>WHY_YOU_NEED_TO_ALWAYS_SHARE_LOCATION</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>WHY_YOU_NEED_TO_SHARE_LOCATION</string>

Common usage

You simply call a HealthKitReporter methods surrounding by try catch blocks.

Warning: If Apple Health is not supported by the device (i.e. iPad) the error result will occur.

The reporter supports following operations with HealthKit:

  • accessing to permissions
  • reading data
  • writing data
  • observing data changes

If you want to read, write data or observe data changes, you always need to be sure that the data types are authorized to be read/written/observed. In that case call authorization method and await for the result telling about the presentation of the authorization window. Notice that Apple Health Kit will show this window only once during the whole time app is installed on the device, in this case if some types were denied to be read or written, user should manually allow this in Apple Health App.

Requesting permissions

As was mentioned above, you need to provide HealthKit entitlements and extend the info.plist file of your App with HealthKit permissions. (see Preparation)

Call the method: requestAuthorization

For this method you need to specify the strings identifiers of types you want to get access.

In the example, we want to read data for all QuantityTypes and write data for QuantityType.stepCount:

Future<void> requestAuthorization() async {
  try {
    final readTypes = QuantityType.values.map((e) => e.identifier).toList();
    final writeTypes = <String>[
      QuantityType.stepCount.identifier,
    ];
    final isRequested =
        await HealthKitReporter.requestAuthorization(readTypes, writeTypes);
    if (isRequested) {
      // read data/write data/observe data
    }
  } catch (e) {
    print(e);
  }
}

Warning: Please keep in mind, Apple Health Kit does not let anyone to know if reading permissions were provided.

User can decline some of the reading permissions, but the result of the function will still be true. See Authorization status

Reading Data

After authorization, you can try to start reading data.

Future<void> read(bool isRequested) async {
  if (isRequested) {
    final preferredUnits =
        await HealthKitReporter.preferredUnits([QuantityType.stepCount]);
    for (final preferredUnit in preferredUnits) {
      print('preferredUnit: ${preferredUnit.identifier}');
      final type = QuantityTypeFactory.from(preferredUnit.identifier);
      final quantities = await HealthKitReporter.quantityQuery(
        type,
        preferredUnit.unit,
        _predicate,
      );
      print('quantity: ${quantities.map((e) => e.map).toList()}');
      final statistics = await HealthKitReporter.statisticsQuery(
        type,
        preferredUnit.unit,
        _predicate,
      );
      print('statistics: ${statistics.map}');
    }
    final characteristics = await HealthKitReporter.characteristicsQuery();
    print('characteristics: ${characteristics.map}');
    final categories = await HealthKitReporter.categoryQuery(
      CategoryType.sleepAnalysis,
      _predicate,
    );
    print('categories: ${categories.map((e) => e.map).toList()}');
    final samples = await HealthKitReporter.sampleQuery(
      QuantityType.stepCount.identifier,
      _predicate,
    );
    print('samples: ${samples.map((e) => e.map).toList()}');
    final sources = await HealthKitReporter.sourceQuery(
      QuantityType.stepCount.identifier,
      _predicate,
    );
    print('sources: ${sources.map((e) => e.map).toList()}');
    final correlations = await HealthKitReporter.correlationQuery(
      CorrelationType.bloodPressure.identifier,
      _predicate,
    );
    print('correlations: ${correlations.map((e) => e.map).toList()}');
  } else {
    print('error isRequested: $isRequested');
  }
}

In the example above, there is a call of preferredUnits function. You can provide identifiers to get preferred units for them and eventually receive properly calculated values from queries. The units will be chosen automatically based on you current localization. This is only required for QuantityTypes. If you will try to provide invalid unit for a type, you will get an error.

The usage of sampleQuery for quantity types will return nearly the same result as quantityQuery, but the units for the values will be used according to SI, while quantityQuery together with preferredUnits will handle values units according to thee current localization.

Writing Data

Before writing data, you may need to check if writing is allowed by calling isAuthorizedToWrite.

If it is ok to write, you need to create a Sample object and call a save method.

final _device = Device(
    'FlutterTracker',
    'kvs',
    'T-800',
    '3',
    '3.0',
    '1.1.1',
    'kvs.sample.app',
    '444-888-555',
  );
final _source = Source(
    'myApp',
    'com.kvs.health_kit_reporter_example',
  );
final _operatingSystem = OperatingSystem(
    1,
    2,
    3,
  );

SourceRevision get _sourceRevision => SourceRevision(
    _source,
   '5',
   'fit',
   '4',
   _operatingSystem,
  );

void saveSteps() async {
  try {
    final canWrite = await HealthKitReporter.isAuthorizedToWrite(
        QuantityType.stepCount.identifier);
    if (canWrite) {
      final now = DateTime.now();
      final minuteAgo = now.add(Duration(minutes: -1));
      final harmonized = QuantityHarmonized(100, 'count', null);
      final steps = Quantity(
          'testStepsUUID',
          QuantityType.stepCount.identifier,
          minuteAgo.millisecondsSinceEpoch,
          now.millisecondsSinceEpoch,
          _device,
          _sourceRevision,
          harmonized);
      print('try to save: ${steps.map}');
      final saved = await HealthKitReporter.save(steps);
      print('stepsSaved: $saved');
    } else {
      print('error canWrite steps: $canWrite');
    }
  } catch (e) {
    print(e);
  }
}

Recommendation: As well as for reading, here will better as well to call preferredUnits first, to know what unit is valid for a type. Please see HKUnit.init

Warning: PLease be sure to provide valid values for the appropriate types. For example, HealthKit will not allow to save Quantity value for the QuantityType.stepCount if the value is 0

Observing Data

If you want to know, that something was changed in HealthKit, you can observe the repository.

Try simple observerQuery to get notifications if something is changed.

This call is a subscription for EventChannel of the plugin, so don't forget to cancel it as soon as you don't need it anymore.

 Future<void> observerQuery() async {
  final identifier = QuantityType.stepCount.identifier;
  final sub = HealthKitReporter.observerQuery(
    [identifier],
    _predicate,
    onUpdate: (identifier) async {
      print('Updates for observerQuerySub');
      print(identifier);
    },
  );
  print('observerQuerySub: $sub');
  final isSet = await HealthKitReporter.enableBackgroundDelivery(
    identifier,
    UpdateFrequency.immediate,
  );
  print('enableBackgroundDelivery: $isSet');
}

According to Observing Query and Background Delivery you might create an App which will be called every time by HealthKit, even if the app is in background, to notify, that some data was changed in HealthKit depending on frequency. But keep in mind that sometimes the desired frequency you set cannot be fulfilled by HealthKit.

To receive notifications when the app is killed by the system or in background:

  • provide an additional capability Background Mode and select Background fetch
  • with calling observerQuery, you need to call enableBackgroundDelivery function as well

As a recommendation set up the subscription inside initState or build methods of your widget or as more preferred in main function of your app.

If you want to stop observation, you need to:

  • remove the subscription for observerQuery
  • call disableBackgroundDelivery or disableAllBackgroundDelivery

Requirements

The library supports minimum iOS 9. Some features like HeartbeatSeries are available only starting with iOS 13.0 and like Electrocardiogramm starting with iOS 14.0.

License

Under MIT License

Sponsorhip

If you think that my repo helped you to solve the issues you struggle with, please don't be shy and sponsor :-)

health_kit_reporter's People

Contributors

kvs-coder avatar nohli avatar opsb avatar sambergeron avatar shilangyu avatar smocken78 avatar victorkachalovthalia avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

health_kit_reporter's Issues

startWatchApp not working

Describe the bug
Invoking startWatchApp is currently not working

To Reproduce
Try to start WatchApp

Add any other context about the problem here.
I added a possible fix at:
#27

method data not found when predicate period include minutes and seconds

Describe the bug
Method HealthKitReporter.workoutRouteQuery(periodo) data not found when predicate period include minutes and seconds

To Reproduce
Steps to reproduce the behavior:
execute query method with parameters

final periodo =
Predicate(DateTime(2023, 6, 16, 17, 23), DateTime(2023, 6, 16, 17, 33));

Data if exists

flutter: 2023-06-16 17:23:39.000
flutter: 2023-06-16 17:32:14.000

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
query Workout

image

Desktop (please complete the following information):

  • OS: [e.g. iOS]. Iphone 13
  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]

Smartphone (please complete the following information):

  • Device: Iphone 13
  • OS:
  • Browser [e.g. stock browser, safari]
  • Version [e.g. 22]

Additional context
Add any other context about the problem here.

Add a way to verify platform support

Is your feature request related to a problem? Please describe.

There is no way to query whether the underlying platform supports HealthKit. One could check if we are running on iOS but this is not enough since for example iPad does not support HealthKit. Currently this plugin will just bail on registering the platform channel making it impossible to talk with the underlying platform.

Describe the solution you'd like

A method is exposed on HealthKitReporter which allows to check whether the platform supports HealthKit

Describe alternatives you've considered

Currently a horrible workaround is to call any method and see if it throws the error "No implementation found for method ..."

Additional context

I am willing to contribute this feature, I just need some confirmation that it will be accepted.

Remove android from supported platforms in pubspec.yaml

The problem

Since this plugin is obviously not supported by the Android platform, it is confusing, that you still find this package on pub.dev when you are filtering for Android packages.

The solution

You just could remove remove the platform from the pubspec.yaml and drop the android folder. The drawback is, that the package is losing 10 pub points, but i think this should be done.

`isAuthorizedToWrite` implementation not found on iPad

I'm getting Crashlytics reports stating that no implementation is found for isAuthorizedToWrite on the channel. It turns out all 3 occurrences are on iPads so I'm assuming it's an issue with iPad compatibility.

In the meantime I'm going to detect the device in my code to circumvent the crash when it's an iPad.

Screen Shot 2022-03-09 at 1 09 50 PM

  • Devices: iPad Pro 5th generation and iPad 8th generation
  • OS: iPadOS 15.3.1 for all 3 occurrences I have.

Unexpected dataType of class HKActivitySummaryType for startDate predicate

Describe the bug
I have this error:
"Unexpected dataType of class HKActivitySummaryType for startDate predicate"

2020-12-23 14:19:03.814970+0300 Runner[5703:578480] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unexpected dataType of class HKActivitySummaryType for startDate predicate' *** First throw call stack: (0x1bce75344 0x1bcb8acc0 0x1bcd6551c 0x1d0bcbfa8 0x1d0b2005c 0x1d0b1fec8 0x1d0b1fb94 0x1d0aeb2d0 0x1d0ae89c4 0x1d0b08824 0x1049fb9c0 0x1049fb930 0x1049fb45c 0x104b974d8 0x104b97970 0x104b9212c 0x104b97a2c 0x104b97b2c 0x1032a1c84 0x102a603b4 0x102d3ac18 0x102a69948 0x102a6c074 0x1bcdf13a8 0x1bcdf10c0 0x1bcdf0740 0x1bcdeb538 0x1bcdeabc8 0x1c71cc5cc 0x1c0f9d744 0x1026c1b48 0x1bcc67384) libc++abi.dylib: terminating with uncaught exception of type NSException *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unexpected dataType of class HKActivitySummaryType for startDate predicate' terminating with uncaught exception of type NSException (lldb)

Smartphone:

  • Device: iPhone11
  • OS: iOS13.6.1

Please help.

Save WorkoutRouteHarmonized

I try to save a workout route harmonized but I git error

I try to save like this:

try {
      final canWrite = await HealthKitReporter.isAuthorizedToWrite(
        SeriesType.workoutRoute.identifier,
      );
      if (canWrite) {
        final now = DateTime.now();
        const duration = 60;
        final minuteAgo = now.add(Duration(seconds: -duration));
        final harmonized = WorkoutRouteHarmonized(
          10,
          [
            WorkoutRouteBatch([
              WorkoutRouteLocation(
                43.584231,
                -84.787381,
                281.000,
                10.0,
                null,
                null,
                20.0,
                2.0,
                null,
                minuteAgo.microsecondsSinceEpoch,
                10.0,
              ),
              WorkoutRouteLocation(
                43.582840,
                -84.787370,
                281.000,
                10.0,
                null,
                null,
                20.0,
                2.0,
                null,
                now.millisecondsSinceEpoch,
                10.0,
              ),
            ], true),
          ],
          null,
        );

        final workout = WorkoutRoute(
          'testWorkoutUUID',
          'bicycle',
          minuteAgo.millisecondsSinceEpoch,
          now.millisecondsSinceEpoch,
          device,
          sourceRevision,
          harmonized,
        );
        print('try to save: ${workout.map}');
        final saved = await HealthKitReporter.save(workout);
        print('workoutSaved: $saved');
      } else {
        print('error canWrite workout: $canWrite');
      }
    } catch (e) {
      print(e);
    }

Error

flutter: isRequested auth: true
flutter: try to save: {uuid: testWorkoutUUID, identifier: bicycle, startTimestamp: 1650733338915, endTimestamp: 1650733398915, device: {name: FlutterTracker, manufacturer: kvs, model: T-800, hardwareVersion: 3, firmwareVersion: 3.0, softwareVersion: 1.1.1, localIdentifier: kvs.sample.app, udiDeviceIdentifier: 444-888-555}, sourceRevision: {source: {name: myApp, bundleIdentifier: com.kvs.health_kit_reporter_example}, version: 5, productType: fit, systemVersion: 4, operatingSystem: {majorVersion: 1, minorVersion: 2, patchVersion: 3}}, harmonized: {count: 10, routes: [{locations: [{latitude: 43.584231, longitude: -84.787381, altitude: 281.0, course: 10.0, courseAccuracy: null, floor: null, horizontalAccuracy: 20.0, speed: 2.0, speedAccuracy: null, timestamp: 1650733338915182, verticalAccuracy: 10.0}, {latitude: 43.58284, longitude: -84.78737, altitude: 281.0, course: 10.0, courseAccuracy: null, floor: null, horizontalAccuracy: 20.0, speed: 2.0, speedAccuracy: null, timestamp: 1650733398915, verticalAccuracy: 10.0}], done: true}], metadata: null}}
Unsupported value: HealthKitReporter.HealthKitError.invalidValue("Invalid arguments: [:]") of type __SwiftNativeNSError
*** Assertion failure in -[FlutterStandardWriter writeValue:], FlutterStandardCodec.mm:338
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Unsupported value for standard codec'
*** First throw call stack:
(0x180f5370c 0x19868ef04 0x1826f4b00 0x103ded08c 0x103ded7ec 0x103dea7dc 0x10119ead8 0x1011b1e20 0x1011b0868 0x1011a5fbc 0x1011b0910 0x103dea744 0x103923c78 0x103cb1b3c 0x103bd9148 0x103bdceac 0x180f67c58 0x180ef14e8 0x180eec0a0 0x180ecbd94 0x180edec30 0x1a18f9988 0x1836d9c50 0x1834733d0 0x100d170dc 0x1010343d0)
libc++abi: terminating with uncaught exception of type NSException
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
    frame #0: 0x00000001bb6a1bbc libsystem_kernel.dylib`__pthread_kill + 8
libsystem_kernel.dylib`__pthread_kill:
->  0x1bb6a1bbc <+8>:  b.lo   0x1bb6a1bd8               ; <+36>
    0x1bb6a1bc0 <+12>: stp    x29, x30, [sp, #-0x10]!
    0x1bb6a1bc4 <+16>: mov    x29, sp
    0x1bb6a1bc8 <+20>: bl     0x1bb69d60c               ; cerror_nocancel
Target 0: (Runner) stopped.

Thanks.

Cannot run example app

Describe the bug
Cannot run example app. It breaks with a couple of swift compiler errors.
For instance Use of undeclared type 'Harmonized' and Use of undeclared type 'HKElectrocardiogram'

Additional context
Tested with flutter 1.20 and 1.22

Reading workouts always returns empty array

Describe the bug
Reading data from any quantityQuery will return the appropriate information, but trying to read workout information with a workoutQuery will always return an empty array. Read permissions are definitely enabled.

Sample code for reading:

final canReadWorkouts = await HealthKitReporter.requestAuthorization(
            [WorkoutType.workoutType.identifier], []);
        if (canReadWorkouts) {
          final workouts = await HealthKitReporter.workoutQuery(predicate);
          _logger.info("Workouts: ${workouts.length}");
          for (var workout in workouts) {
            _logger.info(
                "workout: ${workout.harmonized.value} ${workout.harmonized.totalEnergyBurnedUnit}");
          }
        }

Will return Workouts: 0

predicate for the same time period appropriately fetches active energy quantity

AH has a couple workouts logged
Screen Shot 2021-02-19 at 3 17 56 PM

I'm wondering if I'm pulling the workouts properly or if I'm missing a permission.
Any extra info would be appreciated.

Crash in production app encodeErrorEnvelope

Describe the bug
Reported crashes on iOS production devices.

Screenshots

1
3
4
5

Additional context
Before the plugin integration the app had about zero crashes, now there are a few (about 7% of devices).

I don't know what additional information could help you.

Is it possible to listen to 2 (or more) anchoredObjectQuery?

Describe the bug
When I try to call HealthKitReporter.anchoredObjectQuery twice (first time for WorkoutType.workoutType.identifier, second for CategoryType.sleepAnalysis.identifier) it seems to overwrite the first call with the second, so I cannot see updates to WorkoutType.workoutType.identifier, only those for CategoryType.sleepAnalysis.identifier.

I tried each one separately (i.e.test with WorkoutType.workoutType.identifier, then rebuild the app and test with CategoryType.sleepAnalysis.identifier) and they both work. But 2 together do not work.

Smartphone (please complete the following information):

  • Device: Iphone 8
  • OS: iOS 14

Additional context
[✓] Flutter (Channel stable, 2.5.2, on macOS 11.6 20G165 darwin-x64, locale en-GB)
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
[✓] Xcode - develop for iOS and macOS

Could the predicate param be optional in some cases?

Firstly, thanks for creating this library! It's great! I just have a quick question / request...

Is your feature request related to a problem? Please describe.

Our usecase is to register for background updates for a number of QuantityTypes using the observerQuery method, which takes a non-optional predicate. I see from Apple's docs the predicate is optional : A predicate that limits the samples matched by the query. Pass nil if you want to receive updates for every new sample of the specified type. Essentially we don't want to specify an end date to continually get updates.

Describe the solution you'd like

Make the predicates optional wherever possible.

Describe alternatives you've considered

The only work around to the non-optional predicate I can think of is to pick an arbitrary date well into the future.

Creating a new `anchoredObjectQuery` stream cancels the previous one

Describe the bug
When you call HealthKitReporter.anchoredObjectQuery and then later call it again to create a new anchoredObjectQuery the original one is cancelled.

To Reproduce
Steps to reproduce the behavior:

var originalStream = HealthKitReporter.anchoredObjectQuery(...);
var newStream = HealthKitReporter.anchoredObjectQuery(...); // cancels originalStream

Expected behavior
You should be able to create any number of anchoredObjectQuerys that run as independent streams.

Additional context
A single AnchoredObjectQueryStreamHandler is registered with the event channel at https://github.com/VictorKachalov/health_kit_reporter/blob/master/ios/Classes/SwiftHealthKitReporterPlugin.swift#L69. AnchoredObjectQueryStreamHandler only has a single query though which is replaced at https://github.com/VictorKachalov/health_kit_reporter/blob/master/ios/Classes/AnchoredObjectQueryStreamHandler.swift#L36 whenever HealthKitReporter.anchoredObjectQuery is called.

I'm new to Flutter/Dart so I'm not sure how this tends to be handled but in other languages using channels I've used an identifier (say a uuid) for the stream that is created for a particular call to HealthKitReporter.anchoredObjectQuery. That way it's possible to have multiple AnchoredQueries on the Swift side and use the uuid to route messages appropriately on the Dart side.

HealthKitReporter.workoutRouteQuery: Unhandled Exception: type 'Null' is not a subtype of type 'List<dynamic>'

Describe the bug
Hi,
I am trying to read route data from Health App tracked with an Apple Watch. The route is correctly displayed in Health App. When trying to read the route data, I get following Exceptions:

[VERBOSE-2:ui_dart_state.cc(209)] Unhandled Exception: type 'Null' is not a subtype of type 'List'
new WorkoutRoute.fromJson
package:health_kit_reporter/…/payload/workout_route.dart:30
HealthKitReporter.workoutRouteQuery.
package:health_kit_reporter/health_kit_reporter.dart:155
_rootRunUnary (dart:async[/zone.dart:1434:47])
_CustomZone.runUnary (dart:async[/zone.dart:1335:19])
_CustomZone.runUnaryGuarded (dart:async[/zone.dart:1244:7])
_BufferingStreamSubscription._sendData (dart:async[/stream_impl.dart:341:11])
_DelayedData.perform (dart:async[/stream_impl.dart:591:14])
_StreamImplEvents.handleNext (dart:async[/stream_impl.dart:706:11])
_PendingEvents.schedule. (dart:async[/stream_impl.dart:663:7])
_rootRun (dart:async[/zone.dart:1418:47])
_CustomZone.run (dart:async[/zone.dart:1328:19])
_CustomZone.runGuarded (dart:async[/zone.dart:1236:7])
_CustomZone.bindCallbackGuarded. (dart:async[/zone.dart:1276:23])
_rootRun (dart:async[/zone.dart:1426:13])
_CustomZone.run (dart:async[/zone.dart:1328:19])
_CustomZone.runGuarded (dart:async[/zone.dart:1236:7])
_CustomZone.bindCallbackGuarded. (dart:async[/zone.dart:1276:23])
_microtaskLoop (dart:async[/schedule_microtask.dart:40:21])
_startMicrotaskLoop (dart:async[/schedule_microtask.dart:49:5])

To Reproduce
Here are my code fragments to read the data:

void _startUpdateStreams() async {
List identifierList = [SeriesType.route.identifier];

Predicate _timeIntervallPredicate = Predicate(
DateTime.now().add(const Duration(days: -7)),
DateTime.now().add(const Duration(days: 7)));

_workoutRouteUpdates(_timeIntervallPredicate);

for (int i = 0; i < identifierList.length; i++) {
final isSet = await HealthKitReporter.enableBackgroundDelivery(
identifierList[i], UpdateFrequency.immediate);
log.d('enableBackgroundDelivery for '+identifierList[i]+': $isSet');
}
}

void _workoutRouteUpdates(Predicate _predicate) {
final sub =
HealthKitReporter.workoutRouteQuery(_predicate, onUpdate: (serie) {
log.d('Updates for workoutRouteQuery');
log.d("serie.locations.length: " + serie.locations.length.toString());
});
log.d('workoutRouteQuery: $sub');
}

Expected behavior
Do not get an exception but get access to the location data.

Smartphone (please complete the following information):

  • Device: iPhone7
  • OS: iOS15.4.1

Workout metadata missing.

Describe the bug
When I use HealthKitReporter.workoutQuery(predicate) to retrieve workout data, harmonized.metadata always returns null.

To Reproduce
try { final workouts = await HealthKitReporter.workoutQuery(predicate); workouts.forEach((element) { print('metadata: ${element.harmonized.metadata}'); }); } catch (e) { print(e); }

Expected behavior
The metadata should look like this:
{HKAverageMETs: 4.85739 kcal/hr·kg, HKIndoorWorkout: 0, HKWeatherTemperature: 52.016 degF, HKWeatherHumidity: 7600 %, HKTimeZone: Asia/Shanghai, HKElevationAscended: 2403 cm}

Additional context
I think the reason might be that there's something wrong with Metadata.make()in the native code.

1.5.x introduces API breaking changes

Describe the bug
Version 1.5.x is mislabeled. Its version number suggests that there are new features with no breaking API changes. But in fact old code is not compatible anymore.

To Reproduce

  1. Have a flutter project that relies on version 1.3.x or 1.4.x of this plugin.
  2. Run flutter clean, remove the pubspec.lock
  3. Run flutter pub upgrade
  4. See error messages

Expected behavior
The plugin should continue to work with the old code, as it's a minor series upgrade. What is now called 1.5.x should have been a 2.x

Screenshots
None, but changes like f08e629#diff-bb8f6fdce8b91b43f4156f21e5fed48f710f08ebaad88347e4b3cc896fdccd6dR167 are likely to have caused the problem.

Desktop (please complete the following information):
All of them

Smartphone (please complete the following information):
All of them

Additional context
Please see https://dart.dev/tools/pub/versioning

Build error with latest version

Describe the bug
'Correlation' has no member 'make':

    /Users/builder/programs/flutter_3_0_1/.pub-cache/hosted/pub.dartlang.org/health_kit_reporter-2.0.4/ios/Classes/Extensions+SwiftHealthKitReporterPlugin.swift:1482:42: error: type 'Correlation' has no member 'make'
                let sample = try Correlation.make(from: correlation)
                                 ~~~~~~~~~~~ ^~~~
    Command CompileSwiftSources failed with a nonzero exit code

To Reproduce
Steps to reproduce the behavior:

  1. Add plugin version 2.0.4 to app
  2. Build app for iOS

Expected behavior
Build succeeds

Desktop (please complete the following information):

  • Flutter 3.0.1

Additional context
Build log is from Codemagic.

App crashes, no reason why.

The app just closes; no reason why.

      final started = DateTime.parse(drill.timeStartedISO!);
      final ended = DateTime.parse(drill.timeEndedISO!);

      final packageInfo = await PackageInfo.fromPlatform();

      final operatingSystem = OperatingSystem(1, 2, 3);
      final source = Source(packageInfo.appName, packageInfo.packageName);
      final sourceRevision = SourceRevision(source, null, null, '4', operatingSystem);

      final harmonized = QuantityHarmonized(
        drill.totalCalories().round(),
        'CALORIES',
        {
          'Total Weight Lifted': drill.getTotalLoggedVolumeKG(),
          'Workouts': drill.getWorkoutsDone(),
          'Workout Name': drill.makeupName(),
        },
      );

      final steps = Quantity(
        drill.uid,
        QuantityType.activeEnergyBurned.identifier,
        started.millisecondsSinceEpoch,
        ended.millisecondsSinceEpoch,
        null,
        sourceRevision,
        harmonized,
      );

      await HealthKitReporter.save(steps);

Retrieving even a single iOS ECG measurement w/ voltage data causes app to crash

Hi there, thanks so much for the fantastic package!!

I am trying to retrieve iOS ECG data including voltage information within my Flutter app.
Sadly the app crashes when I try to retrieve just a single ECG reading. I have tracked them back and they crash within the Swift file at the line let voltageQuery = HKElectrocardiogramQuery(ecgSample) { (query, [result][1]) in ie. when it's actually retrieving the data (relevant Apple documentation here).

Whenever I do it, I get the memory error:

* thread #3, queue = 'com.apple.HealthKit.HKHealthStore.client.0x281d32630', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
    frame #0: 0x0000000000000000
error: memory read failed for 0x0
Target 0: (Runner) stopped.

I get the same error on both an iPhone 7 and iPhone 11 (both running min. iOS 14) using various different readings.

Does anyone know how to avoid this happening please?

I'm not sure if say there's a way to retrieve a part of a reading for example, as I think the app is just struggling to handle the size of variable.

Thanks a lot!

Wrong indicate git revision of 1.0.6?

Describe the bug
Wrong indicate git revision of 1.0.6?

To Reproduce

Screenshots

スクリーンショット 2021-01-17 10 01 38

Your example is No Error.
スクリーンショット 2021-01-17 10 02 14

Additional context

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 1.22.5, on macOS 11.1 20C69 darwin-arm, locale ja-JP)
 
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[✓] Xcode - develop for iOS and macOS (Xcode 12.3)
[!] Android Studio (version 4.1)
    ✗ Flutter plugin not installed; this adds Flutter specific functionality.
    ✗ Dart plugin not installed; this adds Dart specific functionality.
[✓] VS Code (version 1.52.1)
[✓] Connected device (1 available)

! Doctor found issues in 1 category.

Get the HKWorkoutActivityType for workouts

Is your feature request related to a problem? Please describe.
I'd like to get the HKWorkoutActivityType enum value for workouts. Currently we get a description string instead.

Describe the solution you'd like
Add an HKWorkoutActivityType field to the harmonized data of a workout. So if the description is Step Training we would also see HKWorkoutActivityType: stepTraining.

Currently the convertion from the HKWorkoutActivityType to the description string is done in the native pod plugin here: https://github.com/VictorKachalov/HealthKitReporter/blob/master/Sources/Decorator/Extensions%2BHKWorkoutActivityType.swift

Describe alternatives you've considered
We could map back from the description String to the key, but that's dangerous (would break without warning if the plugin is changed).

App crashes when trying to write mindful minutes.

Describe the bug
Since version 1.5.0 or 1.5.1 the app crashes on iOS.

While everything in Dart is in try-catch-blocks, the whole app crashes.
Was there a change that I need to update? The analyzer does not complain about any argument.

Screenshots

Below the crash logs I've sent to myself via TestFlight and a screenshot of the crash in Xcode:

Log 1
Incident Identifier: 818A3A29-E11B-40E9-AB96-CCBFB0548444
Hardware Model:      iPhone10,6
Process:             Runner [18400]
Path:                /private/var/containers/Bundle/Application/8C7D995A-D00B-4055-A557-255202043F77/Runner.app/Runner
Identifier:          com.achimsapps.breathe
Version:             3.18.0 (2220)
AppStoreTools:       13A1030d
AppVariant:          1:iPhone10,6:15
Beta:                YES
Code Type:           ARM-64 (Native)
Role:                Foreground
Parent Process:      launchd [1]
Coalition:           com.achimsapps.breathe [3592]

Date/Time:           2021-11-01 21:18:42.2634 +0100
Launch Time:         2021-11-01 21:17:52.8102 +0100
OS Version:          iPhone OS 15.1 (19B74)
Release Type:        User
Baseband Version:    5.00.00
Report Version:      104

Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note:  EXC_CORPSE_NOTIFY
Triggered by Thread:  0

Last Exception Backtrace:
0   CoreFoundation                	0x182e09c9c __exceptionPreprocess + 216 (NSException.m:200)
1   libobjc.A.dylib               	0x199fbd758 objc_exception_throw + 56 (objc-exception.mm:565)
2   CoreFoundation                	0x182e5cd04 +[NSException raise:format:] + 108 (NSException.m:156)
3   HealthKit                     	0x18ec00aa8 -[HKObject _validateForCreation] + 140 (HKObject.m:127)
4   HealthKit                     	0x18ec00838 +[HKObject _newDataObjectWithMetadata:device:config:] + 268 (HKObject.m:112)
5   HealthKit                     	0x18ec006e8 +[HKSample _newSampleWithType:startDate:endDate:device:metadata:config:] + 176 (HKSample.m:42)
6   HealthKit                     	0x18ec01f7c +[HKCategorySample categorySampleWithType:value:startDate:endDate:device:metadata:] + 268 (HKCategorySample.m:42)
7   HealthKitReporter             	0x1011d8dd4 @nonobjc HKCategorySample.__allocating_init(type:value:start:end:device:metadata:) + 48 (<compiler-generated>:0)
8   HealthKitReporter             	0x1011d8dd4 Category.asOriginal() + 1076 (Category.swift:125)
9   HealthKitReporter             	0x1012046f0 HealthKitWriter.delete(sample:completion:) + 408
10  health_kit_reporter           	0x101464aa8 specialized SwiftHealthKitReporterPlugin.handle(_:result:) + 6292 (SwiftHealthKitReporterPlugin.swift:0)
11  health_kit_reporter           	0x101455d90 specialized SwiftHealthKitReporterPlugin.handle(_:result:) + 12 (<compiler-generated>:0)
12  health_kit_reporter           	0x101455d90 @objc SwiftHealthKitReporterPlugin.handle(_:result:) + 76
13  Flutter                       	0x101a94dc0 0x1015a8000 + 5164480
14  Flutter                       	0x1015e7f34 0x1015a8000 + 261940
15  Flutter                       	0x1018f0db4 0x1015a8000 + 3444148
16  Flutter                       	0x101896068 0x1015a8000 + 3072104
17  Flutter                       	0x101899098 0x1015a8000 + 3084440
18  CoreFoundation                	0x182e1dfcc __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 28 (CFRunLoop.c:1812)
19  CoreFoundation                	0x182da8338 __CFRunLoopDoTimer + 1016 (CFRunLoop.c:2420)
20  CoreFoundation                	0x182da2fcc __CFRunLoopDoTimers + 324 (CFRunLoop.c:2580)
21  CoreFoundation                	0x182d82ea4 __CFRunLoopRun + 1948 (CFRunLoop.c:3116)
22  CoreFoundation                	0x182d95d7c CFRunLoopRunSpecific + 572 (CFRunLoop.c:3268)
23  GraphicsServices              	0x19d00a9a0 GSEventRunModal + 160 (GSEvent.c:2200)
24  UIKitCore                     	0x1855c805c -[UIApplication _run] + 1080 (UIApplication.m:3493)
25  UIKitCore                     	0x18535dce0 UIApplicationMain + 2028 (UIApplication.m:5046)
26  Runner                        	0x100e4f090 main + 64 (AppDelegate.swift:5)
27  dyld                          	0x10114c190 start + 444 (dyldMain.cpp:876)

Thread 0 name:
Thread 0 Crashed:
0   libsystem_kernel.dylib        	0x00000001bc7f29e8 __pthread_kill + 8
1   libsystem_pthread.dylib       	0x00000001dcd45824 pthread_kill + 208 (pthread.c:1610)
2   libsystem_c.dylib             	0x000000018d2830b4 abort + 120 (abort.c:118)
3   libc++abi.dylib               	0x000000019a0b2e1c abort_message + 128 (abort_message.cpp:78)
4   libc++abi.dylib               	0x000000019a0a4bec demangling_terminate_handler() + 296 (cxa_default_handlers.cpp:71)
5   libobjc.A.dylib               	0x0000000199fc30c8 _objc_terminate() + 124 (objc-exception.mm:701)
6   libc++abi.dylib               	0x000000019a0b22cc std::__terminate(void (*)()) + 16 (cxa_handlers.cpp:59)
7   libc++abi.dylib               	0x000000019a0b4e4c __cxa_rethrow + 144 (cxa_exception.cpp:616)
8   libobjc.A.dylib               	0x0000000199fbf298 objc_exception_rethrow + 40 (objc-exception.mm:604)
9   CoreFoundation                	0x0000000182d95e68 CFRunLoopRunSpecific + 808 (CFRunLoop.c:3283)
10  GraphicsServices              	0x000000019d00a9a0 GSEventRunModal + 160 (GSEvent.c:2200)
11  UIKitCore                     	0x00000001855c805c -[UIApplication _run] + 1080 (UIApplication.m:3493)
12  UIKitCore                     	0x000000018535dce0 UIApplicationMain + 2028 (UIApplication.m:5046)
13  Runner                        	0x0000000100e4f090 main + 64 (AppDelegate.swift:5)
14  dyld                          	0x000000010114c190 start + 444 (dyldMain.cpp:876)

Thread 1:
0   libsystem_pthread.dylib       	0x00000001dcd399e8 start_wqthread + 0

Thread 2:
0   libsystem_pthread.dylib       	0x00000001dcd399e8 start_wqthread + 0

Thread 3:
0   libsystem_pthread.dylib       	0x00000001dcd399e8 start_wqthread + 0

Thread 4 name:
Thread 4:
0   libsystem_kernel.dylib        	0x00000001bc7ecb10 mach_msg_trap + 8
1   libsystem_kernel.dylib        	0x00000001bc7ed134 mach_msg + 72 (mach_msg.c:119)
2   CoreFoundation                	0x0000000182d7eac0 __CFRunLoopServiceMachPort + 368 (CFRunLoop.c:2646)
3   CoreFoundation                	0x0000000182d82ba8 __CFRunLoopRun + 1184 (CFRunLoop.c:3000)
4   CoreFoundation                	0x0000000182d95d7c CFRunLoopRunSpecific + 572 (CFRunLoop.c:3268)
5   Foundation                    	0x00000001844ce00c -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 232 (NSRunLoop.m:373)
6   Foundation                    	0x000000018450d18c -[NSRunLoop(NSRunLoop) runUntilDate:] + 88 (NSRunLoop.m:420)
7   UIKitCore                     	0x0000000185545d58 -[UIEventFetcher threadMain] + 512 (UIEventFetcher.m:1167)
8   Foundation                    	0x000000018451aefc __NSThread__start__ + 792 (NSThread.m:972)
9   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
10  libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 5 name:
Thread 5:
0   libsystem_kernel.dylib        	0x00000001bc7ecb10 mach_msg_trap + 8
1   libsystem_kernel.dylib        	0x00000001bc7ed134 mach_msg + 72 (mach_msg.c:119)
2   CoreFoundation                	0x0000000182d7eac0 __CFRunLoopServiceMachPort + 368 (CFRunLoop.c:2646)
3   CoreFoundation                	0x0000000182d82ba8 __CFRunLoopRun + 1184 (CFRunLoop.c:3000)
4   CoreFoundation                	0x0000000182d95d7c CFRunLoopRunSpecific + 572 (CFRunLoop.c:3268)
5   Flutter                       	0x0000000101898f74 0x1015a8000 + 3084148
6   Flutter                       	0x0000000101898788 0x1015a8000 + 3082120
7   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
8   libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 6 name:
Thread 6:
0   libsystem_kernel.dylib        	0x00000001bc7ecb10 mach_msg_trap + 8
1   libsystem_kernel.dylib        	0x00000001bc7ed134 mach_msg + 72 (mach_msg.c:119)
2   CoreFoundation                	0x0000000182d7eac0 __CFRunLoopServiceMachPort + 368 (CFRunLoop.c:2646)
3   CoreFoundation                	0x0000000182d82ba8 __CFRunLoopRun + 1184 (CFRunLoop.c:3000)
4   CoreFoundation                	0x0000000182d95d7c CFRunLoopRunSpecific + 572 (CFRunLoop.c:3268)
5   Flutter                       	0x0000000101898f74 0x1015a8000 + 3084148
6   Flutter                       	0x0000000101898788 0x1015a8000 + 3082120
7   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
8   libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 7 name:
Thread 7:
0   libsystem_kernel.dylib        	0x00000001bc7ecb10 mach_msg_trap + 8
1   libsystem_kernel.dylib        	0x00000001bc7ed134 mach_msg + 72 (mach_msg.c:119)
2   CoreFoundation                	0x0000000182d7eac0 __CFRunLoopServiceMachPort + 368 (CFRunLoop.c:2646)
3   CoreFoundation                	0x0000000182d82ba8 __CFRunLoopRun + 1184 (CFRunLoop.c:3000)
4   CoreFoundation                	0x0000000182d95d7c CFRunLoopRunSpecific + 572 (CFRunLoop.c:3268)
5   Flutter                       	0x0000000101898f74 0x1015a8000 + 3084148
6   Flutter                       	0x0000000101898788 0x1015a8000 + 3082120
7   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
8   libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 8 name:
Thread 8:
0   libsystem_kernel.dylib        	0x00000001bc7ed4f0 __psynch_cvwait + 8
1   libsystem_pthread.dylib       	0x00000001dcd3a8b8 _pthread_cond_wait$VARIANT$armv81 + 1216 (pthread_cond.c:636)
2   libc++.1.dylib                	0x000000019a0502b8 std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&) + 24 (__threading_support:437)
3   Flutter                       	0x0000000101893b60 0x1015a8000 + 3062624
4   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
5   libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 9 name:
Thread 9:
0   libsystem_kernel.dylib        	0x00000001bc7ed4f0 __psynch_cvwait + 8
1   libsystem_pthread.dylib       	0x00000001dcd3a8b8 _pthread_cond_wait$VARIANT$armv81 + 1216 (pthread_cond.c:636)
2   libc++.1.dylib                	0x000000019a0502b8 std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&) + 24 (__threading_support:437)
3   Flutter                       	0x0000000101893b60 0x1015a8000 + 3062624
4   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
5   libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 10 name:
Thread 10:
0   libsystem_kernel.dylib        	0x00000001bc7ed4f0 __psynch_cvwait + 8
1   libsystem_pthread.dylib       	0x00000001dcd3a8b8 _pthread_cond_wait$VARIANT$armv81 + 1216 (pthread_cond.c:636)
2   libc++.1.dylib                	0x000000019a0502b8 std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&) + 24 (__threading_support:437)
3   Flutter                       	0x0000000101893b60 0x1015a8000 + 3062624
4   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
5   libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 11 name:
Thread 11:
0   libsystem_kernel.dylib        	0x00000001bc7ed4f0 __psynch_cvwait + 8
1   libsystem_pthread.dylib       	0x00000001dcd3a8b8 _pthread_cond_wait$VARIANT$armv81 + 1216 (pthread_cond.c:636)
2   libc++.1.dylib                	0x000000019a0502b8 std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&) + 24 (__threading_support:437)
3   Flutter                       	0x0000000101893b60 0x1015a8000 + 3062624
4   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
5   libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 12 name:
Thread 12:
0   libsystem_kernel.dylib        	0x00000001bc7ed4f0 __psynch_cvwait + 8
1   libsystem_pthread.dylib       	0x00000001dcd3a8b8 _pthread_cond_wait$VARIANT$armv81 + 1216 (pthread_cond.c:636)
2   libc++.1.dylib                	0x000000019a0502b8 std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&) + 24 (__threading_support:437)
3   Flutter                       	0x0000000101893b60 0x1015a8000 + 3062624
4   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
5   libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 13 name:
Thread 13:
0   libsystem_kernel.dylib        	0x00000001bc7ed4f0 __psynch_cvwait + 8
1   libsystem_pthread.dylib       	0x00000001dcd3a8b8 _pthread_cond_wait$VARIANT$armv81 + 1216 (pthread_cond.c:636)
2   libc++.1.dylib                	0x000000019a0502b8 std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&) + 24 (__threading_support:437)
3   Flutter                       	0x0000000101893b60 0x1015a8000 + 3062624
4   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
5   libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 14 name:
Thread 14:
0   libsystem_kernel.dylib        	0x00000001bc7ee2f8 kevent + 8
1   Flutter                       	0x00000001019e348c 0x1015a8000 + 4437132
2   Flutter                       	0x0000000101a10cc4 0x1015a8000 + 4623556
3   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
4   libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 15 name:
Thread 15:
0   libsystem_kernel.dylib        	0x00000001bc7ecb10 mach_msg_trap + 8
1   libsystem_kernel.dylib        	0x00000001bc7ed134 mach_msg + 72 (mach_msg.c:119)
2   CoreFoundation                	0x0000000182d7eac0 __CFRunLoopServiceMachPort + 368 (CFRunLoop.c:2646)
3   CoreFoundation                	0x0000000182d82ba8 __CFRunLoopRun + 1184 (CFRunLoop.c:3000)
4   CoreFoundation                	0x0000000182d95d7c CFRunLoopRunSpecific + 572 (CFRunLoop.c:3268)
5   AudioSession                  	0x000000018b918d7c CADeprecated::GenericRunLoopThread::Entry(void*) + 156 (GenericRunLoopThread.h:95)
6   AudioSession                  	0x000000018b9220ac CADeprecated::CAPThread::Entry(CADeprecated::CAPThread*) + 88 (CAPThread.cpp:324)
7   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
8   libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 16:
0   libsystem_pthread.dylib       	0x00000001dcd399e8 start_wqthread + 0

Thread 17:
0   libsystem_pthread.dylib       	0x00000001dcd399e8 start_wqthread + 0

Thread 18 name:
Thread 18:
0   libsystem_kernel.dylib        	0x00000001bc7ecb64 semaphore_timedwait_trap + 8
1   libdispatch.dylib             	0x0000000182aa571c _dispatch_sema4_timedwait$VARIANT$armv81 + 60 (lock.c:154)
2   libdispatch.dylib             	0x0000000182aa5cac _dispatch_semaphore_wait_slow + 72 (semaphore.c:116)
3   libdispatch.dylib             	0x0000000182aba0f8 _dispatch_worker_thread + 304 (queue.c:7040)
4   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
5   libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 19:
0   libsystem_pthread.dylib       	0x00000001dcd399e8 start_wqthread + 0

Thread 20 name:
Thread 20 name:
Thread 20:
0   libsystem_kernel.dylib        	0x00000001bc7ecb10 mach_msg_trap + 8
1   libsystem_kernel.dylib        	0x00000001bc7ed134 mach_msg + 72 (mach_msg.c:119)
2   libdispatch.dylib             	0x0000000182aa7cbc _dispatch_mach_send_and_wait_for_reply + 504 (mach.c:815)
3   libdispatch.dylib             	0x0000000182aa8068 dispatch_mach_send_with_result_and_wait_for_reply$VARIANT$armv81 + 52 (mach.c:2019)
4   libxpc.dylib                  	0x00000001dcd63458 xpc_connection_send_message_with_reply_sync + 236 (connection.c:974)
5   CoreMedia                     	0x000000018cdb5d58 FigXPCRemoteClientSendSyncMessageCreatingReply + 40 (FigXPCClientServer.c:939)
6   CoreMedia                     	0x000000018cdb5ec4 FigXPCSendStdSetPropertyMessage + 128 (FigXPCClientServer.c:969)
7   MediaToolbox                  	0x000000018c7bf774 remoteXPCPlayer_SetProperty + 140 (FigPlayer_RemoteXPC.m:5847)
8   MediaToolbox                  	0x000000018c6d2198 playerasync_runOneCommand + 2332 (FigPlayer_Async.c:0)
9   MediaToolbox                  	0x000000018c6d51bc playerasync_runAsynchronousCommandOnQueue + 180 (FigPlayer_Async.c:1539)
10  libdispatch.dylib             	0x0000000182ad6198 _dispatch_client_callout + 16 (object.m:560)
11  libdispatch.dylib             	0x0000000182ab113c _dispatch_lane_serial_drain$VARIANT$armv81 + 604 (inline_internal.h:2601)
12  libdispatch.dylib             	0x0000000182ab1c28 _dispatch_lane_invoke$VARIANT$armv81 + 440 (queue.c:3937)
13  libdispatch.dylib             	0x0000000182aba2e0 _dispatch_root_queue_drain + 328 (inline_internal.h:0)
14  libdispatch.dylib             	0x0000000182aba0b4 _dispatch_worker_thread + 236 (queue.c:7037)
15  libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
16  libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 21 name:
Thread 21 name:
Thread 21:
0   libsystem_kernel.dylib        	0x00000001bc7ecb10 mach_msg_trap + 8
1   libsystem_kernel.dylib        	0x00000001bc7ed134 mach_msg + 72 (mach_msg.c:119)
2   libdispatch.dylib             	0x0000000182aa7cbc _dispatch_mach_send_and_wait_for_reply + 504 (mach.c:815)
3   libdispatch.dylib             	0x0000000182aa8068 dispatch_mach_send_with_result_and_wait_for_reply$VARIANT$armv81 + 52 (mach.c:2019)
4   libxpc.dylib                  	0x00000001dcd63458 xpc_connection_send_message_with_reply_sync + 236 (connection.c:974)
5   CoreMedia                     	0x000000018cdb5d58 FigXPCRemoteClientSendSyncMessageCreatingReply + 40 (FigXPCClientServer.c:939)
6   MediaToolbox                  	0x000000018c7c222c remoteXPCPlayer_SetRateWithOptions + 148 (FigPlayer_RemoteXPC.m:6352)
7   MediaToolbox                  	0x000000018c6d1ed0 playerasync_runOneCommand + 1620 (FigPlayer_Async.c:0)
8   MediaToolbox                  	0x000000018c6d51bc playerasync_runAsynchronousCommandOnQueue + 180 (FigPlayer_Async.c:1539)
9   libdispatch.dylib             	0x0000000182ad6198 _dispatch_client_callout + 16 (object.m:560)
10  libdispatch.dylib             	0x0000000182ab113c _dispatch_lane_serial_drain$VARIANT$armv81 + 604 (inline_internal.h:2601)
11  libdispatch.dylib             	0x0000000182ab1c28 _dispatch_lane_invoke$VARIANT$armv81 + 440 (queue.c:3937)
12  libdispatch.dylib             	0x0000000182aba2e0 _dispatch_root_queue_drain + 328 (inline_internal.h:0)
13  libdispatch.dylib             	0x0000000182aba0b4 _dispatch_worker_thread + 236 (queue.c:7037)
14  libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
15  libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 22 name:
Thread 22:
0   libsystem_kernel.dylib        	0x00000001bc7ed4f0 __psynch_cvwait + 8
1   libsystem_pthread.dylib       	0x00000001dcd3a8e4 _pthread_cond_wait$VARIANT$armv81 + 1260 (pthread_cond.c:640)
2   Flutter                       	0x0000000101b41374 0x1015a8000 + 5870452
3   Flutter                       	0x0000000101b87214 0x1015a8000 + 6156820
4   Flutter                       	0x0000000101b40c9c 0x1015a8000 + 5868700
5   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
6   libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8


Thread 0 crashed with ARM Thread State (64-bit):
    x0: 0x0000000000000000   x1: 0x0000000000000000   x2: 0x0000000000000000   x3: 0x0000000000000000
    x4: 0x000000019a0b5e55   x5: 0x000000016efb7220   x6: 0x000000000000006e   x7: 0x0000000000267900
    x8: 0x0000000101194580   x9: 0xbb9d6fcefdfc5c84  x10: 0x000000016efb6c80  x11: 0x000000000000000b
   x12: 0x0000000000000000  x13: 0x0000000051e16000  x14: 0x0000000000000010  x15: 0x0000000000000002
   x16: 0x0000000000000148  x17: 0x0000000000000000  x18: 0x0000000000000000  x19: 0x0000000000000006
   x20: 0x0000000000000103  x21: 0x0000000101194660  x22: 0x0000000000000001  x23: 0x0000000280134420
   x24: 0x0000000000000000  x25: 0x0000000000000001  x26: 0x0000000eb1e31100  x27: 0x00000001f4389000
   x28: 0x0000000000000001   fp: 0x000000016efb7190   lr: 0x00000001dcd45824
    sp: 0x000000016efb7170   pc: 0x00000001bc7f29e8 cpsr: 0x40000000
   esr: 0x56000080  Address size fault


Binary Images:
0x100e48000 - 0x100e4ffff Runner arm64  <d034162f8a28328fa5c59db7eae904d1> /private/var/containers/Bundle/Application/8C7D995A-D00B-4055-A557-255202043F77/Runner.app/Runner
0x101134000 - 0x101187fff dyld arm64  <5e7ef5771cc5369aa04d28fbba883086> /usr/lib/dyld
0x1011d0000 - 0x101243fff HealthKitReporter arm64  <5d43f174d41b34f5b05c13adc0cc7515> /private/var/containers/Bundle/Application/8C7D995A-D00B-4055-A557-255202043F77/Runner.app/Frameworks/HealthKitReporter.framework/HealthKitReporter
0x101440000 - 0x10146bfff health_kit_reporter arm64  <f84c1d03ba7536c089e908f5ec0fa69b> /private/var/containers/Bundle/Application/8C7D995A-D00B-4055-A557-255202043F77/Runner.app/Frameworks/health_kit_reporter.framework/health_kit_reporter
0x1015a8000 - 0x101cebfff Flutter arm64  <e01ae2d7b4293d2bad99555f1db36746> /private/var/containers/Bundle/Application/8C7D995A-D00B-4055-A557-255202043F77/Runner.app/Frameworks/Flutter.framework/Flutter
0x182a72000 - 0x182af4fff libdispatch.dylib arm64  <56aa6e938d8e32feac73d3e79b1ba2f5> /usr/lib/system/libdispatch.dylib
0x182d78000 - 0x1831b2fff CoreFoundation arm64  <ea9c1df294c7379bbf8d970335b1552f> /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation
0x1844b6000 - 0x184796fff Foundation arm64  <86d8a58db71f34c683e0014b2b835f1d> /System/Library/Frameworks/Foundation.framework/Foundation
0x1850dc000 - 0x186865fff UIKitCore arm64  <fb5c2d366a053355b898d8d3c163d02e> /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore
0x18b913000 - 0x18b93afff AudioSession arm64  <12427ae9e9e23966989f711c820e7125> /System/Library/PrivateFrameworks/AudioSession.framework/AudioSession
0x18c5ba000 - 0x18ccd6fff MediaToolbox arm64  <c27c31322a2d301b8c5f4e89e90b0c48> /System/Library/Frameworks/MediaToolbox.framework/MediaToolbox
0x18ccd7000 - 0x18cddffff CoreMedia arm64  <78b1b609495335ac8eb02d6bdd487283> /System/Library/Frameworks/CoreMedia.framework/CoreMedia
0x18d264000 - 0x18d2defff libsystem_c.dylib arm64  <5700e26c19b735c9b739e62c325f4fcc> /usr/lib/system/libsystem_c.dylib
0x18ebf6000 - 0x18eed3fff HealthKit arm64  <52629b13ccb5354ca9567bed7de669a1> /System/Library/Frameworks/HealthKit.framework/HealthKit
0x199fa9000 - 0x199fdefff libobjc.A.dylib arm64  <78e77e2874d0371aa2466d41374ba19a> /usr/lib/libobjc.A.dylib
0x19a047000 - 0x19a09ffff libc++.1.dylib arm64  <0b3e0b571a513ec98680bd398555aeeb> /usr/lib/libc++.1.dylib
0x19a0a0000 - 0x19a0b8fff libc++abi.dylib arm64  <a69670f6fe393e03a3f051781fbe97b5> /usr/lib/libc++abi.dylib
0x19d009000 - 0x19d011fff GraphicsServices arm64  <af306dd576573f63912fabc225106419> /System/Library/PrivateFrameworks/GraphicsServices.framework/GraphicsServices
0x1bc7ec000 - 0x1bc81dfff libsystem_kernel.dylib arm64  <28a82cbdb2103662af9e636819d8909a> /usr/lib/system/libsystem_kernel.dylib
0x1dcd35000 - 0x1dcd48fff libsystem_pthread.dylib arm64  <ce7eb78851553c3888d812f1419fa5fa> /usr/lib/system/libsystem_pthread.dylib
0x1dcd57000 - 0x1dcd89fff libxpc.dylib arm64  <0d9c930f4a4b352c988d4b52a1636fb2> /usr/lib/system/libxpc.dylib

EOF

Log 2
Incident Identifier: 6F48EAF0-19F5-49C5-B79F-1CB3A9068FAD
Hardware Model:      iPhone10,6
Process:             Runner [13398]
Path:                /private/var/containers/Bundle/Application/8C7D995A-D00B-4055-A557-255202043F77/Runner.app/Runner
Identifier:          com.achimsapps.breathe
Version:             3.18.0 (2220)
AppStoreTools:       13A1030d
AppVariant:          1:iPhone10,6:15
Beta:                YES
Code Type:           ARM-64 (Native)
Role:                Foreground
Parent Process:      launchd [1]
Coalition:           com.achimsapps.breathe [2962]

Date/Time:           2021-10-30 21:36:55.1023 +0200
Launch Time:         2021-10-30 21:36:52.5655 +0200
OS Version:          iPhone OS 15.1 (19B74)
Release Type:        User
Baseband Version:    5.00.00
Report Version:      104

Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note:  EXC_CORPSE_NOTIFY
Triggered by Thread:  0

Last Exception Backtrace:
0   CoreFoundation                	0x182e09c9c __exceptionPreprocess + 216 (NSException.m:200)
1   libobjc.A.dylib               	0x199fbd758 objc_exception_throw + 56 (objc-exception.mm:565)
2   CoreFoundation                	0x182e5cd04 +[NSException raise:format:] + 108 (NSException.m:156)
3   HealthKit                     	0x18ec00aa8 -[HKObject _validateForCreation] + 140 (HKObject.m:127)
4   HealthKit                     	0x18ec00838 +[HKObject _newDataObjectWithMetadata:device:config:] + 268 (HKObject.m:112)
5   HealthKit                     	0x18ec006e8 +[HKSample _newSampleWithType:startDate:endDate:device:metadata:config:] + 176 (HKSample.m:42)
6   HealthKit                     	0x18ec01f7c +[HKCategorySample categorySampleWithType:value:startDate:endDate:device:metadata:] + 268 (HKCategorySample.m:42)
7   HealthKitReporter             	0x102870dd4 @nonobjc HKCategorySample.__allocating_init(type:value:start:end:device:metadata:) + 48 (<compiler-generated>:0)
8   HealthKitReporter             	0x102870dd4 Category.asOriginal() + 1076 (Category.swift:125)
9   HealthKitReporter             	0x10289c6f0 HealthKitWriter.delete(sample:completion:) + 408
10  health_kit_reporter           	0x102c68aa8 0x102c44000 + 150184 (SwiftHealthKitReporterPlugin.swift:0)
11  health_kit_reporter           	0x102c59d90 specialized SwiftHealthKitReporterPlugin.handle(_:result:) + 12 (<compiler-generated>:0)
12  health_kit_reporter           	0x102c59d90 @objc SwiftHealthKitReporterPlugin.handle(_:result:) + 76
13  Flutter                       	0x103298dc0 0x102dac000 + 5164480
14  Flutter                       	0x102debf34 0x102dac000 + 261940
15  Flutter                       	0x1030f4db4 0x102dac000 + 3444148
16  Flutter                       	0x10309a068 0x102dac000 + 3072104
17  Flutter                       	0x10309d098 0x102dac000 + 3084440
18  CoreFoundation                	0x182e1dfcc __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 28 (CFRunLoop.c:1812)
19  CoreFoundation                	0x182da8338 __CFRunLoopDoTimer + 1016 (CFRunLoop.c:2420)
20  CoreFoundation                	0x182da2fcc __CFRunLoopDoTimers + 324 (CFRunLoop.c:2580)
21  CoreFoundation                	0x182d82ea4 __CFRunLoopRun + 1948 (CFRunLoop.c:3116)
22  CoreFoundation                	0x182d95d7c CFRunLoopRunSpecific + 572 (CFRunLoop.c:3268)
23  GraphicsServices              	0x19d00a9a0 GSEventRunModal + 160 (GSEvent.c:2200)
24  UIKitCore                     	0x1855c805c -[UIApplication _run] + 1080 (UIApplication.m:3493)
25  UIKitCore                     	0x18535dce0 UIApplicationMain + 2028 (UIApplication.m:5046)
26  Runner                        	0x10265b090 main + 64 (AppDelegate.swift:5)
27  dyld                          	0x1027e4190 start + 444 (dyldMain.cpp:876)

Thread 0 name:
Thread 0 Crashed:
0   libsystem_kernel.dylib        	0x00000001bc7f29e8 __pthread_kill + 8
1   libsystem_pthread.dylib       	0x00000001dcd45824 pthread_kill + 208 (pthread.c:1610)
2   libsystem_c.dylib             	0x000000018d2830b4 abort + 120 (abort.c:118)
3   libc++abi.dylib               	0x000000019a0b2e1c abort_message + 128 (abort_message.cpp:78)
4   libc++abi.dylib               	0x000000019a0a4bec demangling_terminate_handler() + 296 (cxa_default_handlers.cpp:71)
5   libobjc.A.dylib               	0x0000000199fc30c8 _objc_terminate() + 124 (objc-exception.mm:701)
6   libc++abi.dylib               	0x000000019a0b22cc std::__terminate(void (*)()) + 16 (cxa_handlers.cpp:59)
7   libc++abi.dylib               	0x000000019a0b4e4c __cxa_rethrow + 144 (cxa_exception.cpp:616)
8   libobjc.A.dylib               	0x0000000199fbf298 objc_exception_rethrow + 40 (objc-exception.mm:604)
9   CoreFoundation                	0x0000000182d95e68 CFRunLoopRunSpecific + 808 (CFRunLoop.c:3283)
10  GraphicsServices              	0x000000019d00a9a0 GSEventRunModal + 160 (GSEvent.c:2200)
11  UIKitCore                     	0x00000001855c805c -[UIApplication _run] + 1080 (UIApplication.m:3493)
12  UIKitCore                     	0x000000018535dce0 UIApplicationMain + 2028 (UIApplication.m:5046)
13  Runner                        	0x000000010265b090 main + 64 (AppDelegate.swift:5)
14  dyld                          	0x00000001027e4190 start + 444 (dyldMain.cpp:876)

Thread 1:
0   libsystem_pthread.dylib       	0x00000001dcd399e8 start_wqthread + 0

Thread 2:
0   libsystem_pthread.dylib       	0x00000001dcd399e8 start_wqthread + 0

Thread 3:
0   libsystem_pthread.dylib       	0x00000001dcd399e8 start_wqthread + 0

Thread 4 name:
Thread 4:
0   libsystem_kernel.dylib        	0x00000001bc7ecb10 mach_msg_trap + 8
1   libsystem_kernel.dylib        	0x00000001bc7ed134 mach_msg + 72 (mach_msg.c:119)
2   CoreFoundation                	0x0000000182d7eac0 __CFRunLoopServiceMachPort + 368 (CFRunLoop.c:2646)
3   CoreFoundation                	0x0000000182d82ba8 __CFRunLoopRun + 1184 (CFRunLoop.c:3000)
4   CoreFoundation                	0x0000000182d95d7c CFRunLoopRunSpecific + 572 (CFRunLoop.c:3268)
5   Foundation                    	0x00000001844ce00c -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 232 (NSRunLoop.m:373)
6   Foundation                    	0x000000018450d18c -[NSRunLoop(NSRunLoop) runUntilDate:] + 88 (NSRunLoop.m:420)
7   UIKitCore                     	0x0000000185545d58 -[UIEventFetcher threadMain] + 512 (UIEventFetcher.m:1167)
8   Foundation                    	0x000000018451aefc __NSThread__start__ + 792 (NSThread.m:972)
9   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
10  libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 5:
0   libsystem_pthread.dylib       	0x00000001dcd399e8 start_wqthread + 0

Thread 6:
0   libsystem_pthread.dylib       	0x00000001dcd399e8 start_wqthread + 0

Thread 7:
0   libsystem_pthread.dylib       	0x00000001dcd399e8 start_wqthread + 0

Thread 8 name:
Thread 8:
0   libsystem_kernel.dylib        	0x00000001bc7ecb10 mach_msg_trap + 8
1   libsystem_kernel.dylib        	0x00000001bc7ed134 mach_msg + 72 (mach_msg.c:119)
2   CoreFoundation                	0x0000000182d7eac0 __CFRunLoopServiceMachPort + 368 (CFRunLoop.c:2646)
3   CoreFoundation                	0x0000000182d82ba8 __CFRunLoopRun + 1184 (CFRunLoop.c:3000)
4   CoreFoundation                	0x0000000182d95d7c CFRunLoopRunSpecific + 572 (CFRunLoop.c:3268)
5   Flutter                       	0x000000010309cf74 0x102dac000 + 3084148
6   Flutter                       	0x000000010309c788 0x102dac000 + 3082120
7   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
8   libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 9 name:
Thread 9:
0   libsystem_kernel.dylib        	0x00000001bc7ecb10 mach_msg_trap + 8
1   libsystem_kernel.dylib        	0x00000001bc7ed134 mach_msg + 72 (mach_msg.c:119)
2   CoreFoundation                	0x0000000182d7eac0 __CFRunLoopServiceMachPort + 368 (CFRunLoop.c:2646)
3   CoreFoundation                	0x0000000182d82ba8 __CFRunLoopRun + 1184 (CFRunLoop.c:3000)
4   CoreFoundation                	0x0000000182d95d7c CFRunLoopRunSpecific + 572 (CFRunLoop.c:3268)
5   Flutter                       	0x000000010309cf74 0x102dac000 + 3084148
6   Flutter                       	0x000000010309c788 0x102dac000 + 3082120
7   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
8   libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 10 name:
Thread 10:
0   libsystem_kernel.dylib        	0x00000001bc7ef954 ftruncate + 8
1   Flutter                       	0x0000000103088234 0x102dac000 + 2998836
2   Flutter                       	0x000000010309a068 0x102dac000 + 3072104
3   Flutter                       	0x000000010309d098 0x102dac000 + 3084440
4   CoreFoundation                	0x0000000182e1dfcc __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 28 (CFRunLoop.c:1812)
5   CoreFoundation                	0x0000000182da8338 __CFRunLoopDoTimer + 1016 (CFRunLoop.c:2420)
6   CoreFoundation                	0x0000000182da2fcc __CFRunLoopDoTimers + 324 (CFRunLoop.c:2580)
7   CoreFoundation                	0x0000000182d82ea4 __CFRunLoopRun + 1948 (CFRunLoop.c:3116)
8   CoreFoundation                	0x0000000182d95d7c CFRunLoopRunSpecific + 572 (CFRunLoop.c:3268)
9   Flutter                       	0x000000010309cf74 0x102dac000 + 3084148
10  Flutter                       	0x000000010309c788 0x102dac000 + 3082120
11  libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
12  libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 11 name:
Thread 11:
0   libsystem_kernel.dylib        	0x00000001bc7ed4f0 __psynch_cvwait + 8
1   libsystem_pthread.dylib       	0x00000001dcd3a8b8 _pthread_cond_wait$VARIANT$armv81 + 1216 (pthread_cond.c:636)
2   libc++.1.dylib                	0x000000019a0502b8 std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&) + 24 (__threading_support:437)
3   Flutter                       	0x0000000103097b60 0x102dac000 + 3062624
4   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
5   libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 12 name:
Thread 12:
0   libsystem_kernel.dylib        	0x00000001bc7ed4f0 __psynch_cvwait + 8
1   libsystem_pthread.dylib       	0x00000001dcd3a8b8 _pthread_cond_wait$VARIANT$armv81 + 1216 (pthread_cond.c:636)
2   libc++.1.dylib                	0x000000019a0502b8 std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&) + 24 (__threading_support:437)
3   Flutter                       	0x0000000103097b60 0x102dac000 + 3062624
4   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
5   libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 13 name:
Thread 13:
0   libsystem_kernel.dylib        	0x00000001bc7ed4f0 __psynch_cvwait + 8
1   libsystem_pthread.dylib       	0x00000001dcd3a8b8 _pthread_cond_wait$VARIANT$armv81 + 1216 (pthread_cond.c:636)
2   libc++.1.dylib                	0x000000019a0502b8 std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&) + 24 (__threading_support:437)
3   Flutter                       	0x0000000103097b60 0x102dac000 + 3062624
4   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
5   libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 14 name:
Thread 14:
0   libsystem_kernel.dylib        	0x00000001bc7ed4f0 __psynch_cvwait + 8
1   libsystem_pthread.dylib       	0x00000001dcd3a8b8 _pthread_cond_wait$VARIANT$armv81 + 1216 (pthread_cond.c:636)
2   libc++.1.dylib                	0x000000019a0502b8 std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&) + 24 (__threading_support:437)
3   Flutter                       	0x0000000103097b60 0x102dac000 + 3062624
4   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
5   libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 15 name:
Thread 15:
0   libsystem_kernel.dylib        	0x00000001bc7ed4f0 __psynch_cvwait + 8
1   libsystem_pthread.dylib       	0x00000001dcd3a8b8 _pthread_cond_wait$VARIANT$armv81 + 1216 (pthread_cond.c:636)
2   libc++.1.dylib                	0x000000019a0502b8 std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&) + 24 (__threading_support:437)
3   Flutter                       	0x0000000103097b60 0x102dac000 + 3062624
4   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
5   libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 16 name:
Thread 16:
0   libsystem_kernel.dylib        	0x00000001bc7ed4f0 __psynch_cvwait + 8
1   libsystem_pthread.dylib       	0x00000001dcd3a8b8 _pthread_cond_wait$VARIANT$armv81 + 1216 (pthread_cond.c:636)
2   libc++.1.dylib                	0x000000019a0502b8 std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&) + 24 (__threading_support:437)
3   Flutter                       	0x0000000103097b60 0x102dac000 + 3062624
4   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
5   libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 17 name:
Thread 17:
0   libsystem_kernel.dylib        	0x00000001bc7ee2f8 kevent + 8
1   Flutter                       	0x00000001031e748c 0x102dac000 + 4437132
2   Flutter                       	0x0000000103214cc4 0x102dac000 + 4623556
3   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
4   libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 18 name:
Thread 18:
0   libsystem_kernel.dylib        	0x00000001bc7ed4f0 __psynch_cvwait + 8
1   libsystem_pthread.dylib       	0x00000001dcd3a8e4 _pthread_cond_wait$VARIANT$armv81 + 1260 (pthread_cond.c:640)
2   Flutter                       	0x0000000103345374 0x102dac000 + 5870452
3   Flutter                       	0x000000010338b214 0x102dac000 + 6156820
4   Flutter                       	0x0000000103344c9c 0x102dac000 + 5868700
5   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
6   libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 19 name:
Thread 19:
0   libsystem_kernel.dylib        	0x00000001bc7ecb10 mach_msg_trap + 8
1   libsystem_kernel.dylib        	0x00000001bc7ed134 mach_msg + 72 (mach_msg.c:119)
2   CoreFoundation                	0x0000000182d7eac0 __CFRunLoopServiceMachPort + 368 (CFRunLoop.c:2646)
3   CoreFoundation                	0x0000000182d82ba8 __CFRunLoopRun + 1184 (CFRunLoop.c:3000)
4   CoreFoundation                	0x0000000182d95d7c CFRunLoopRunSpecific + 572 (CFRunLoop.c:3268)
5   AudioSession                  	0x000000018b918d7c CADeprecated::GenericRunLoopThread::Entry(void*) + 156 (GenericRunLoopThread.h:95)
6   AudioSession                  	0x000000018b9220ac CADeprecated::CAPThread::Entry(CADeprecated::CAPThread*) + 88 (CAPThread.cpp:324)
7   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
8   libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 20 name:
Thread 20:
0   libsystem_kernel.dylib        	0x00000001bc7ecb64 semaphore_timedwait_trap + 8
1   libdispatch.dylib             	0x0000000182aa571c _dispatch_sema4_timedwait$VARIANT$armv81 + 60 (lock.c:154)
2   libdispatch.dylib             	0x0000000182aa5cac _dispatch_semaphore_wait_slow + 72 (semaphore.c:116)
3   libdispatch.dylib             	0x0000000182aba0f8 _dispatch_worker_thread + 304 (queue.c:7040)
4   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
5   libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 21 name:
Thread 21 name:
Thread 21:
0   libsystem_kernel.dylib        	0x00000001bc7ecb10 mach_msg_trap + 8
1   libsystem_kernel.dylib        	0x00000001bc7ed134 mach_msg + 72 (mach_msg.c:119)
2   libdispatch.dylib             	0x0000000182aa7cbc _dispatch_mach_send_and_wait_for_reply + 504 (mach.c:815)
3   libdispatch.dylib             	0x0000000182aa8068 dispatch_mach_send_with_result_and_wait_for_reply$VARIANT$armv81 + 52 (mach.c:2019)
4   libxpc.dylib                  	0x00000001dcd63458 xpc_connection_send_message_with_reply_sync + 236 (connection.c:974)
5   CoreMedia                     	0x000000018cdb5d58 FigXPCRemoteClientSendSyncMessageCreatingReply + 40 (FigXPCClientServer.c:939)
6   CoreMedia                     	0x000000018cdb5ec4 FigXPCSendStdSetPropertyMessage + 128 (FigXPCClientServer.c:969)
7   MediaToolbox                  	0x000000018c7bf774 remoteXPCPlayer_SetProperty + 140 (FigPlayer_RemoteXPC.m:5847)
8   MediaToolbox                  	0x000000018c6d2198 playerasync_runOneCommand + 2332 (FigPlayer_Async.c:0)
9   MediaToolbox                  	0x000000018c6d51bc playerasync_runAsynchronousCommandOnQueue + 180 (FigPlayer_Async.c:1539)
10  libdispatch.dylib             	0x0000000182ad6198 _dispatch_client_callout + 16 (object.m:560)
11  libdispatch.dylib             	0x0000000182ab113c _dispatch_lane_serial_drain$VARIANT$armv81 + 604 (inline_internal.h:2601)
12  libdispatch.dylib             	0x0000000182ab1c28 _dispatch_lane_invoke$VARIANT$armv81 + 440 (queue.c:3937)
13  libdispatch.dylib             	0x0000000182aba2e0 _dispatch_root_queue_drain + 328 (inline_internal.h:0)
14  libdispatch.dylib             	0x0000000182aba0b4 _dispatch_worker_thread + 236 (queue.c:7037)
15  libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
16  libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 22 name:
Thread 22 name:
Thread 22:
0   libsystem_kernel.dylib        	0x00000001bc7ecb10 mach_msg_trap + 8
1   libsystem_kernel.dylib        	0x00000001bc7ed134 mach_msg + 72 (mach_msg.c:119)
2   libdispatch.dylib             	0x0000000182aa7cbc _dispatch_mach_send_and_wait_for_reply + 504 (mach.c:815)
3   libdispatch.dylib             	0x0000000182aa8068 dispatch_mach_send_with_result_and_wait_for_reply$VARIANT$armv81 + 52 (mach.c:2019)
4   libxpc.dylib                  	0x00000001dcd63458 xpc_connection_send_message_with_reply_sync + 236 (connection.c:974)
5   CoreMedia                     	0x000000018cdb5d58 FigXPCRemoteClientSendSyncMessageCreatingReply + 40 (FigXPCClientServer.c:939)
6   MediaToolbox                  	0x000000018c7c222c remoteXPCPlayer_SetRateWithOptions + 148 (FigPlayer_RemoteXPC.m:6352)
7   MediaToolbox                  	0x000000018c6d1ed0 playerasync_runOneCommand + 1620 (FigPlayer_Async.c:0)
8   MediaToolbox                  	0x000000018c6d51bc playerasync_runAsynchronousCommandOnQueue + 180 (FigPlayer_Async.c:1539)
9   libdispatch.dylib             	0x0000000182ad6198 _dispatch_client_callout + 16 (object.m:560)
10  libdispatch.dylib             	0x0000000182ab113c _dispatch_lane_serial_drain$VARIANT$armv81 + 604 (inline_internal.h:2601)
11  libdispatch.dylib             	0x0000000182ab1c28 _dispatch_lane_invoke$VARIANT$armv81 + 440 (queue.c:3937)
12  libdispatch.dylib             	0x0000000182aba2e0 _dispatch_root_queue_drain + 328 (inline_internal.h:0)
13  libdispatch.dylib             	0x0000000182aba0b4 _dispatch_worker_thread + 236 (queue.c:7037)
14  libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
15  libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 23 name:
Thread 23:
0   libsystem_kernel.dylib        	0x00000001bc7ecb64 semaphore_timedwait_trap + 8
1   libdispatch.dylib             	0x0000000182aa571c _dispatch_sema4_timedwait$VARIANT$armv81 + 60 (lock.c:154)
2   libdispatch.dylib             	0x0000000182aa5cac _dispatch_semaphore_wait_slow + 72 (semaphore.c:116)
3   libdispatch.dylib             	0x0000000182aba0f8 _dispatch_worker_thread + 304 (queue.c:7040)
4   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
5   libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 24:
0   libsystem_pthread.dylib       	0x00000001dcd399e8 start_wqthread + 0

Thread 25 name:
Thread 25:
0   libsystem_kernel.dylib        	0x00000001bc7ecb64 semaphore_timedwait_trap + 8
1   libdispatch.dylib             	0x0000000182aa571c _dispatch_sema4_timedwait$VARIANT$armv81 + 60 (lock.c:154)
2   libdispatch.dylib             	0x0000000182aa5cac _dispatch_semaphore_wait_slow + 72 (semaphore.c:116)
3   libdispatch.dylib             	0x0000000182aba0f8 _dispatch_worker_thread + 304 (queue.c:7040)
4   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
5   libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8

Thread 26:
0   libsystem_pthread.dylib       	0x00000001dcd399e8 start_wqthread + 0

Thread 27 name:
Thread 27:
0   libsystem_kernel.dylib        	0x00000001bc7ed4f0 __psynch_cvwait + 8
1   libsystem_pthread.dylib       	0x00000001dcd3a8e4 _pthread_cond_wait$VARIANT$armv81 + 1260 (pthread_cond.c:640)
2   Flutter                       	0x0000000103345374 0x102dac000 + 5870452
3   Flutter                       	0x000000010338b214 0x102dac000 + 6156820
4   Flutter                       	0x0000000103344c9c 0x102dac000 + 5868700
5   libsystem_pthread.dylib       	0x00000001dcd3b3a4 _pthread_start + 116 (pthread.c:891)
6   libsystem_pthread.dylib       	0x00000001dcd399fc thread_start + 8


No thread state (register information) available

Binary Images:
0x102654000 - 0x10265bfff Runner arm64  <d034162f8a28328fa5c59db7eae904d1> /private/var/containers/Bundle/Application/8C7D995A-D00B-4055-A557-255202043F77/Runner.app/Runner
0x1027cc000 - 0x10281ffff dyld arm64  <5e7ef5771cc5369aa04d28fbba883086> /usr/lib/dyld
0x102868000 - 0x1028dbfff HealthKitReporter arm64  <5d43f174d41b34f5b05c13adc0cc7515> /private/var/containers/Bundle/Application/8C7D995A-D00B-4055-A557-255202043F77/Runner.app/Frameworks/HealthKitReporter.framework/HealthKitReporter
0x102c44000 - 0x102c6ffff health_kit_reporter arm64  <f84c1d03ba7536c089e908f5ec0fa69b> /private/var/containers/Bundle/Application/8C7D995A-D00B-4055-A557-255202043F77/Runner.app/Frameworks/health_kit_reporter.framework/health_kit_reporter
0x102dac000 - 0x1034effff Flutter arm64  <e01ae2d7b4293d2bad99555f1db36746> /private/var/containers/Bundle/Application/8C7D995A-D00B-4055-A557-255202043F77/Runner.app/Frameworks/Flutter.framework/Flutter
0x182a72000 - 0x182af4fff libdispatch.dylib arm64  <56aa6e938d8e32feac73d3e79b1ba2f5> /usr/lib/system/libdispatch.dylib
0x182d78000 - 0x1831b2fff CoreFoundation arm64  <ea9c1df294c7379bbf8d970335b1552f> /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation
0x1844b6000 - 0x184796fff Foundation arm64  <86d8a58db71f34c683e0014b2b835f1d> /System/Library/Frameworks/Foundation.framework/Foundation
0x1850dc000 - 0x186865fff UIKitCore arm64  <fb5c2d366a053355b898d8d3c163d02e> /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore
0x18b913000 - 0x18b93afff AudioSession arm64  <12427ae9e9e23966989f711c820e7125> /System/Library/PrivateFrameworks/AudioSession.framework/AudioSession
0x18c5ba000 - 0x18ccd6fff MediaToolbox arm64  <c27c31322a2d301b8c5f4e89e90b0c48> /System/Library/Frameworks/MediaToolbox.framework/MediaToolbox
0x18ccd7000 - 0x18cddffff CoreMedia arm64  <78b1b609495335ac8eb02d6bdd487283> /System/Library/Frameworks/CoreMedia.framework/CoreMedia
0x18d264000 - 0x18d2defff libsystem_c.dylib arm64  <5700e26c19b735c9b739e62c325f4fcc> /usr/lib/system/libsystem_c.dylib
0x18ebf6000 - 0x18eed3fff HealthKit arm64  <52629b13ccb5354ca9567bed7de669a1> /System/Library/Frameworks/HealthKit.framework/HealthKit
0x199fa9000 - 0x199fdefff libobjc.A.dylib arm64  <78e77e2874d0371aa2466d41374ba19a> /usr/lib/libobjc.A.dylib
0x19a047000 - 0x19a09ffff libc++.1.dylib arm64  <0b3e0b571a513ec98680bd398555aeeb> /usr/lib/libc++.1.dylib
0x19a0a0000 - 0x19a0b8fff libc++abi.dylib arm64  <a69670f6fe393e03a3f051781fbe97b5> /usr/lib/libc++abi.dylib
0x19d009000 - 0x19d011fff GraphicsServices arm64  <af306dd576573f63912fabc225106419> /System/Library/PrivateFrameworks/GraphicsServices.framework/GraphicsServices
0x1bc7ec000 - 0x1bc81dfff libsystem_kernel.dylib arm64  <28a82cbdb2103662af9e636819d8909a> /usr/lib/system/libsystem_kernel.dylib
0x1dcd35000 - 0x1dcd48fff libsystem_pthread.dylib arm64  <ce7eb78851553c3888d812f1419fa5fa> /usr/lib/system/libsystem_pthread.dylib
0x1dcd57000 - 0x1dcd89fff libxpc.dylib arm64  <0d9c930f4a4b352c988d4b52a1636fb2> /usr/lib/system/libxpc.dylib

EOF

crash

Smartphone (please complete the following information):

  • Device: iPhone X
  • OS: iOS 15.1

Does ObserverQuery work when app is killed?

It is not clear by the documentation, if observerQuery works when app is killed.
My current understanding is that it doesn't work. If that is true, do you think you will support it in the future?

Is it possible to get separate characteristics?

I have to get BirthDate and BiologicalSex in my app, for this purposes I use HealthKitReporter.characteristicsQuery() method.
I've faced with the following problem.
I get an exception _TypeError (type 'Null' is not a subtype of type 'String') in case if I request permissions only for CharacteristicType.dateOfBirth , CharacteristicType.biologicalSex and then call HealthKitReporter.characteristicsQuery().
As result I have to request permissions for all characteristics and then call HealthKitReporter.characteristicsQuery() to get only BirthDate and BiologicalSex.
Is it possible to get these characteristics without requesting additional permissions?

Calling `statisticsQuery` for a `QuantityType` that does not have any data in Health Kit should not throw.

Is your feature request related to a problem? Please describe.
Calling statisticsQuery for a QuantityType that does not have any data in Health Kit throws an error (see below) rather than returning a Statistics object with the values set to null.

Describe the solution you'd like
To maintain consistency with the behaviour observed when data does exists for the queried type but there is no data in the query time frame (for example if there is only one data point for the queried type on 06/06/22, but the query Predicate is for 07/06/22 to 08/06/22), it would be good if the function returned a Statistics object with the values set to null instead of throwing an error.

Describe alternatives you've considered
Doing a Try/Catch works, but it's counter-intuitive and more expensive.

Additional context
See #48

QuantityType.heartRateVariabilitySDNN always empty

Describe the bug
QuantityType.heartRateVariabilitySDNN is always returned empty

To Reproduce

Expected behavior

スクリーンショット 2021-01-18 21 06 44

Screenshots

I could retrieve e.g. HEART_RATE but few QuantityType always empty.
スクリーンショット 2021-01-18 22 29 13

Additional context
iPhone 12 Pro Max iOS 14.3

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 1.22.5, on macOS 11.1 20C69 darwin-arm, locale ja-JP)
 
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[✓] Xcode - develop for iOS and macOS (Xcode 12.3)
[!] Android Studio (version 4.1)
    ✗ Flutter plugin not installed; this adds Flutter specific functionality.
    ✗ Dart plugin not installed; this adds Dart specific functionality.
[✓] VS Code (version 1.52.1)
[✓] Connected device (1 available)

! Doctor found issues in 1 category.

HKMetadataKeySyncIdentifier / HKMetadataKeySyncVersion are not updated when passed in Quantity.metadata

Is your feature request related to a problem? Please describe.
Is it possible to write HKCumulativeQuantitySample values? For instance, I'd like to write QuantityType.dietaryEnergyConsumed values per day. Sample code:

  final now = DateTime.now();
  final lastMidnight = DateTime(now.year, now.month, now.day);
  const harmonized = QuantityHarmonized(100, 'kcal', null);
  final steps = Quantity(
    '',
    QuantityType.dietaryEnergyConsumed.identifier,
    lastMidnight.millisecondsSinceEpoch,
    now.millisecondsSinceEpoch,
    null,
    SourceRevision(...),
    harmonized,
  );
  await HealthKitReporter.save(steps);

Currently, when data is saved this way, calorie values are split per hour in apple health.
In this example, 100 calories are added at 12 noon, and apple health displays (100/12) calories consumed every hour (midnight - 1, 1-2, ... )

Describe the solution you'd like
Cumulative daily consumption shown as a single data point.

Thanks for the great plugin!

I was waiting for a package like yours. Yesterday, I've implemented saving mindful minutes and it works well!

If interested, I could share some sample code here, that works for this use case (was struggling before finding out that I had to use Category() and that CategoryHarmonized.value needed to be 0 - also found out that most of the values for Device are better left null).

FYI, in the Swift package, there is a typo in the error messages ('foramtted').

Build error 2.0.3 - extra arguments at positions #2, #3 in call ... reporter.reader.electrocardiogramQuery

Describe the bug
While working on issue #38, I tried to update to release 2.0.3. When trying to create the iOS archive, following errors occur:

Swift Compiler Error (Xcode): Extra arguments at positions # 2, # 3 in call
.../.pub-cache/hosted/pub.dartlang.org/health_kit_reporter-2.0.3/ios/Classes/Extensions+SwiftHealthKitReporterPlugin.swift:551:70

Swift Compiler Error (Xcode): Missing argument for parameter 'resultsHandler' in call
.../.pub-cache/hosted/pub.dartlang.org/health_kit_reporter-2.0.3/ios/Classes/Extensions+SwiftHealthKitReporterPlugin.swift:576:17

Encountered error while archiving for device.

-- OR in more detailled form --
-- START --

.../.pub-cache/hosted/pub.dartlang.org/health_kit_reporter-2.0.3/ios/Classes/Extensions+SwiftHealthKitReporterPlugin.swift:552:71: error: extra arguments at positions # 2, # 3 in call
let query = try reporter.reader.electrocardiogramQuery(
^
HealthKitReporter.HealthKitReader:28:17: note: 'electrocardiogramQuery(predicate:sortDescriptors:limit:resultsHandler:)' declared here
public func electrocardiogramQuery(predicate: NSPredicate? = .allSamples, sortDescriptors: [NSSortDescriptor] = [
^
.../.pub-cache/hosted/pub.dartlang.org/health_kit_reporter-2.0.3/ios/Classes/Extensions+SwiftHealthKitReporterPlugin.swift:577:18: error: missing argument for parameter 'resultsHandler' in call
}
^
resultsHandler: <#ElectrocardiogramResultsHandler#>
HealthKitReporter.HealthKitReader:28:17: note: 'electrocardiogramQuery(predicate:sortDescriptors:limit:resultsHandler:)' declared here
public func electrocardiogramQuery(predicate: NSPredicate? = .allSamples, sortDescriptors: [NSSortDescriptor] = [
^
.../.pub-cache/hosted/pub.dartlang.org/health_kit_reporter-2.0.3/ios/Classes/Extensions+SwiftHealthKitReporterPlugin.swift:626:45: warning: 'sampleQuery(type:predicate:sortDescriptors:limit:resultsHandler:)' was deprecated in iOS 11: Use special functions for fetching
Quantity/Category/Workout samples. For Quantity Samples will return with SI units
let query = try reporter.reader.sampleQuery(
^
.../.pub-cache/hosted/pub.dartlang.org/health_kit_reporter-2.0.3/ios/Classes/Extensions+SwiftHealthKitReporterPlugin.swift:846:87: warning: string interpolation produces a debug description for an optional value; did you mean to make this explicit?
message: "Error in json encoding of workout routes: (routes)",
^~~~~~
.../.pub-cache/hosted/pub.dartlang.org/health_kit_reporter-2.0.3/ios/Classes/Extensions+SwiftHealthKitReporterPlugin.swift:846:87: note: use 'String(describing:)' to silence this warning
message: "Error in json encoding of workout routes: (routes)",
^~~~~~
String(describing: )
.../.pub-cache/hosted/pub.dartlang.org/health_kit_reporter-2.0.3/ios/Classes/Extensions+SwiftHealthKitReporterPlugin.swift:846:87: note: provide a default value to avoid this warning
message: "Error in json encoding of workout routes: (routes)",
^~~~~~
?? <#default value#>

-- END --

Desktop (please complete the following information):
flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.10.5, on macOS 12.3.1 21E258 darwin-arm, locale de-DE)
[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 13.3.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.1)
[✓] VS Code (version 1.66.2)
[✓] Connected device (3 available)
[✓] HTTP Host Availability

• No issues found!

I need know if workout is outdoor or indoor

Is your feature request related to a problem? Please describe.
I need know if workout is outdoor or indoor

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
i need paint map if is outdoor

Additional context

ECG support?

Are you designing to push an update that will support the Electrocardiogram (ECG) in the near future?

Thanks

InvalidValueException with swimBikeRun activities

Describe the bug

the swimBikeRun WorkoutActivityType is missing, resulting in an InvalidValueException. This breaks HealthKitReporter.workoutQuery() with no way to work around the issue.

To Reproduce
Record a swimikeRun activity and try to import it with workoutQuery().

Expected behavior
I expect workoutQuery() to return the workout. We will always have unknown workout activity types because Apple keeps adding them. In this case it would be OK to have an "unknown" type returned.

Screenshots

Problem is this line in workout_activity_type.dart:

  default:
    throw InvalidValueException('Unknown value: $value');

Calling `statisticsQuery` for `QuantityType.restingHeartRate` is never returning (future never completes).

Describe the bug
Calling statisticsQuery for QuantityType.restingHeartRate is never returning (future never completes).

To Reproduce
Steps to reproduce the behavior:

final QuantityType quantityType = QuantityType.restingHeartRate;
final Predicate predicate = Predicate(dateStart, dateEnd);
final List<PreferredUnit> preferredUnit = await HealthKitReporter.preferredUnits([quantityType]);

print('BEFORE'); // Does print

final Statistics statistics = await HealthKitReporter.statisticsQuery(
  quantityType,
  preferredUnit.first.unit,
  predicate,
);

print('AFTER'); // Never prints

NOTE: To my knowledge, I don't have any restingHeartRate data in my Health Kit data.

Expected behavior
The future should complete, returning the data, and 'AFTER' would print.

Desktop (please complete the following information):

  • OS: macOS 12.5.1
  • Flutter version: Channel stable, 3.3.1

Smartphone (please complete the following information):

  • Device: iPhone8
  • OS: iOS 15.1 19B74

Additional context
To my knowledge, I don't have any restingHeartRate data in my Health Kit data (and there is no way I know of to add some manually).

Flutter throwing categoryQuery identifier error

flutter: PlatformException(CategoryQuery, Error in categoryQuery for identifier: HKCategoryTypeIdentifierSleepAnalysis, Optional(Error Domain=com.apple.healthkit Code=5 "Authorization not determined" UserInfo={NSLocalizedDescription=Authorization not determined}), null)

final readTypes = [
CategoryType.sleepAnalysis.identifier
];

iOS 16.0

Is there a way to pull a list of workouts?

I'm trying to pull a list of workouts from health kit and reading Apple's docs it appears it needs the identifier of either HKWorkoutType or HKWorkoutTypeIdentifier I may be going about this the wrong way but when I added HKWorkoutTypeIdentifier to my list for requesting read permissions there is a toggle for workouts on the health kit pop up in app, but then when I try to read the data from workouts I get the following error message:

Unhandled Exception: PlatformException(<health_kit_reporter.SwiftHealthKitReporterPlugin: 0x2814d8870>, Error in parsing quantity type, Identifier unknown: HKWorkoutTypeIdentifier, null)

Essentially I use await HealthKitReporter.requestAuthorization(readTypes, []); where readTypes are the identifiers I want to use (heart rate, energy, workouts, ect.) to read from. I pass in an empty list for write types because I'm not interested in writing only reading. Then the Quantity types related to readTypes and use it in:

final preferredUnits = await HealthKitReporter.preferredUnits(types);
        for (var preferredUnit in preferredUnits) {
              logger.e('preferredUnit: ${preferredUnit.identifier}');

              final type = QuantityTypeFactory.from( preferredUnit.identifier );

              final quantities = await HealthKitReporter.quantityQuery(type, preferredUnit.unit,  _predicate );

Does this code seem correct and I'm just using the wrong identifiers?

Is there already a built in way to get workouts saved in health kit? Am I going about it the right way to possibly implement this? Is this not currently possible?

Hard Crash when addQuantity is used.

Describe the bug
Using the await HealthKitReporter.addQuantity function causes the app to hard crash.

To Reproduce

final preferredUnits = await HealthKitReporter.preferredUnits(
          [
            QuantityType.activeEnergyBurned,
            QuantityType.stepCount,
            QuantityType.distanceCycling
          ],
        );

final calorieUnit = preferredUnits.first;
final distanceUnit = preferredUnits.last;

final workoutHarmonized = WorkoutHarmonized(
          WorkoutActivityType.cycling,
          200,
          calorieUnit.unit,
          1,
          distanceUnit.unit,
          null,
          '',
          null,
          '',
          null,
        );

final workout = Workout(
          '',
          '',
          DateTime.now()
              .subtract(const Duration(seconds: 60))
              .millisecondsSinceEpoch,
          DateTime.now().millisecondsSinceEpoch,
          null,
          sourceRevision,
          workoutHarmonized,
          workout.duration,
          [],
        );

await HealthKitReporter.save(workout);

final energySample = Quantity(
          '',
          QuantityType.activeEnergyBurned.identifier,
          DateTime.now()
              .subtract(const Duration(seconds: 30))
              .millisecondsSinceEpoch,
          DateTime.now().millisecondsSinceEpoch,
          null,
          sourceRevision,
          QuantityHarmonized(
            100,
            calorieUnit.unit,
            null,
          ),
        );

await HealthKitReporter.save(energySample); //Works, but does not fill the rings if an Apple Watch is paired.

// Need this to fill the workout rings 
await HealthKitReporter.addQuantity([energySample], workout); // Crashes the app

Error

*** Terminating app due to uncaught exception '_HKObjectValidationFailureException', reason: 'Type HKSample can not have endDate of NSDate.distantFuture'
*** First throw call stack:
(0x1d124ce38 0x1ca3e78d8 0x1d133cc28 0x1e6b5f6ec 0x1e6b5f4b8 0x1e6b5f3a8 0x1e6b61d7c 0x1016f8f04 0x1016f8b94 0x1016db2c8 0x1cb0348dc 0x1016db0a4 0x101926e98 0x10191d114 0x101927c98 0x105244b14 0x104d2fa8c 0x1d8863460 0x1d8864f88 0x1d88737f4 0x1d8873444 0x1d12dd6c8 0x1d12bf02c 0x1d12c3eb0 0x20b4b9368 0x1d37b9668 0x1d37b92cc 0x100d5e25c 0x1efbbc960)
libc++abi: terminating with uncaught exception of type NSException
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
    frame #0: 0x000000020ed67674 libsystem_kernel.dylib`__pthread_kill + 8
libsystem_kernel.dylib`:
->  0x20ed67674 <+8>:  b.lo   0x20ed67694               ; <+40>
    0x20ed67678 <+12>: pacibsp
    0x20ed6767c <+16>: stp    x29, x30, [sp, #-0x10]!
    0x20ed67680 <+20>: mov    x29, sp
Target 0: (Runner) stopped.
Lost connection to device.

Swift Equivalent

private let healthStore = HKHealthStore()

let workout = HKWorkout(
        activityType: .cycling,
        start: Date.now,
        end: Date().withAddedMinutes(minutes: 1),
        workoutEvents: [],
        totalEnergyBurned: HKQuantity(unit: .largeCalorie(), doubleValue: 200),
        totalDistance: HKQuantity(unit: .mile(), doubleValue: 1),
        metadata: nil
      )

 healthStore.save(workout) ... //Works

let energySample  = HKQuantitySample(
      type: HKObjectType.quantityType(forIdentifier: .activeEnergyBurned)!,
      quantity: HKQuantity(unit: .largeCalorie(), doubleValue: 100),
      start: Date.now,
      end: Date.now.withAddedMinutes(minutes: 0.5))
)

healthStore.add([energySample], to: workout) // Works even with future end date.

No new data on subsequent queries

Describe the bug
The fresh and up-to-date data is returned only on the very first query. The subsequent queries return the subset of the very first query: as the time window moves forward the less and less data is left in the returned list.

To Reproduce
Steps to reproduce the behavior:

final prefUnits = await HealthKitReporter.preferredUnits([QuantityType.heartRate]);
final hrUnits = prefUnits.first.unit;

// make multiple calls with some time intervals to reproduce
final now = DateTime.now();
final hbQuery = await HealthKitReporter.quantityQuery(QuantityType.heartRate, hrUnits, Predicate(now.subtract(Duration(seconds: 120)), now));
print(hbQuery.map((e) => e.harmonized.value));

Eventually the list becomes empty.

Expected behavior
Get up-to-date data on every query (as it happens on the very first query).

Desktop (please complete the following information):

  • OS: iOS

Smartphone (please complete the following information):

  • Device: iPhone11
  • OS: iOS15.4.1

Adding Blood Pressure Correlation Crashes

I am trying to write Blood Pressure value both Systolic and Diastolic as a Correlation but the app crashes.

    final sysVal = QuantityHarmonized(120, 'mmHg', null);
    final diaVal = QuantityHarmonized(89, 'mmHg', null);

    final sys = Quantity(
        'testSysUUID234',
        QuantityType.bloodPressureSystolic.identifier,
        minuteAgo.millisecondsSinceEpoch,
        now.millisecondsSinceEpoch,
        device,
        sourceRevision,
        sysVal);
    final dia = Quantity(
        'testDiaUUID456',
        QuantityType.bloodPressureDiastolic.identifier,
        minuteAgo.millisecondsSinceEpoch,
        now.millisecondsSinceEpoch,
        device,
        sourceRevision,
        diaVal);
        final bpVal = CorrelationHarmonized([sys, dia], [], null);
        final bp = Correlation(
                         'testSysUUID456',
                         CorrelationType.bloodPressure.identifier,
                         minuteAgo.millisecondsSinceEpoch,
                         now.millisecondsSinceEpoch,
                         device,
                         sourceRevision,
                        bpVal);
     final savedBP = await HealthKitReporter.save(bp);

Here is my Code. Is there something wrong or the plugin doesn't support adding blood pressure yet?

I don't want to add the as separate Quantity because then it won't show up in the health app

Can someone help me please?

Samples are broken

Samples from the docs.

final now = DateTime.now();
      final minuteAgo = now.add(Duration(minutes: -1));
      final device = Device('FlutterTracker', 'kvs', 'T-800', '3', '3.0', '1.1.1', 'kvs.f.t', '444-888-555');
      final source = Source('maApp', 'com.kvs.health_kit_reporter_example');
      final operatingSystem = OperatingSystem(1, 2, 3);
      final sourceRevision = SourceRevision(source, '5', 'fit', '4', operatingSystem);
      final harmonized = QuantityHarmonized(100, 'count', null);
      final steps = Quantity(
        QuantityType.activeEnergyBurned.identifier,
        minuteAgo.millisecondsSinceEpoch,
        now.millisecondsSinceEpoch,
        device,
        sourceRevision,
        harmonized,
      );
      print(steps.map);

Screenshot 2021-05-15 at 13 00 43

Identifier unknown error

Thanks so much for the awesome package!

I'd hugely appreciate your help with this please.

I am getting the error PlatformException(<health_kit_reporter.SwiftHealthKitReporterPlugin: 0x283a82330>, Error in parsing quantity type, Identifier unknown: HKQuantityTypeIdentifierAppleSleepingWristTemperature, null) when I try to run the code:

// Authorise usage of all data
final List<String> readTypes = <String>[];
readTypes.addAll(QuantityType.values.map((e) => e.identifier));
final writeTypes = <String>[];
authorized = await HealthKitReporter.requestAuthorization(readTypes, writeTypes);

// Prepare to get data
List<QuantityType> typesToGet = [];
for (final QuantityType e in QuantityType.values) {
   final QuantityType? type = QuantityTypeFactory.tryFrom(e.identifier);
   if (type != null) {
      typesToGet.add(type);
   }
}
List<PreferredUnit> preferredUnits = await HealthKitReporter.preferredUnits(typesToGet);

If I manually remove this value from the list before running the final preferredUnits(typesToGet) line, I then get the error with other types such as runningStrideLength, runningVerticalOscillation and runningGroundContactTime.

I wonder if perhaps it is because I don't have an Apple Watch so don't have any data from that - if so though, some guidance on how to handle this would be much appreciated.

Thank you!

Deprecated usage warning

When building a flutter app which uses this plugin, a deprecation warning is issued:

/Users/xxx/.pub-cache/hosted/pub.dartlang.org/health_kit_reporter-2.1.0/ios/Classes/Extensions+SwiftHealthKitReporterPlugin.swift:626:45: warning: 'sampleQuery(type:predicate:sortDescriptors:limit:resultsHandler:)' was deprecated in iOS 11: Use special functions for fetching Quantity/Category/Workout samples. For Quantity Samples will return with SI units
                let query = try reporter.reader.sampleQuery(

I do not know much about iOS development so I cannot comment on it more than just pasting the warning here.

request isAuthorizedToRead

I'd like to check is authorized to read.

isAuthorizedToWrite is exists, but not for read.

before request to read access, check is authorized to read.

can you help me?

Support retrieving voltage measurements for ECG records

Is your feature request related to a problem? Please describe.
There is no option to get a voltage measurement for ECG records.

Describe the solution you'd like
Modify the Electrocardiogram class to include voltage measurement samples.

Describe alternatives you've considered
Add additional platform method to query voltage measurement samples.

Additional context
At the moment, the library provides a way of retrieving ECG records from Apple Health Kit which is great but it does not allow to get the underlying voltage measurements. Therefore, the usage of this feature is limited.

Crash on iPhone 5S ios 12

dyld: Symbol not found: _OBJC_CLASS_$_HKElectrocardiogramQuery Referenced from: /private/var/containers/Bundle/Application/943403A9-5FAB-401D-B053-3DA33B6223C0/Runner.app/Frameworks/HealthKitReporter.framework/HealthKitReporter Expected in: /System/Library/Frameworks/HealthKit.framework/HealthKit in /private/var/containers/Bundle/Application/943403A9-5FAB-401D-B053-3DA33B6223C0/Runner.app/Frameworks/HealthKitReporter.framework/HealthKitReporter (lldb)

I got an error when i pulled example from your repository on the master branch.
Could you fix this issue?

Data Relationship

HI, Is there a way to relate the data as a while for example which workout route for this workout?

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.