health_kit_reporter icon indicating copy to clipboard operation
health_kit_reporter copied to clipboard

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

Open umangsh opened this issue 2 years ago • 3 comments

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.

umangsh avatar Jun 22 '22 23:06 umangsh

HKMetadataKeySyncIdentifier and HKMetadataKeySyncVersion is relevant, setting them in QuantityHarmonized.metadata is ignored

    QuantityHarmonized(nutrient.amount!, nutrient.unit!, <String, dynamic>{
      'HKMetadataKeySyncIdentifier':
          '${DateFormat(constants.DATE_FORMAT).format(date)}-${nutrient.id}',
      'HKMetadataKeySyncVersion': DateTime.now().millisecondsSinceEpoch,
    }),

umangsh avatar Jun 23 '22 10:06 umangsh

I'm using iphone 13 mini, ios 15.5. Unable to set HKMetadataKeySyncVersion as any type in Quantity.harmonized['metadata']

  1. HKMetadataKeySyncVersion can't be passed in as a String, exception in App Delegate.

QuantityHarmonized(100, 'kcal', <String, String>{ 'HKMetadataKeySyncVersion': '${DateTime.now().millisecondsSinceEpoch}', 'HKMetadataKeySyncIdentifier': // ignore: lines_longer_than_80_chars '${constants.appTitle}-${DateFormat(constants.DATE_FORMAT).format(date)}-${nutrient.id}', }),

throws @objc class AppDelegate: FlutterAppDelegate { Thread 1: "Invalid class __NSCFString for metadata key: HKMetadataKeySyncVersion. Expected NSNumber."

  1. HKMetadataKeySyncVersion is dropped when passed as int / double, the cast from [String: Any] to [String: String] fails silently at https://github.com/VictorKachalov/HealthKitReporter/blob/6bae58ded9a089dd870e6db7480ace35775a2a85/Sources/Model/Payload/Quantity.swift#L190.

QuantityHarmonized(100, 'kcal', <String, dynamic>{ 'HKMetadataKeySyncVersion': DateTime.now().millisecondsSinceEpoch, 'HKMetadataKeySyncIdentifier': // ignore: lines_longer_than_80_chars '${constants.appTitle}-${DateFormat(constants.DATE_FORMAT).format(date)}-${nutrient.id}', }),

Debug output in Quantity.swift:

dictionary["metadata"] : Optional({ HKMetadataKeySyncIdentifier = "FAMNOM-2022-06-22-1092"; HKMetadataKeySyncVersion = 1656022275836; })

metadata: nil

umangsh avatar Jun 23 '22 22:06 umangsh

Hi @umangsh

Please check new 2.1.0 version (be sure that updated HealthKitReporter to 2.0.0 is used)

kvs-coder avatar Oct 30 '22 09:10 kvs-coder