react-native-health
react-native-health copied to clipboard
Fatal Exception: NSInvalidArgumentException when retrieving health data
Thanks for creating this library.
Describe the bug After migrating an app from rn-apple-healthkit to react-native-health there have been a large number of crashes reported in Crashlytics. The crash seems to occur when health data is received. However I have been unable to reproduce this error myself on an iPhone simulator or a physical device.
This is the error:
Fatal Exception: NSInvalidArgumentException ***[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[1]
Which seems to happen inside the completionHandler
in the method fetchSumOfSamplesOnDayForType
. This method is called from many other methods that retrieve various types of health data such as getStepCountOnDay
.
Where one of these values in *response
is nil, which due to the if-statement should be startDate or endDate. And buildISO8601StringFromDate
can return nil if there is an error.
Inside the completionHandler:
if (!value && value != 0) {
callback(@[RCTJSErrorFromNSError(error)]);
return;
}
NSDictionary *response = @{
@"value" : @(value),
@"startDate" : [RCTAppleHealthKit buildISO8601StringFromDate:startDate],
@"endDate" : [RCTAppleHealthKit buildISO8601StringFromDate:endDate],
};
callback(@[[NSNull null], response]);
Do you have an idea what might cause this error?
These are the permissions that I use:
const appleHealthKitOptions = {
permissions: {
read: [
AppleHealthKit.Constants.Permissions.StepCount,
AppleHealthKit.Constants.Permissions.SleepAnalysis,
AppleHealthKit.Constants.Permissions.HeartRate,
AppleHealthKit.Constants.Permissions.DistanceCycling
],
write: []
}
};
And these AppleHealthKit methods:
AppleHealthKit.getDailyStepCountSamples
AppleHealthKit.getDailyDistanceCyclingSamples
AppleHealthKit.getSleepSamples
AppleHealthKit.getHeartRateSamples
To Reproduce Unfortunately I cannot reproduce it myself.
Smartphone (please complete the following information):
- Device: It happens on many different types of iPhones
- OS: Both iOS 13 and 14
- Version 1.7.0
Thanks a lot.
Hey @rnbrk, really weird, I could not reproduce this as well, please share more information if you have
Also running into this. Seems to only be when fetching StepCount
*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[1]
@macelai @lucaspbordignon We are also having the same exact issue and not able to reproduce it. But this can potentially be fixed by just having default values for the cases when start or end date are null in the buildISO8601StringFromDate assignment right? Since this is in the method fetchSumOfSamplesOnDayForType, maybe using the "day" as the start and end date? Wdyt?
We are facing the same issue, any news on this? We are also using Version 1.7 so is there a chance that this is fixed in the latest release?
@lucaspbordignon I am using 1.12 version of this library and my users get the same crashes every day. I don't understand the reason. I can't reproduce this bug but see them on bugsnag. Any solution, advice? Maybe these bugs are related to iOS 15 (and later) updates? @c-goettert @rnbrk Did you find any working solution to prevent this bug?
@gigby unfortunatley no, we couldn't find a solution / reason for this bug yet..
@c-goettert I found out. It happens on iOS 15.2 or later due to prewarming feature. You can easily awoid these bugs if you don't call Healthkit from a background app state. No background calls no these bugs
@gigby thanks for letting me know, we indeed use background calls to fetch health data. We'll deactivate those and see if this will solve the issue.
@gigby unfortunatly we still see this issue after disabling our background task. How did you make sure that Healthkit is not called from a background state? Did you use AppState-Events from React Native or did you just remove any existing Background Observers? Or did you remove Background-Fetch Entitlement from your app completely?
@c-goettert I used AppState events from RN. Very simple. And now I don't see these errors in Bugsnag although earlier I observed hundreds of them per 1 week an example
export async function initHealthkit(perms: Array<string> = []) {
const healthKitOptions = {
permissions: {
read: (perms && perms.length) ? perms : ALL_REQUIRED_IOS_HEALTH_PERMISSIONS,
},
} as HealthKitPermissions;
let result = false;
// calls to apple healthkit on the background state may cause crashes on ios 15 and later
const isBackground = AppStateListener.isAppInBackground();
if (!isBackground) {
result = await new Promise<boolean>((res) => {
AppleHealthKit.initHealthKit(healthKitOptions, (err, results) => {
if (err) {
// OMG! error here is string!
eNotifier(new Error(err));
res(false);
}
res(!!results);
});
});
}
return result;
}
@c-goettert And somewhere in code I use previous func to get some data like this:
export async function getSleepHours(timeFrom?: number | Date, timeTo: number | Date = Date.now()) {
const result: Array<TSleepEventRawIos> = [];
const isGranted = await initHealthkit([AppleHealthKit.Constants.Permissions.SleepAnalysis]);
if (isGranted) {
let timeStart;
// code here
}
@c-goettert Were you able to look into the thing mentioned above by @gigby?
I'm getting this same issue but not on every phone that runs this code. I'm not sure if it's something related to initializing apple health after checking if the app isn't in the background as our code runs when the app is open.
Any update on this bug? We are receiving this error mostly on iOS 15, and few in iOS 14. We do not intentionally call any method from background state.
Having the same issue
+1 Looks like mostly users on iOS 15
We are also still facing this issue. For the next release I will try @gigby's solution to check if the app is in foreground before interacting with HealthKit.
We're getting the same error/crash when calling AppleHealthKit.getStepCount
. Did anyone manage to find a fix/workaround?
UPDATE
startDate
and endDate
are nil
. These values shouldn't be passed along as arguments on the callback.
https://github.com/agencyenterprise/react-native-health/blob/38603c64134fbf32cef6d4df453e2cc06849bf07/RCTAppleHealthKit/RCTAppleHealthKit%2BMethods_Fitness.m#L37
I'm having this issue, did anybody figure it out?
Hey guys, I plan to take a deep look into this crash in a few days. If you have any additional information it would be very welcome, thanks
Thank you for looking into this, we are still regularly getting lots of these in our error reporting. For us I can say that it only seems to occur when the app runs in background mode. It might be somehow related to the iOS rights system, e.g. that values may not be accessed while the phone is locked or similar. This would fit the error messages we get from the lib before the exception:
Error while trying to get blood pressure samples from healthkit: , error getting blood pressure samples:Error Domain=com.apple.healthkit Code=6 "Protected health data is inaccessible" UserInfo={NSLocalizedDescription=Protected health data is inaccessible}
This is what an example stack-trace looks like (probably not very helpful):
libobjc.A.dylib 0x000000019a6c4f54 objc_exception_throw + 60
CoreFoundation 0x0000000182159530 B2D21CFD-378C-36D5-BAF7-3F70599CFEFC + 1713456
CoreFoundation 0x00000001821646ac B2D21CFD-378C-36D5-BAF7-3F70599CFEFC + 1758892
CoreFoundation 0x000000018200d464 B2D21CFD-378C-36D5-BAF7-3F70599CFEFC + 353380
CoreFoundation 0x000000018202be0c B2D21CFD-378C-36D5-BAF7-3F70599CFEFC + 478732
App 0x00000001022e4744 _ZN5folly6detail15str_to_integralIxEENS_8ExpectedIT_NS_14ConversionCodeEEEPNS_5RangeIPKcEE + 161376
App 0x00000001022f1eb8 _ZN5folly6detail15str_to_integralIxEENS_8ExpectedIT_NS_14ConversionCodeEEEPNS_5RangeIPKcEE + 216532
libdispatch.dylib 0x0000000181cc0914 A5CBAAB3-E389-3548-BAAC-FAB18411B94A + 10516
libdispatch.dylib 0x0000000181cc2660 A5CBAAB3-E389-3548-BAAC-FAB18411B94A + 18016
libdispatch.dylib 0x0000000181cc9de4 A5CBAAB3-E389-3548-BAAC-FAB18411B94A + 48612
libdispatch.dylib 0x0000000181cca98c A5CBAAB3-E389-3548-BAAC-FAB18411B94A + 51596
libdispatch.dylib 0x0000000181cd51a8 A5CBAAB3-E389-3548-BAAC-FAB18411B94A + 94632
libsystem_pthread.dylib 0x00000001f23620f4 _pthread_wqthread + 288
libsystem_pthread.dylib 0x00000001f2361e94 start_wqthread + 8```
Seems related to #97. Got this same message Fatal Exception: NSInvalidArgumentException ***[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[1]
while testing #97.
Both issues are related to HealthKit denying access to data. I'm still investigating and keep you guys posted.
Fixed by #280
I fixed #97 and I believe it will fix this issue too. Please update to v1.13.6 and let me know if the issue persists.