@kingstinct/react-native-healthkit 14.1.0 → 16.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/README.md +37 -3
  2. package/ReactNativeHealthkit.podspec +11 -7
  3. package/app.plugin.js +33 -94
  4. package/app.plugin.ts +29 -104
  5. package/ios/CategoryTypeModule.swift +1 -0
  6. package/ios/CharacteristicTypeModule.swift +7 -6
  7. package/ios/Constants.swift +9 -10
  8. package/ios/CoreModule.swift +77 -42
  9. package/ios/CorrelationTypeModule.swift +3 -2
  10. package/ios/ElectrocardiogramModule.swift +4 -3
  11. package/ios/HeartbeatSeriesModule.swift +4 -3
  12. package/ios/Helpers.swift +11 -216
  13. package/ios/MedicationModule.swift +9 -8
  14. package/ios/MemoryEstimation.swift +84 -0
  15. package/ios/PredicateHelpers.swift +16 -86
  16. package/ios/QuantityTypeModule.swift +37 -28
  17. package/ios/Serializers.swift +34 -70
  18. package/ios/SourceProxy.swift +15 -5
  19. package/ios/StateOfMindModule.swift +3 -2
  20. package/ios/WorkoutProxy.swift +31 -13
  21. package/ios/WorkoutsModule.swift +4 -3
  22. package/lib/commonjs/generated/healthkit.generated.js +15 -3
  23. package/lib/commonjs/healthkit.ios.js +6 -2
  24. package/lib/commonjs/healthkit.js +24 -79
  25. package/lib/commonjs/types/Auth.js +3 -18
  26. package/lib/commonjs/types/Background.js +2 -10
  27. package/lib/commonjs/types/QueryOptions.js +2 -17
  28. package/lib/module/generated/healthkit.generated.js +14 -2
  29. package/lib/module/healthkit.ios.js +4 -0
  30. package/lib/module/healthkit.js +22 -77
  31. package/lib/module/types/Auth.js +1 -18
  32. package/lib/module/types/Background.js +1 -10
  33. package/lib/module/types/QueryOptions.js +1 -17
  34. package/lib/typescript/generated/healthkit.generated.d.ts +20 -7
  35. package/lib/typescript/healthkit.d.ts +4 -2
  36. package/lib/typescript/healthkit.ios.d.ts +13 -9
  37. package/lib/typescript/specs/CoreModule.nitro.d.ts +22 -4
  38. package/lib/typescript/specs/SourceProxy.nitro.d.ts +2 -5
  39. package/lib/typescript/types/Auth.d.ts +1 -16
  40. package/lib/typescript/types/Background.d.ts +1 -9
  41. package/lib/typescript/types/Device.d.ts +1 -13
  42. package/lib/typescript/types/QuantityType.d.ts +3 -3
  43. package/lib/typescript/types/QueryOptions.d.ts +3 -37
  44. package/lib/typescript/types/Shared.d.ts +2 -25
  45. package/lib/typescript/types/Source.d.ts +1 -10
  46. package/lib/typescript/types/Subscriptions.d.ts +2 -3
  47. package/lib/typescript/types/Units.d.ts +1 -1
  48. package/nitrogen/generated/ios/ReactNativeHealthkit-Swift-Cxx-Bridge.cpp +24 -16
  49. package/nitrogen/generated/ios/ReactNativeHealthkit-Swift-Cxx-Bridge.hpp +91 -12
  50. package/nitrogen/generated/ios/c++/HybridCategoryTypeModuleSpecSwift.hpp +8 -5
  51. package/nitrogen/generated/ios/c++/HybridCoreModuleSpecSwift.hpp +8 -0
  52. package/nitrogen/generated/ios/c++/HybridCorrelationTypeModuleSpecSwift.hpp +8 -5
  53. package/nitrogen/generated/ios/c++/HybridElectrocardiogramModuleSpecSwift.hpp +8 -5
  54. package/nitrogen/generated/ios/c++/HybridHeartbeatSeriesModuleSpecSwift.hpp +8 -5
  55. package/nitrogen/generated/ios/c++/HybridMedicationModuleSpecSwift.hpp +8 -5
  56. package/nitrogen/generated/ios/c++/HybridQuantityTypeModuleSpecSwift.hpp +8 -5
  57. package/nitrogen/generated/ios/c++/HybridStateOfMindModuleSpecSwift.hpp +8 -5
  58. package/nitrogen/generated/ios/c++/HybridWorkoutProxySpecSwift.hpp +3 -4
  59. package/nitrogen/generated/ios/c++/HybridWorkoutsModuleSpecSwift.hpp +6 -3
  60. package/nitrogen/generated/ios/swift/CategorySample.swift +8 -8
  61. package/nitrogen/generated/ios/swift/CategoryTypeIdentifier.swift +8 -0
  62. package/nitrogen/generated/ios/swift/CategoryTypeIdentifierWriteable.swift +8 -0
  63. package/nitrogen/generated/ios/swift/CorrelationSample.swift +8 -8
  64. package/nitrogen/generated/ios/swift/ElectrocardiogramSample.swift +8 -8
  65. package/nitrogen/generated/ios/swift/Func_void_std__unordered_map_std__string__std__chrono__system_clock__time_point_.swift +54 -0
  66. package/nitrogen/generated/ios/swift/HeartbeatSeriesSample.swift +8 -8
  67. package/nitrogen/generated/ios/swift/HybridCoreModuleSpec.swift +1 -0
  68. package/nitrogen/generated/ios/swift/HybridCoreModuleSpec_cxx.swift +25 -0
  69. package/nitrogen/generated/ios/swift/MedicationDoseEvent.swift +8 -8
  70. package/nitrogen/generated/ios/swift/ObjectTypeIdentifier.swift +12 -4
  71. package/nitrogen/generated/ios/swift/QuantitySample.swift +8 -8
  72. package/nitrogen/generated/ios/swift/QuantityTypeIdentifier.swift +4 -4
  73. package/nitrogen/generated/ios/swift/QuantityTypeIdentifierWriteable.swift +4 -4
  74. package/nitrogen/generated/ios/swift/QueryStatisticsResponse.swift +6 -13
  75. package/nitrogen/generated/ios/swift/QueryStatisticsResponseFromSingleSource.swift +4 -11
  76. package/nitrogen/generated/ios/swift/SampleTypeIdentifier.swift +12 -4
  77. package/nitrogen/generated/ios/swift/SampleTypeIdentifierWriteable.swift +12 -4
  78. package/nitrogen/generated/ios/swift/SourceRevision.swift +4 -11
  79. package/nitrogen/generated/ios/swift/StateOfMindSample.swift +8 -8
  80. package/nitrogen/generated/ios/swift/WorkoutActivityType.swift +8 -0
  81. package/nitrogen/generated/shared/c++/CategorySample.hpp +7 -7
  82. package/nitrogen/generated/shared/c++/CategoryTypeIdentifier.hpp +67 -59
  83. package/nitrogen/generated/shared/c++/CategoryTypeIdentifierWriteable.hpp +67 -59
  84. package/nitrogen/generated/shared/c++/CorrelationSample.hpp +7 -7
  85. package/nitrogen/generated/shared/c++/ElectrocardiogramSample.hpp +7 -7
  86. package/nitrogen/generated/shared/c++/HeartbeatSeriesSample.hpp +7 -7
  87. package/nitrogen/generated/shared/c++/HybridCoreModuleSpec.cpp +1 -0
  88. package/nitrogen/generated/shared/c++/HybridCoreModuleSpec.hpp +3 -1
  89. package/nitrogen/generated/shared/c++/MedicationDoseEvent.hpp +7 -7
  90. package/nitrogen/generated/shared/c++/ObjectTypeIdentifier.hpp +206 -198
  91. package/nitrogen/generated/shared/c++/QuantitySample.hpp +7 -7
  92. package/nitrogen/generated/shared/c++/QuantityTypeIdentifier.hpp +73 -73
  93. package/nitrogen/generated/shared/c++/QuantityTypeIdentifierWriteable.hpp +73 -73
  94. package/nitrogen/generated/shared/c++/QueryStatisticsResponse.hpp +8 -9
  95. package/nitrogen/generated/shared/c++/QueryStatisticsResponseFromSingleSource.hpp +8 -9
  96. package/nitrogen/generated/shared/c++/SampleTypeIdentifier.hpp +199 -191
  97. package/nitrogen/generated/shared/c++/SampleTypeIdentifierWriteable.hpp +193 -185
  98. package/nitrogen/generated/shared/c++/SourceRevision.hpp +8 -9
  99. package/nitrogen/generated/shared/c++/StateOfMindSample.hpp +7 -7
  100. package/nitrogen/generated/shared/c++/WorkoutActivityType.hpp +4 -0
  101. package/package.json +8 -3
  102. package/src/generated/healthkit-schema.json +53 -8
  103. package/src/generated/healthkit.generated.ts +22 -6
  104. package/src/healthkit.ios.ts +6 -0
  105. package/src/healthkit.ts +32 -84
  106. package/src/specs/CoreModule.nitro.ts +25 -4
  107. package/src/specs/SourceProxy.nitro.ts +2 -4
  108. package/src/test-setup.ts +1 -0
  109. package/src/type-tests/generated-typing.ts +30 -8
  110. package/src/types/Auth.ts +4 -17
  111. package/src/types/Background.ts +1 -9
  112. package/src/types/Device.ts +1 -13
  113. package/src/types/QuantityType.ts +3 -3
  114. package/src/types/QueryOptions.ts +7 -65
  115. package/src/types/Shared.ts +7 -28
  116. package/src/types/Source.ts +1 -11
  117. package/src/types/Subscriptions.ts +2 -3
  118. package/src/types/Units.ts +1 -1
  119. package/ios/BackgroundDeliveryManager.swift +0 -277
  120. package/ios/Bridge.h +0 -10
  121. package/ios/ExceptionCatcher.h +0 -5
  122. package/ios/ExceptionCatcher.mm +0 -32
  123. package/ios/module.modulemap +0 -5
@@ -1,277 +0,0 @@
1
- import Foundation
2
- import HealthKit
3
- import os.log
4
-
5
- private let bgLog = OSLog(subsystem: "com.kingstinct.healthkit", category: "BackgroundDelivery")
6
-
7
- /// Manages HealthKit background delivery by registering observer queries at app launch,
8
- /// before the JS bridge is available. This is required by Apple — observer queries must
9
- /// be set up in `application(_:didFinishLaunchingWithOptions:)` to receive background
10
- /// delivery callbacks after the app has been terminated.
11
- ///
12
- /// Usage from AppDelegate.swift:
13
- /// BackgroundDeliveryManager.shared.setupBackgroundObservers()
14
- ///
15
- /// The types to observe are persisted in UserDefaults by `configureBackgroundTypes()`
16
- /// called from JS. On subsequent cold launches, the manager reads these and registers
17
- /// observers immediately, queuing any events until JS subscribes via `drainPendingEvents()`.
18
- @objc public class BackgroundDeliveryManager: NSObject {
19
- @objc public static let shared = BackgroundDeliveryManager()
20
-
21
- private let healthStore = HKHealthStore()
22
- private let queue = DispatchQueue(label: "com.kingstinct.healthkit.background", attributes: .concurrent)
23
- private var observerQueries: [String: HKObserverQuery] = [:]
24
- private var pendingEvents: [(typeIdentifier: String, errorMessage: String?)] = []
25
- private var jsCallback: ((String, String?) -> Void)?
26
- // Per-type callbacks, checked before the global `jsCallback` above. Lets
27
- // CoreModule.subscribeToObserverQuery route a JS subscription for a
28
- // background-configured type through this manager's already-running
29
- // HKObserverQuery instead of registering a second, independent one.
30
- private var typeCallbacks: [String: (String, String?) -> Void] = [:]
31
- private var isSetUp = false
32
-
33
- static let typesKey = "com.kingstinct.healthkit.backgroundTypes"
34
- static let frequencyKey = "com.kingstinct.healthkit.backgroundFrequency"
35
-
36
- private override init() {
37
- super.init()
38
- }
39
-
40
- /// Call this from AppDelegate.didFinishLaunchingWithOptions to register observer queries
41
- /// for any previously configured background delivery types.
42
- @objc public func setupBackgroundObservers() {
43
- guard HKHealthStore.isHealthDataAvailable() else { return }
44
-
45
- guard let typeIdentifiers = UserDefaults.standard.stringArray(forKey: BackgroundDeliveryManager.typesKey) else {
46
- return
47
- }
48
-
49
- let frequencyRaw = UserDefaults.standard.integer(forKey: BackgroundDeliveryManager.frequencyKey)
50
- let frequency = HKUpdateFrequency(rawValue: frequencyRaw) ?? .immediate
51
-
52
- registerObservers(typeIdentifiers: typeIdentifiers, frequency: frequency)
53
- }
54
-
55
- /// Persist types and frequency, then register observers for the current session.
56
- /// Called from JS via CoreModule.configureBackgroundTypes().
57
- func configure(typeIdentifiers: [String], frequency: HKUpdateFrequency) {
58
- UserDefaults.standard.set(typeIdentifiers, forKey: BackgroundDeliveryManager.typesKey)
59
- UserDefaults.standard.set(frequency.rawValue, forKey: BackgroundDeliveryManager.frequencyKey)
60
-
61
- // Tear down existing observers before re-registering
62
- tearDown()
63
- registerObservers(typeIdentifiers: typeIdentifiers, frequency: frequency)
64
- }
65
-
66
- /// Subscribe a JS callback. Any events that arrived before JS was ready are flushed immediately.
67
- func setCallback(_ callback: @escaping (String, String?) -> Void) {
68
- queue.sync(flags: .barrier) {
69
- self.jsCallback = callback
70
- let events = self.pendingEvents
71
- self.pendingEvents = []
72
-
73
- for event in events {
74
- callback(event.typeIdentifier, event.errorMessage)
75
- }
76
- }
77
- }
78
-
79
- /// Remove the JS callback (e.g., on teardown).
80
- func removeCallback() {
81
- queue.sync(flags: .barrier) {
82
- self.jsCallback = nil
83
- }
84
- }
85
-
86
- /// Returns any pending events and clears the queue. Used by CoreModule.subscribeToObserverQuery
87
- /// to flush events that arrived before JS subscribed.
88
- func drainPendingEvents() -> [(typeIdentifier: String, errorMessage: String?)] {
89
- return queue.sync(flags: .barrier) {
90
- let events = self.pendingEvents
91
- self.pendingEvents = []
92
- return events
93
- }
94
- }
95
-
96
- /// Subscribe a JS callback for a specific type. Any events for this type
97
- /// that arrived before JS subscribed (e.g. from a background wake, queued
98
- /// in `pendingEvents` above) are flushed immediately.
99
- func setCallback(typeIdentifier: String, callback: @escaping (String, String?) -> Void) {
100
- queue.sync(flags: .barrier) {
101
- self.typeCallbacks[typeIdentifier] = callback
102
- let matching = self.pendingEvents.filter { $0.typeIdentifier == typeIdentifier }
103
- self.pendingEvents.removeAll { $0.typeIdentifier == typeIdentifier }
104
- for event in matching {
105
- callback(typeIdentifier, event.errorMessage)
106
- }
107
- }
108
- }
109
-
110
- /// Remove the per-type JS callback (e.g., on unsubscribe).
111
- func removeCallback(typeIdentifier: String) {
112
- queue.sync(flags: .barrier) {
113
- self.typeCallbacks.removeValue(forKey: typeIdentifier)
114
- }
115
- }
116
-
117
- /// True if `typeIdentifier` has a native HKObserverQuery registered by
118
- /// `registerObservers` — i.e. background delivery is configured for it.
119
- /// CoreModule.subscribeToObserverQuery checks this before deciding whether
120
- /// to reuse this manager's observer or register its own.
121
- func isBackgroundConfigured(typeIdentifier: String) -> Bool {
122
- return queue.sync {
123
- self.observerQueries[typeIdentifier] != nil
124
- }
125
- }
126
-
127
- /// Stop all observer queries and clear state.
128
- func tearDown() {
129
- queue.sync(flags: .barrier) {
130
- for (_, query) in self.observerQueries {
131
- self.healthStore.stop(query)
132
- }
133
- self.observerQueries = [:]
134
- self.typeCallbacks = [:]
135
- self.isSetUp = false
136
- }
137
- }
138
-
139
- /// Clear persisted configuration (disables background delivery on next launch).
140
- func clearConfiguration() {
141
- UserDefaults.standard.removeObject(forKey: BackgroundDeliveryManager.typesKey)
142
- UserDefaults.standard.removeObject(forKey: BackgroundDeliveryManager.frequencyKey)
143
- tearDown()
144
- }
145
-
146
- private func registerObservers(typeIdentifiers: [String], frequency: HKUpdateFrequency) {
147
- queue.sync(flags: .barrier) {
148
- guard !self.isSetUp else { return }
149
- self.isSetUp = true
150
- }
151
-
152
- for typeIdentifier in typeIdentifiers {
153
- guard let sampleType = sampleTypeFromString(typeIdentifier) else {
154
- print("[react-native-healthkit] BackgroundDeliveryManager: skipping unrecognized type \(typeIdentifier)")
155
- continue
156
- }
157
-
158
- // Use nil predicate to catch all samples, including those written while the app was terminated.
159
- // The current subscribeToObserverQuery uses Date.init() which misses data from when the app was dead.
160
- let query = HKObserverQuery(
161
- sampleType: sampleType,
162
- predicate: nil
163
- ) { [weak self] (_: HKObserverQuery, completionHandler: @escaping HKObserverQueryCompletionHandler, error: Error?) in
164
- // handleObserverCallback opens a beginBackgroundTask() window as its
165
- // first, synchronous action, before this returns to call
166
- // completionHandler() — otherwise iOS is free to suspend the process
167
- // the moment HealthKit's own completion handler fires, possibly
168
- // before Hermes has finished booting to run the JS callback.
169
- self?.handleObserverCallback(
170
- typeIdentifier: typeIdentifier,
171
- error: error
172
- )
173
- // Must call the completion handler promptly so iOS knows we processed the update.
174
- completionHandler()
175
- }
176
-
177
- healthStore.execute(query)
178
-
179
- healthStore.enableBackgroundDelivery(for: sampleType, frequency: frequency) { success, error in
180
- if let error = error {
181
- print("[react-native-healthkit] BackgroundDeliveryManager: enableBackgroundDelivery failed for \(typeIdentifier): \(error.localizedDescription)")
182
- } else if !success {
183
- print("[react-native-healthkit] BackgroundDeliveryManager: enableBackgroundDelivery returned false for \(typeIdentifier)")
184
- }
185
- }
186
-
187
- queue.sync(flags: .barrier) {
188
- self.observerQueries[typeIdentifier] = query
189
- }
190
- }
191
- }
192
-
193
- private func handleObserverCallback(typeIdentifier: String, error: Error?) {
194
- let errorMessage = error?.localizedDescription
195
- os_log("observer fired: %{public}@", log: bgLog, type: .info, typeIdentifier)
196
-
197
- // Ask iOS for real execution time before doing anything else, so the
198
- // process survives long enough for Hermes to boot and the JS callback to
199
- // run — see the comment at this query's registration above.
200
- var backgroundTaskId = UIBackgroundTaskIdentifier.invalid
201
- let endTask: () -> Void = { [weak self] in
202
- self?.queue.sync(flags: .barrier) {
203
- guard backgroundTaskId != .invalid else { return }
204
- UIApplication.shared.endBackgroundTask(backgroundTaskId)
205
- backgroundTaskId = .invalid
206
- }
207
- }
208
- backgroundTaskId = UIApplication.shared.beginBackgroundTask(withName: "healthkit-observer-\(typeIdentifier)") {
209
- os_log("background task expired: %{public}@", log: bgLog, type: .info, typeIdentifier)
210
- endTask()
211
- }
212
- os_log("background task started: %{public}@", log: bgLog, type: .info, typeIdentifier)
213
-
214
- queue.sync(flags: .barrier) {
215
- if let callback = self.typeCallbacks[typeIdentifier] {
216
- DispatchQueue.main.async {
217
- os_log("dispatching to per-type JS callback: %{public}@", log: bgLog, type: .info, typeIdentifier)
218
- callback(typeIdentifier, errorMessage)
219
- }
220
- } else if let callback = self.jsCallback {
221
- // JS is connected — dispatch to main thread for JSI safety
222
- DispatchQueue.main.async {
223
- os_log("dispatching to global JS callback: %{public}@", log: bgLog, type: .info, typeIdentifier)
224
- callback(typeIdentifier, errorMessage)
225
- }
226
- } else {
227
- // JS not ready yet — queue the event for later
228
- os_log("no JS callback yet, queuing: %{public}@", log: bgLog, type: .info, typeIdentifier)
229
- self.pendingEvents.append((typeIdentifier: typeIdentifier, errorMessage: errorMessage))
230
- }
231
- }
232
-
233
- // Hold the task open for a fixed, generous window rather than trying to
234
- // ack precisely when JS finishes — Hermes boot plus the JS callback's own
235
- // async work (HealthKit reads + Supabase upsert) is unpredictable, and a
236
- // completion-ack channel back from JS isn't worth building on the first
237
- // pass for a personal-use app. First place to revisit if verification
238
- // shows this window is too tight.
239
- DispatchQueue.main.asyncAfter(deadline: .now() + 25) {
240
- os_log("background task window elapsed: %{public}@", log: bgLog, type: .info, typeIdentifier)
241
- endTask()
242
- }
243
- }
244
-
245
- // Local type resolution that doesn't depend on NitroModules (which isn't available at AppDelegate time).
246
- // Uses the older factory APIs (quantityType(forIdentifier:) etc.) for iOS 13+ compatibility.
247
- private func sampleTypeFromString(_ identifier: String) -> HKSampleType? {
248
- if identifier.starts(with: "HKQuantityTypeIdentifier") {
249
- let typeId = HKQuantityTypeIdentifier(rawValue: identifier)
250
- return HKSampleType.quantityType(forIdentifier: typeId)
251
- }
252
- if identifier.starts(with: "HKCategoryTypeIdentifier") {
253
- let typeId = HKCategoryTypeIdentifier(rawValue: identifier)
254
- return HKSampleType.categoryType(forIdentifier: typeId)
255
- }
256
- if identifier == "HKWorkoutTypeIdentifier" {
257
- return HKSampleType.workoutType()
258
- }
259
- if identifier.starts(with: "HKCorrelationTypeIdentifier") {
260
- let typeId = HKCorrelationTypeIdentifier(rawValue: identifier)
261
- return HKSampleType.correlationType(forIdentifier: typeId)
262
- }
263
- if identifier == "HKAudiogramSampleType" {
264
- return HKObjectType.audiogramSampleType()
265
- }
266
- if identifier == "HKDataTypeIdentifierHeartbeatSeries" || identifier == "HKWorkoutRouteTypeIdentifier" {
267
- return HKObjectType.seriesType(forIdentifier: identifier)
268
- }
269
- if identifier == "HKElectrocardiogramType" {
270
- if #available(iOS 14.0, *) {
271
- return HKSampleType.electrocardiogramType()
272
- }
273
- return nil
274
- }
275
- return nil
276
- }
277
- }
package/ios/Bridge.h DELETED
@@ -1,10 +0,0 @@
1
- //
2
- // Bridge.h
3
- // ReactNativeHealthkit
4
- //
5
- // Created by Marc Rousavy on 22.07.24.
6
- //
7
-
8
- #pragma once
9
-
10
- #import "ExceptionCatcher.h"
@@ -1,5 +0,0 @@
1
- #import <Foundation/Foundation.h>
2
- #import <HealthKit/HealthKit.h>
3
-
4
- HKUnit * _Nullable HKUnitFromStringCatchingExceptions(NSString * _Nonnull unitString, NSError * _Nullable * _Nullable outError);
5
- BOOL RunBlockCatchingObjCExceptions(void (NS_NOESCAPE ^_Nonnull block)(void), NSError * _Nullable * _Nullable outError);
@@ -1,32 +0,0 @@
1
- #import "ExceptionCatcher.h"
2
-
3
- HKUnit * _Nullable HKUnitFromStringCatchingExceptions(NSString * _Nonnull unitString, NSError * _Nullable * _Nullable outError) {
4
- if (outError) { *outError = nil; }
5
- @try {
6
- HKUnit *unit = [HKUnit unitFromString:unitString];
7
- return unit;
8
- }
9
- @catch (NSException *exception) {
10
- if (outError) {
11
- NSDictionary *userInfo = exception.userInfo ?: @{};
12
-
13
- *outError = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
14
- }
15
- return nil;
16
- }
17
- }
18
-
19
- BOOL RunBlockCatchingObjCExceptions(void (NS_NOESCAPE ^block)(void), NSError * _Nullable * _Nullable outError) {
20
- if (outError) { *outError = nil; }
21
- @try {
22
- block();
23
- return YES;
24
- }
25
- @catch (NSException *exception) {
26
- if (outError) {
27
- NSDictionary *userInfo = exception.userInfo ?: @{};
28
- *outError = [NSError errorWithDomain:exception.name code:0 userInfo:userInfo];
29
- }
30
- return NO;
31
- }
32
- }
@@ -1,5 +0,0 @@
1
- module ReactNativeHealthkit_Private {
2
- header "Bridge.h"
3
- header "ExceptionCatcher.h"
4
- export *
5
- }