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