Closed nohli closed 3 years ago
Hi @nohli
As I undestood, you did not experience this behaviour during development/debuging?
What is your project minimum support target? (This plugin requires iOS 12)
Some of the types like HKElectrocardiogramm or HKSeriesType will require higher iOS version - 14.0 and 13.0 respectively. So from crash reports I could assume that it could be that these types maybe were used in devices with iOS 12 and lower but the whole testing was executed only for devices with iOS 14+. Flutter unfortunately will not warn you about the availability of the types for different iOS systems...
Could you please also tell me as well, what 'flutter doctor' says?
@VictorKachalov it happens on all iOS versions. Does the 'Last Exception Backtrace' in the first screenshot help?
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel beta, 1.26.0-17.3.pre, on macOS 11.2.1 20D74 darwin-x64,
locale en-US)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
[✓] Xcode - develop for iOS and macOS
[✓] Android Studio (version 4.1)
[✓] VS Code (version 1.53.1)
[✓] Connected device (1 available)
! Error: Achims iPhone is not connected. Xcode will continue when Achims
iPhone is connected. (code -13)
! Error: Achims iPhone is not connected. Xcode will continue when Achims
iPhone is connected. (code -13)
• No issues found!`
[✓] Flutter (Channel beta, 1.26.0-17.3.pre, on macOS 11.2.1 20D74 darwin-x64, locale en-US)
I see that the channel is "beta". I would advise to try to make a build on "stable" version, please see https://github.com/flutter/flutter/wiki/Flutter-build-release-channels
Could you please try this?
My apps are already null safe, I can't go back to stable. Also, the beta is very close to be released as stable...
The crash appeared with this package - does the error message give any hint (like the SwiftHealthKitReporterPlugin.requestAuthorization
and above parts), or can I provide any more details?
I can share the code, maybe there is something wrong (maybe if you have time, you could have a quick look). During debugging and on my device in production it works fine. Most of the device arguments and Category.uuid are set to null - does this make a difference? If all possible arguments are passed, there is unnecessary data like iOS version etc. saved in Apple Health.
import 'dart:io';
import 'package:device_info/device_info.dart';
import 'package:flutter/material.dart';
import 'package:health_kit_reporter/health_kit_reporter.dart';
import 'package:health_kit_reporter/model/payload/category.dart';
import 'package:health_kit_reporter/model/payload/device.dart';
import 'package:health_kit_reporter/model/payload/source.dart';
import 'package:health_kit_reporter/model/payload/source_revision.dart';
import 'package:health_kit_reporter/model/type/category_type.dart';
import 'package:package_info/package_info.dart';
Future<void> saveMindfulMinutes() async {
if (await _isiPhone) {
if (await _requestAuthorization()) {
await _writeMindfulMinutes();
}
}
}
Future<bool> get _isiPhone async {
try {
final bool isiPhone = Platform.isIOS &&
(await DeviceInfoPlugin().iosInfo).model.contains('iPhone');
return isiPhone;
} catch (error) {
debugPrint('_isiPhone: ${error.toString()}');
}
return false;
}
Future<bool> _requestAuthorization() async {
try {
final List<String> readTypes = <String>[];
final List<String> writeTypes = <String>[
CategoryType.mindfulSession.identifier,
];
final bool isRequested =
await HealthKitReporter.requestAuthorization(readTypes, writeTypes);
return isRequested;
} catch (error) {
debugPrint('_requestAuthorization(): ${error.toString()}');
}
return false;
}
Future<void> _writeMindfulMinutes() async {
try {
final bool canWrite = await HealthKitReporter.isAuthorizedToWrite(
CategoryType.mindfulSession.identifier);
if (canWrite) {
final IosDeviceInfo deviceInfo = await DeviceInfoPlugin().iosInfo;
final DateTime endTime = DateTime.now();
final DateTime startTime = endTime.subtract(const Duration(minutes: 5));
final Device device =
Device(deviceInfo.name, null, null, null, null, null, null, null);
const Source source = Source('Breathe', 'com.achimsapps.breathe');
final List<String> osVersion = deviceInfo.systemVersion.split('.');
final OperatingSystem operatingSystem = OperatingSystem(
osVersion.isNotEmpty ? int.tryParse(osVersion[0]) ?? 14 : 14,
osVersion.length > 1 ? int.tryParse(osVersion[1]) ?? 0 : 0,
osVersion.length > 2 ? int.tryParse(osVersion[2]) ?? 0 : 0,
);
final String appVersion = (await PackageInfo.fromPlatform()).version;
final SourceRevision sourceRevision = SourceRevision(
source,
appVersion,
deviceInfo.utsname.machine,
deviceInfo.systemVersion,
operatingSystem,
);
const CategoryHarmonized harmonized = CategoryHarmonized(
0,
'Breath Meditation',
<String, dynamic>{'': ''},
);
final Category mindfulMinutes = Category(
null,
CategoryType.mindfulSession.identifier,
startTime.millisecondsSinceEpoch,
endTime.millisecondsSinceEpoch,
device,
sourceRevision,
harmonized,
);
// debugPrint(mindfulMinutes.map.toString());
HealthKitReporter.save(mindfulMinutes);
}
} catch (error) {
debugPrint('_writeMindfulMinutes(): ${error.toString()}');
}
}
Hi @nohli
I have investigated your code and haven't find anything wrong. I need to try to reproduce your error in order to understand what causes the issue. Because it is currently unclear why it crashes during authorization
SwiftHealthKitReporterPlugin.requestAuthorization
@VictorKachalov I also can't reproduce the crash on the simulator...the exception stacktrace always looks the same:
Last Exception Backtrace:
0 CoreFoundation __exceptionPreprocess + 216 (NSException.m:199)
1 libobjc.A.dylib objc_exception_throw + 56 (objc-exception.mm:565)
2 CoreFoundation +[NSException raise:format:arguments:] + 96 (NSException.m:146)
3 Foundation -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 128 (NSException.m:231)
4 Flutter -[FlutterStandardMethodCodec encodeErrorEnvelope:] + 196 (FlutterStandardCodec.mm:110)
5 Flutter __45-[FlutterMethodChannel setMethodCallHandler:]_block_invoke_2 + 136 (FlutterChannels.mm:0)
6 health_kit_reporter thunk for @escaping @callee_unowned @convention(block) (@unowned Swift.AnyObject?) -> () + 92 (<compiler-generated>:0)
7 health_kit_reporter closure #1 in SwiftHealthKitReporterPlugin.requestAuthorization(reporter:arguments:result:) + 320
8 health_kit_reporter partial apply for closure #1 in SwiftHealthKitReporterPlugin.requestAuthorization(reporter:arguments:result:) + 72 (<compiler-generated>:0)
9 HealthKitReporter thunk for @escaping @callee_guaranteed (@unowned Bool, @guaranteed Error?) -> () + 56 (<compiler-generated>:0)
10 HealthKit __84-[HKHealthStore requestAuthorizationToShareTypes:readTypes:shouldPrompt:completion:]_block_invoke + 368 (HKHealthStore.m:688)
Describe the bug Reported crashes on iOS production devices.
Screenshots
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.