@shenai/react-native-sdk 3.1.1
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.
- package/LICENSE.md +5 -0
- package/android/build.gradle +81 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/AndroidManifestNew.xml +2 -0
- package/android/src/main/java/com/shenaisdk/ShenaiSdkModule.java +1325 -0
- package/android/src/main/java/com/shenaisdk/ShenaiSdkPackage.java +24 -0
- package/android/src/main/java/com/shenaisdk/ShenaiSdkViewManager.java +37 -0
- package/ios/ShenaiSdkNativeModule.m +1121 -0
- package/ios/ShenaiSdkViewManager.m +37 -0
- package/lib/module/hooks.js +83 -0
- package/lib/module/index.js +667 -0
- package/lib/typescript/src/hooks.d.ts +37 -0
- package/lib/typescript/src/index.d.ts +466 -0
- package/package.json +57 -0
- package/react-native-shenai-sdk.podspec +37 -0
|
@@ -0,0 +1,1121 @@
|
|
|
1
|
+
#import <Foundation/Foundation.h>
|
|
2
|
+
#import <React/RCTBridgeModule.h>
|
|
3
|
+
#import <React/RCTEventEmitter.h>
|
|
4
|
+
#import <ShenaiSDK/ShenaiHealthRisks.h>
|
|
5
|
+
#import <ShenaiSDK/ShenaiSDK.h>
|
|
6
|
+
|
|
7
|
+
static id ShenaiMeasurementQualityMetricsToDictionary(MeasurementQualityMetrics *metrics) {
|
|
8
|
+
if (metrics == nil) {
|
|
9
|
+
return (NSDictionary *)[NSNull null];
|
|
10
|
+
}
|
|
11
|
+
return @{
|
|
12
|
+
@"ppgQualityIndex" : metrics.ppgQualityIndex ?: [NSNull null],
|
|
13
|
+
@"bcgQualityIndex" : metrics.bcgQualityIndex ?: [NSNull null],
|
|
14
|
+
@"breathingQualityIndex" : metrics.breathingQualityIndex ?: [NSNull null],
|
|
15
|
+
@"bloodPressureQualityIndex" : metrics.bloodPressureQualityIndex ?: [NSNull null],
|
|
16
|
+
@"expectedSbpMedianAbsErrorMmhg" : metrics.expectedSbpMedianAbsErrorMmhg ?: [NSNull null],
|
|
17
|
+
@"expectedSbpP80AbsErrorMmhg" : metrics.expectedSbpP80AbsErrorMmhg ?: [NSNull null],
|
|
18
|
+
@"expectedSbpMeanAbsErrorMmhg" : metrics.expectedSbpMeanAbsErrorMmhg ?: [NSNull null],
|
|
19
|
+
@"expectedSbpBalancedMaeMmhg" : metrics.expectedSbpBalancedMaeMmhg ?: [NSNull null],
|
|
20
|
+
@"expectedDbpMedianAbsErrorMmhg" : metrics.expectedDbpMedianAbsErrorMmhg ?: [NSNull null],
|
|
21
|
+
@"expectedDbpP80AbsErrorMmhg" : metrics.expectedDbpP80AbsErrorMmhg ?: [NSNull null],
|
|
22
|
+
@"expectedDbpMeanAbsErrorMmhg" : metrics.expectedDbpMeanAbsErrorMmhg ?: [NSNull null],
|
|
23
|
+
@"expectedDbpBalancedMaeMmhg" : metrics.expectedDbpBalancedMaeMmhg ?: [NSNull null],
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@interface ShenaiSdkNativeModule : RCTEventEmitter <RCTBridgeModule>
|
|
28
|
+
|
|
29
|
+
@end
|
|
30
|
+
|
|
31
|
+
@implementation ShenaiSdkNativeModule {
|
|
32
|
+
BOOL hasListeners;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
RCT_EXPORT_MODULE(); // This macro exports the module to React Native
|
|
36
|
+
|
|
37
|
+
- (NSArray<NSString *> *)supportedEvents {
|
|
38
|
+
return @[ @"ShenAIEvent" ];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
- (void)startObserving {
|
|
42
|
+
hasListeners = YES;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
- (void)stopObserving {
|
|
46
|
+
hasListeners = NO;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
- (void)sendShenaiEvent:(NSString *)name {
|
|
50
|
+
[self sendEventWithName:@"ShenAIEvent" body:@{@"EventName" : name}];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
RCT_EXPORT_METHOD(initialize
|
|
54
|
+
: (NSString *)apiKey userId
|
|
55
|
+
: (NSString *)userId settings
|
|
56
|
+
: (NSDictionary *)settings resolver
|
|
57
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
58
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
59
|
+
InitializationSettings *initSettings = [[InitializationSettings alloc] init];
|
|
60
|
+
|
|
61
|
+
// Set settings if they are provided
|
|
62
|
+
if (settings[@"precisionMode"]) {
|
|
63
|
+
initSettings.precisionMode = [settings[@"precisionMode"] integerValue];
|
|
64
|
+
}
|
|
65
|
+
if (settings[@"operatingMode"]) {
|
|
66
|
+
initSettings.operatingMode = [settings[@"operatingMode"] integerValue];
|
|
67
|
+
}
|
|
68
|
+
if (settings[@"measurementPreset"]) {
|
|
69
|
+
NSNumber *presetValue = settings[@"measurementPreset"];
|
|
70
|
+
NSLog(@"Received preset: %@", presetValue);
|
|
71
|
+
initSettings.measurementPreset = presetValue.integerValue;
|
|
72
|
+
} else {
|
|
73
|
+
NSLog(@"No preset received");
|
|
74
|
+
}
|
|
75
|
+
if (settings[@"cameraMode"]) {
|
|
76
|
+
initSettings.cameraMode = [settings[@"cameraMode"] integerValue];
|
|
77
|
+
}
|
|
78
|
+
if (settings[@"onboardingMode"]) {
|
|
79
|
+
initSettings.onboardingMode = [settings[@"onboardingMode"] integerValue];
|
|
80
|
+
}
|
|
81
|
+
if (settings[@"initializationMode"]) {
|
|
82
|
+
initSettings.initializationMode = [settings[@"initializationMode"] integerValue];
|
|
83
|
+
}
|
|
84
|
+
if (settings[@"offlineProcessing"]) {
|
|
85
|
+
initSettings.offlineProcessing = [settings[@"offlineProcessing"] boolValue];
|
|
86
|
+
}
|
|
87
|
+
if (settings[@"showUserInterface"]) {
|
|
88
|
+
initSettings.showUserInterface = [settings[@"showUserInterface"] boolValue];
|
|
89
|
+
}
|
|
90
|
+
if (settings[@"showFacePositioningOverlay"]) {
|
|
91
|
+
initSettings.showFacePositioningOverlay = [settings[@"showFacePositioningOverlay"] boolValue];
|
|
92
|
+
}
|
|
93
|
+
if (settings[@"showVisualWarnings"]) {
|
|
94
|
+
initSettings.showVisualWarnings = [settings[@"showVisualWarnings"] boolValue];
|
|
95
|
+
}
|
|
96
|
+
if (settings[@"enableCameraSwap"]) {
|
|
97
|
+
initSettings.enableCameraSwap = [settings[@"enableCameraSwap"] boolValue];
|
|
98
|
+
}
|
|
99
|
+
if (settings[@"showFaceMask"]) {
|
|
100
|
+
initSettings.showFaceMask = [settings[@"showFaceMask"] boolValue];
|
|
101
|
+
}
|
|
102
|
+
if (settings[@"showBloodFlow"]) {
|
|
103
|
+
initSettings.showBloodFlow = [settings[@"showBloodFlow"] boolValue];
|
|
104
|
+
}
|
|
105
|
+
if (settings[@"hideShenaiLogo"]) {
|
|
106
|
+
initSettings.hideShenaiLogo = [settings[@"hideShenaiLogo"] boolValue];
|
|
107
|
+
}
|
|
108
|
+
if (settings[@"includeTimestampInPdf"]) {
|
|
109
|
+
initSettings.includeTimestampInPdf = [settings[@"includeTimestampInPdf"] boolValue];
|
|
110
|
+
}
|
|
111
|
+
if (settings[@"pdfEmailSubject"]) {
|
|
112
|
+
initSettings.pdfEmailSubject = settings[@"pdfEmailSubject"];
|
|
113
|
+
}
|
|
114
|
+
if (settings[@"pdfEmailBody"]) {
|
|
115
|
+
initSettings.pdfEmailBody = settings[@"pdfEmailBody"];
|
|
116
|
+
}
|
|
117
|
+
if (settings[@"enableStartAfterSuccess"]) {
|
|
118
|
+
initSettings.enableStartAfterSuccess = [settings[@"enableStartAfterSuccess"] boolValue];
|
|
119
|
+
}
|
|
120
|
+
if (settings[@"enableSummaryScreen"]) {
|
|
121
|
+
initSettings.enableSummaryScreen = [settings[@"enableSummaryScreen"] boolValue];
|
|
122
|
+
}
|
|
123
|
+
if (settings[@"showResultsFinishButton"]) {
|
|
124
|
+
initSettings.showResultsFinishButton = [settings[@"showResultsFinishButton"] boolValue];
|
|
125
|
+
}
|
|
126
|
+
if (settings[@"enableHealthRisks"]) {
|
|
127
|
+
initSettings.enableHealthRisks = [settings[@"enableHealthRisks"] boolValue];
|
|
128
|
+
}
|
|
129
|
+
if (settings[@"showHealthIndicesFinishButton"]) {
|
|
130
|
+
initSettings.showHealthIndicesFinishButton = [settings[@"showHealthIndicesFinishButton"] boolValue];
|
|
131
|
+
}
|
|
132
|
+
if (settings[@"saveHealthRisksFactors"]) {
|
|
133
|
+
initSettings.saveHealthRisksFactors = [settings[@"saveHealthRisksFactors"] boolValue];
|
|
134
|
+
}
|
|
135
|
+
if (settings[@"showOutOfRangeResultIndicators"]) {
|
|
136
|
+
initSettings.showOutOfRangeResultIndicators = [settings[@"showOutOfRangeResultIndicators"] boolValue];
|
|
137
|
+
}
|
|
138
|
+
if (settings[@"showSignalQualityIndicator"]) {
|
|
139
|
+
initSettings.showSignalQualityIndicator = [settings[@"showSignalQualityIndicator"] boolValue];
|
|
140
|
+
}
|
|
141
|
+
if (settings[@"showSignalTile"]) {
|
|
142
|
+
initSettings.showSignalTile = [settings[@"showSignalTile"] boolValue];
|
|
143
|
+
}
|
|
144
|
+
if (settings[@"showStartStopButton"]) {
|
|
145
|
+
initSettings.showStartStopButton = [settings[@"showStartStopButton"] boolValue];
|
|
146
|
+
}
|
|
147
|
+
if (settings[@"showInfoButton"]) {
|
|
148
|
+
initSettings.showInfoButton = [settings[@"showInfoButton"] boolValue];
|
|
149
|
+
}
|
|
150
|
+
if (settings[@"showDisclaimer"]) {
|
|
151
|
+
initSettings.showDisclaimer = [settings[@"showDisclaimer"] boolValue];
|
|
152
|
+
}
|
|
153
|
+
if (settings[@"enableMeasurementsDashboard"]) {
|
|
154
|
+
initSettings.enableMeasurementsDashboard = [settings[@"enableMeasurementsDashboard"] boolValue];
|
|
155
|
+
}
|
|
156
|
+
if (settings[@"uiVersion"]) {
|
|
157
|
+
initSettings.uiVersion = (UiVersion)[settings[@"uiVersion"] integerValue];
|
|
158
|
+
}
|
|
159
|
+
if (settings[@"showTrialMetricLabels"]) {
|
|
160
|
+
initSettings.showTrialMetricLabels = [settings[@"showTrialMetricLabels"] boolValue];
|
|
161
|
+
}
|
|
162
|
+
if (settings[@"applyPrecisionModeToBloodPressure"]) {
|
|
163
|
+
initSettings.applyPrecisionModeToBloodPressure = [settings[@"applyPrecisionModeToBloodPressure"] boolValue];
|
|
164
|
+
}
|
|
165
|
+
if (settings[@"blockingMeasurementConditions"]) {
|
|
166
|
+
NSArray *conditions = settings[@"blockingMeasurementConditions"];
|
|
167
|
+
NSMutableArray<NSNumber *> *values = [NSMutableArray arrayWithCapacity:conditions.count];
|
|
168
|
+
for (NSNumber *condition in conditions) {
|
|
169
|
+
[values addObject:@(condition.integerValue)];
|
|
170
|
+
}
|
|
171
|
+
initSettings.blockingMeasurementConditions = values;
|
|
172
|
+
}
|
|
173
|
+
if (settings[@"warningMeasurementConditions"]) {
|
|
174
|
+
NSArray *conditions = settings[@"warningMeasurementConditions"];
|
|
175
|
+
NSMutableArray<NSNumber *> *values = [NSMutableArray arrayWithCapacity:conditions.count];
|
|
176
|
+
for (NSNumber *condition in conditions) {
|
|
177
|
+
[values addObject:@(condition.integerValue)];
|
|
178
|
+
}
|
|
179
|
+
initSettings.warningMeasurementConditions = values;
|
|
180
|
+
}
|
|
181
|
+
if (settings[@"uiFlowScreens"]) {
|
|
182
|
+
NSArray *screens = settings[@"uiFlowScreens"];
|
|
183
|
+
NSMutableArray<NSNumber *> *values = [NSMutableArray arrayWithCapacity:screens.count];
|
|
184
|
+
for (NSNumber *screen in screens) {
|
|
185
|
+
[values addObject:@(screen.integerValue)];
|
|
186
|
+
}
|
|
187
|
+
initSettings.uiFlowScreens = values;
|
|
188
|
+
}
|
|
189
|
+
if (settings[@"frameWidth"]) {
|
|
190
|
+
initSettings.frameWidth = [settings[@"frameWidth"] intValue];
|
|
191
|
+
}
|
|
192
|
+
if (settings[@"frameHeight"]) {
|
|
193
|
+
initSettings.frameHeight = [settings[@"frameHeight"] intValue];
|
|
194
|
+
}
|
|
195
|
+
if (settings[@"rotation"]) {
|
|
196
|
+
initSettings.rotation = [settings[@"rotation"] intValue];
|
|
197
|
+
}
|
|
198
|
+
if (settings[@"risksFactors"]) {
|
|
199
|
+
initSettings.risksFactors = [self risksFactorsFromDictionary:settings[@"risksFactors"]];
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
initSettings.eventCallback = ^(Event event) {
|
|
203
|
+
NSString *jsEvent = @"UNKNOWN";
|
|
204
|
+
|
|
205
|
+
switch (event) {
|
|
206
|
+
case EventStartButtonClicked:
|
|
207
|
+
jsEvent = @"START_BUTTON_CLICKED";
|
|
208
|
+
break;
|
|
209
|
+
case EventStopButtonClicked:
|
|
210
|
+
jsEvent = @"STOP_BUTTON_CLICKED";
|
|
211
|
+
break;
|
|
212
|
+
case EventMeasurementFinished:
|
|
213
|
+
jsEvent = @"MEASUREMENT_FINISHED";
|
|
214
|
+
break;
|
|
215
|
+
case EventUserFlowFinished:
|
|
216
|
+
jsEvent = @"USER_FLOW_FINISHED";
|
|
217
|
+
break;
|
|
218
|
+
case EventScreenChanged:
|
|
219
|
+
jsEvent = @"SCREEN_CHANGED";
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
if (hasListeners) {
|
|
223
|
+
[self sendEventWithName:@"ShenAIEvent" body:@{@"EventName" : jsEvent}];
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
InitializationResult result = [ShenaiSDK initialize:apiKey userID:userId settings:initSettings];
|
|
227
|
+
|
|
228
|
+
resolve(@(result));
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
RCT_EXPORT_METHOD(getRealtimeMetrics
|
|
232
|
+
: (float)periodSec resolver
|
|
233
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
234
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
235
|
+
MeasurementResults *results = [ShenaiSDK getRealtimeMetrics:periodSec];
|
|
236
|
+
if (results) {
|
|
237
|
+
NSMutableArray *heartbeatsArray = [NSMutableArray arrayWithCapacity:results.heartbeats.count];
|
|
238
|
+
for (Heartbeat *heartbeat in results.heartbeats) {
|
|
239
|
+
[heartbeatsArray addObject:@{
|
|
240
|
+
@"startLocationSec" : @(heartbeat.startLocationSec),
|
|
241
|
+
@"endLocationSec" : @(heartbeat.endLocationSec),
|
|
242
|
+
@"durationMs" : @(heartbeat.durationMs)
|
|
243
|
+
}];
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
NSDictionary *resultsDict = @{
|
|
247
|
+
@"heartRateBpm" : @(results.heartRateBpm),
|
|
248
|
+
@"hrvSdnnMs" : results.hrvSdnnMs ?: [NSNull null],
|
|
249
|
+
@"hrvLnrmssdMs" : results.hrvLnrmssdMs ?: [NSNull null],
|
|
250
|
+
@"stressIndex" : results.stressIndex ?: [NSNull null],
|
|
251
|
+
@"parasympatheticActivity" : results.parasympatheticActivity ?: [NSNull null],
|
|
252
|
+
@"breathingRateBpm" : results.breathingRateBpm ?: [NSNull null],
|
|
253
|
+
@"systolicBloodPressureMmhg" : results.systolicBloodPressureMmhg ?: [NSNull null],
|
|
254
|
+
@"diastolicBloodPressureMmhg" : results.diastolicBloodPressureMmhg ?: [NSNull null],
|
|
255
|
+
@"cardiacWorkloadMmhgPerSec" : results.cardiacWorkloadMmhgPerSec ?: [NSNull null],
|
|
256
|
+
@"ageYears" : results.ageYears ?: [NSNull null],
|
|
257
|
+
@"bmiKgPerM2" : results.bmiKgPerM2 ?: [NSNull null],
|
|
258
|
+
@"bmiCategory" : @(results.bmiCategory),
|
|
259
|
+
@"weightKg" : results.weightKg ?: [NSNull null],
|
|
260
|
+
@"heightCm" : results.heightCm ?: [NSNull null],
|
|
261
|
+
@"qualityMetrics" : ShenaiMeasurementQualityMetricsToDictionary(results.qualityMetrics),
|
|
262
|
+
@"heartbeats" : heartbeatsArray,
|
|
263
|
+
@"averageSignalQuality" : @(results.averageSignalQuality)
|
|
264
|
+
};
|
|
265
|
+
resolve(resultsDict);
|
|
266
|
+
} else {
|
|
267
|
+
resolve([NSNull null]);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
RCT_EXPORT_METHOD(setCustomMeasurementConfig
|
|
272
|
+
: (NSDictionary *)config resolver
|
|
273
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
274
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
275
|
+
if (!config) {
|
|
276
|
+
reject(@"E_CONFIG_NULL", @"Configuration is null", nil);
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
CustomMeasurementConfig *measurementConfig = [[CustomMeasurementConfig alloc] init];
|
|
281
|
+
|
|
282
|
+
// Assuming your SDK has a method to apply this config
|
|
283
|
+
measurementConfig.durationSeconds = config[@"durationSeconds"];
|
|
284
|
+
measurementConfig.infiniteMeasurement = [config[@"infiniteMeasurement"] boolValue];
|
|
285
|
+
|
|
286
|
+
{
|
|
287
|
+
NSArray *metricsArray = config[@"instantMetrics"];
|
|
288
|
+
if (metricsArray != nil) {
|
|
289
|
+
NSMutableArray<NSNumber *> *metricsEnumArray = [NSMutableArray arrayWithCapacity:[metricsArray count]];
|
|
290
|
+
for (NSNumber *metricNumber in metricsArray) {
|
|
291
|
+
[metricsEnumArray addObject:@([metricNumber integerValue])];
|
|
292
|
+
}
|
|
293
|
+
measurementConfig.instantMetrics = metricsEnumArray;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
{
|
|
297
|
+
NSArray *metricsArray = config[@"summaryMetrics"];
|
|
298
|
+
if (metricsArray != nil) {
|
|
299
|
+
NSMutableArray<NSNumber *> *metricsEnumArray = [NSMutableArray arrayWithCapacity:[metricsArray count]];
|
|
300
|
+
for (NSNumber *metricNumber in metricsArray) {
|
|
301
|
+
[metricsEnumArray addObject:@([metricNumber integerValue])];
|
|
302
|
+
}
|
|
303
|
+
measurementConfig.summaryMetrics = metricsEnumArray;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
{
|
|
307
|
+
NSArray *healthIndicesArray = config[@"healthIndices"];
|
|
308
|
+
if (healthIndicesArray != nil) {
|
|
309
|
+
NSMutableArray<NSNumber *> *healthIndicesEnumArray =
|
|
310
|
+
[NSMutableArray arrayWithCapacity:[healthIndicesArray count]];
|
|
311
|
+
for (NSNumber *healthIndexNumber in healthIndicesArray) {
|
|
312
|
+
[healthIndicesEnumArray addObject:@([healthIndexNumber integerValue])];
|
|
313
|
+
}
|
|
314
|
+
measurementConfig.healthIndices = healthIndicesEnumArray;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
measurementConfig.realtimeHrPeriodSeconds = config[@"realtimeHrPeriodSeconds"];
|
|
319
|
+
measurementConfig.realtimeHrvPeriodSeconds = config[@"realtimeHrvPeriodSeconds"];
|
|
320
|
+
measurementConfig.realtimeCardiacStressPeriodSeconds = config[@"realtimeCardiacStressPeriodSeconds"];
|
|
321
|
+
|
|
322
|
+
// Apply the configuration to your SDK
|
|
323
|
+
[ShenaiSDK setCustomMeasurementConfig:measurementConfig];
|
|
324
|
+
|
|
325
|
+
resolve(@(YES));
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
RCT_EXPORT_METHOD(setCustomColorTheme
|
|
329
|
+
: (NSDictionary *)theme resolver
|
|
330
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
331
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
332
|
+
if (!theme) {
|
|
333
|
+
reject(@"E_THEME_NULL", @"Theme is null", nil);
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
CustomColorTheme *colorTheme = [[CustomColorTheme alloc] init];
|
|
338
|
+
|
|
339
|
+
// Assuming your SDK has a method to apply this theme
|
|
340
|
+
colorTheme.themeColor = theme[@"themeColor"];
|
|
341
|
+
colorTheme.textColor = theme[@"textColor"];
|
|
342
|
+
colorTheme.backgroundColor = theme[@"backgroundColor"];
|
|
343
|
+
colorTheme.tileColor = theme[@"tileColor"];
|
|
344
|
+
colorTheme.buttonMainColor = theme[@"buttonMainColor"];
|
|
345
|
+
colorTheme.buttonSecondaryColor = theme[@"buttonSecondaryColor"];
|
|
346
|
+
|
|
347
|
+
// Apply the theme to your SDK
|
|
348
|
+
[ShenaiSDK setCustomColorTheme:colorTheme];
|
|
349
|
+
|
|
350
|
+
resolve(@(YES));
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
RCT_EXPORT_METHOD(getMeasurementResults : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
354
|
+
MeasurementResults *results = [ShenaiSDK getMeasurementResults];
|
|
355
|
+
if (results) {
|
|
356
|
+
NSMutableArray *heartbeatsArray = [NSMutableArray arrayWithCapacity:results.heartbeats.count];
|
|
357
|
+
for (Heartbeat *heartbeat in results.heartbeats) {
|
|
358
|
+
[heartbeatsArray addObject:@{
|
|
359
|
+
@"startLocationSec" : @(heartbeat.startLocationSec),
|
|
360
|
+
@"endLocationSec" : @(heartbeat.endLocationSec),
|
|
361
|
+
@"durationMs" : @(heartbeat.durationMs)
|
|
362
|
+
}];
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
NSDictionary *resultsDict = @{
|
|
366
|
+
@"heartRateBpm" : @(results.heartRateBpm),
|
|
367
|
+
@"hrvSdnnMs" : results.hrvSdnnMs ?: [NSNull null],
|
|
368
|
+
@"hrvLnrmssdMs" : results.hrvLnrmssdMs ?: [NSNull null],
|
|
369
|
+
@"stressIndex" : results.stressIndex ?: [NSNull null],
|
|
370
|
+
@"parasympatheticActivity" : results.parasympatheticActivity ?: [NSNull null],
|
|
371
|
+
@"breathingRateBpm" : results.breathingRateBpm ?: [NSNull null],
|
|
372
|
+
@"systolicBloodPressureMmhg" : results.systolicBloodPressureMmhg ?: [NSNull null],
|
|
373
|
+
@"diastolicBloodPressureMmhg" : results.diastolicBloodPressureMmhg ?: [NSNull null],
|
|
374
|
+
@"cardiacWorkloadMmhgPerSec" : results.cardiacWorkloadMmhgPerSec ?: [NSNull null],
|
|
375
|
+
@"ageYears" : results.ageYears ?: [NSNull null],
|
|
376
|
+
@"bmiKgPerM2" : results.bmiKgPerM2 ?: [NSNull null],
|
|
377
|
+
@"bmiCategory" : @(results.bmiCategory),
|
|
378
|
+
@"weightKg" : results.weightKg ?: [NSNull null],
|
|
379
|
+
@"heightCm" : results.heightCm ?: [NSNull null],
|
|
380
|
+
@"qualityMetrics" : ShenaiMeasurementQualityMetricsToDictionary(results.qualityMetrics),
|
|
381
|
+
@"heartbeats" : heartbeatsArray,
|
|
382
|
+
@"averageSignalQuality" : @(results.averageSignalQuality)
|
|
383
|
+
};
|
|
384
|
+
resolve(resultsDict);
|
|
385
|
+
} else {
|
|
386
|
+
resolve([NSNull null]);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
RCT_EXPORT_METHOD(getMeasurementResultsHistory
|
|
391
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
392
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
393
|
+
MeasurementResultsHistory *history = [ShenaiSDK getMeasurementResultsHistory];
|
|
394
|
+
|
|
395
|
+
if (!history) {
|
|
396
|
+
resolve([NSNull null]);
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
NSMutableArray *outerArray = [NSMutableArray arrayWithCapacity:history.history.count];
|
|
401
|
+
for (MeasurementResultsWithMetadata *item in history.history) {
|
|
402
|
+
MeasurementResults *res = item.measurementResults;
|
|
403
|
+
NSMutableArray *heartbeatsArray = [NSMutableArray arrayWithCapacity:res.heartbeats.count];
|
|
404
|
+
for (Heartbeat *hb in res.heartbeats) {
|
|
405
|
+
[heartbeatsArray addObject:@{
|
|
406
|
+
@"startLocationSec" : @(hb.startLocationSec),
|
|
407
|
+
@"endLocationSec" : @(hb.endLocationSec),
|
|
408
|
+
@"durationMs" : @(hb.durationMs)
|
|
409
|
+
}];
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
NSDictionary *resultsDict = @{
|
|
413
|
+
@"heartRateBpm" : @(res.heartRateBpm),
|
|
414
|
+
@"hrvSdnnMs" : res.hrvSdnnMs ?: [NSNull null],
|
|
415
|
+
@"hrvLnrmssdMs" : res.hrvLnrmssdMs ?: [NSNull null],
|
|
416
|
+
@"stressIndex" : res.stressIndex ?: [NSNull null],
|
|
417
|
+
@"parasympatheticActivity" : res.parasympatheticActivity ?: [NSNull null],
|
|
418
|
+
@"breathingRateBpm" : res.breathingRateBpm ?: [NSNull null],
|
|
419
|
+
@"systolicBloodPressureMmhg" : res.systolicBloodPressureMmhg ?: [NSNull null],
|
|
420
|
+
@"diastolicBloodPressureMmhg" : res.diastolicBloodPressureMmhg ?: [NSNull null],
|
|
421
|
+
@"cardiacWorkloadMmhgPerSec" : res.cardiacWorkloadMmhgPerSec ?: [NSNull null],
|
|
422
|
+
@"ageYears" : res.ageYears ?: [NSNull null],
|
|
423
|
+
@"bmiKgPerM2" : res.bmiKgPerM2 ?: [NSNull null],
|
|
424
|
+
@"bmiCategory" : @(res.bmiCategory),
|
|
425
|
+
@"weightKg" : res.weightKg ?: [NSNull null],
|
|
426
|
+
@"heightCm" : res.heightCm ?: [NSNull null],
|
|
427
|
+
@"qualityMetrics" : ShenaiMeasurementQualityMetricsToDictionary(res.qualityMetrics),
|
|
428
|
+
@"heartbeats" : heartbeatsArray,
|
|
429
|
+
@"averageSignalQuality" : @(res.averageSignalQuality)
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
NSDictionary *itemDict = @{
|
|
433
|
+
@"measurementResults" : resultsDict,
|
|
434
|
+
@"epochTimestamp" : item.epochTimestamp,
|
|
435
|
+
@"isCalibration" : @(item.isCalibration)
|
|
436
|
+
};
|
|
437
|
+
|
|
438
|
+
[outerArray addObject:itemDict];
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
NSDictionary *finalDict = @{@"history" : outerArray};
|
|
442
|
+
resolve(finalDict);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
RCT_EXPORT_METHOD(isInitialized : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
446
|
+
BOOL isInitialized = [ShenaiSDK isInitialized];
|
|
447
|
+
resolve(@(isInitialized));
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
RCT_EXPORT_METHOD(deinitialize) { [ShenaiSDK deinitialize]; }
|
|
451
|
+
|
|
452
|
+
RCT_EXPORT_METHOD(setOperatingMode : (NSInteger)mode) { [ShenaiSDK setOperatingMode:mode]; }
|
|
453
|
+
|
|
454
|
+
RCT_EXPORT_METHOD(startMeasurement) { [ShenaiSDK startMeasurement]; }
|
|
455
|
+
|
|
456
|
+
RCT_EXPORT_METHOD(stopMeasurement) { [ShenaiSDK stopMeasurement]; }
|
|
457
|
+
|
|
458
|
+
RCT_EXPORT_METHOD(resetMeasurementSession) { [ShenaiSDK resetMeasurementSession]; }
|
|
459
|
+
|
|
460
|
+
RCT_EXPORT_METHOD(getOperatingMode : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
461
|
+
OperatingMode mode = [ShenaiSDK getOperatingMode];
|
|
462
|
+
resolve(@(mode));
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
RCT_EXPORT_METHOD(getCalibrationState : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
466
|
+
CalibrationState mode = [ShenaiSDK getCalibrationState];
|
|
467
|
+
resolve(@(mode));
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
RCT_EXPORT_METHOD(setPrecisionMode : (NSInteger)mode) { [ShenaiSDK setPrecisionMode:mode]; }
|
|
471
|
+
|
|
472
|
+
RCT_EXPORT_METHOD(getPrecisionMode : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
473
|
+
PrecisionMode mode = [ShenaiSDK getPrecisionMode];
|
|
474
|
+
resolve(@(mode));
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
RCT_EXPORT_METHOD(setApplyPrecisionModeToBloodPressure : (BOOL)apply) {
|
|
478
|
+
[ShenaiSDK setApplyPrecisionModeToBloodPressure:apply];
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
RCT_EXPORT_METHOD(getApplyPrecisionModeToBloodPressure
|
|
482
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
483
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
484
|
+
resolve(@([ShenaiSDK getApplyPrecisionModeToBloodPressure]));
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
RCT_EXPORT_METHOD(setBlockingMeasurementConditions : (NSArray<NSNumber *> *)conditions) {
|
|
488
|
+
[ShenaiSDK setBlockingMeasurementConditions:conditions ?: @[]];
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
RCT_EXPORT_METHOD(getBlockingMeasurementConditions
|
|
492
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
493
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
494
|
+
resolve([ShenaiSDK getBlockingMeasurementConditions]);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
RCT_EXPORT_METHOD(setWarningMeasurementConditions : (NSArray<NSNumber *> *)conditions) {
|
|
498
|
+
[ShenaiSDK setWarningMeasurementConditions:conditions ?: @[]];
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
RCT_EXPORT_METHOD(getWarningMeasurementConditions
|
|
502
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
503
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
504
|
+
resolve([ShenaiSDK getWarningMeasurementConditions]);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
RCT_EXPORT_METHOD(getCurrentViolatedMeasurementEnvironmentCondition
|
|
508
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
509
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
510
|
+
resolve([ShenaiSDK getCurrentViolatedMeasurementEnvironmentCondition]);
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
RCT_EXPORT_METHOD(setMeasurementPreset : (NSInteger)preset) { [ShenaiSDK setMeasurementPreset:preset]; }
|
|
514
|
+
|
|
515
|
+
RCT_EXPORT_METHOD(getMeasurementPreset : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
516
|
+
MeasurementPreset preset = [ShenaiSDK getMeasurementPreset];
|
|
517
|
+
resolve(@(preset));
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
RCT_EXPORT_METHOD(setCameraMode : (NSInteger)mode) { [ShenaiSDK setCameraMode:mode]; }
|
|
521
|
+
|
|
522
|
+
RCT_EXPORT_METHOD(getCameraMode : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
523
|
+
CameraMode mode = [ShenaiSDK getCameraMode];
|
|
524
|
+
resolve(@(mode));
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
RCT_EXPORT_METHOD(getLastCameraError : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
528
|
+
resolve([ShenaiSDK getLastCameraError]);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
RCT_EXPORT_METHOD(setScreen : (NSInteger)screen) { [ShenaiSDK setScreen:screen]; }
|
|
532
|
+
|
|
533
|
+
RCT_EXPORT_METHOD(getScreen : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
534
|
+
Screen screen = [ShenaiSDK getScreen];
|
|
535
|
+
resolve(@(screen));
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
// SDK Interface Elements
|
|
539
|
+
|
|
540
|
+
// User Interface
|
|
541
|
+
RCT_EXPORT_METHOD(setShowUserInterface : (BOOL)show) { [ShenaiSDK setShowUserInterface:show]; }
|
|
542
|
+
|
|
543
|
+
RCT_EXPORT_METHOD(getShowUserInterface : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
544
|
+
BOOL show = [ShenaiSDK getShowUserInterface];
|
|
545
|
+
resolve(@(show));
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
// Face Positioning Overlay
|
|
549
|
+
RCT_EXPORT_METHOD(setShowFacePositioningOverlay : (BOOL)show) { [ShenaiSDK setShowFacePositioningOverlay:show]; }
|
|
550
|
+
|
|
551
|
+
RCT_EXPORT_METHOD(getShowFacePositioningOverlay
|
|
552
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
553
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
554
|
+
BOOL show = [ShenaiSDK getShowFacePositioningOverlay];
|
|
555
|
+
resolve(@(show));
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
// Visual Warnings
|
|
559
|
+
RCT_EXPORT_METHOD(setShowVisualWarnings : (BOOL)show) { [ShenaiSDK setShowVisualWarnings:show]; }
|
|
560
|
+
|
|
561
|
+
RCT_EXPORT_METHOD(getShowVisualWarnings : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
562
|
+
BOOL show = [ShenaiSDK getShowVisualWarnings];
|
|
563
|
+
resolve(@(show));
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
// Camera Swap
|
|
567
|
+
RCT_EXPORT_METHOD(setEnableCameraSwap : (BOOL)enable) { [ShenaiSDK setEnableCameraSwap:enable]; }
|
|
568
|
+
|
|
569
|
+
RCT_EXPORT_METHOD(getEnableCameraSwap : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
570
|
+
BOOL enable = [ShenaiSDK getEnableCameraSwap];
|
|
571
|
+
resolve(@(enable));
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
// Face Mask
|
|
575
|
+
RCT_EXPORT_METHOD(setShowFaceMask : (BOOL)show) { [ShenaiSDK setShowFaceMask:show]; }
|
|
576
|
+
|
|
577
|
+
RCT_EXPORT_METHOD(getShowFaceMask : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
578
|
+
BOOL show = [ShenaiSDK getShowFaceMask];
|
|
579
|
+
resolve(@(show));
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
// Blood Flow
|
|
583
|
+
RCT_EXPORT_METHOD(setShowBloodFlow : (BOOL)show) { [ShenaiSDK setShowBloodFlow:show]; }
|
|
584
|
+
|
|
585
|
+
RCT_EXPORT_METHOD(getShowBloodFlow : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
586
|
+
BOOL show = [ShenaiSDK getShowBloodFlow];
|
|
587
|
+
resolve(@(show));
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
RCT_EXPORT_METHOD(setIncludeTimestampInPdf : (BOOL)include) { [ShenaiSDK setIncludeTimestampInPdf:include]; }
|
|
591
|
+
|
|
592
|
+
RCT_EXPORT_METHOD(getIncludeTimestampInPdf : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
593
|
+
BOOL include = [ShenaiSDK getIncludeTimestampInPdf];
|
|
594
|
+
resolve(@(include));
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
RCT_EXPORT_METHOD(setPdfEmailSubject : (NSString *)subject) { [ShenaiSDK setPdfEmailSubject:subject]; }
|
|
598
|
+
|
|
599
|
+
RCT_EXPORT_METHOD(setPdfEmailBody : (NSString *)body) { [ShenaiSDK setPdfEmailBody:body]; }
|
|
600
|
+
|
|
601
|
+
RCT_EXPORT_METHOD(setShowStartStopButton : (BOOL)show) { [ShenaiSDK setShowStartStopButton:show]; }
|
|
602
|
+
|
|
603
|
+
RCT_EXPORT_METHOD(getShowStartStopButton : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
604
|
+
BOOL show = [ShenaiSDK getShowStartStopButton];
|
|
605
|
+
resolve(@(show));
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
RCT_EXPORT_METHOD(setEnableMeasurementsDashboard : (BOOL)enable) { [ShenaiSDK setEnableMeasurementsDashboard:enable]; }
|
|
609
|
+
|
|
610
|
+
RCT_EXPORT_METHOD(getEnableMeasurementsDashboard
|
|
611
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
612
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
613
|
+
BOOL enabled = [ShenaiSDK getEnableMeasurementsDashboard];
|
|
614
|
+
resolve(@(enabled));
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
RCT_EXPORT_METHOD(setShowInfoButton : (BOOL)show) { [ShenaiSDK setShowInfoButton:show]; }
|
|
618
|
+
|
|
619
|
+
RCT_EXPORT_METHOD(getShowInfoButton : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
620
|
+
BOOL show = [ShenaiSDK getShowInfoButton];
|
|
621
|
+
resolve(@(show));
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
RCT_EXPORT_METHOD(getShowDisclaimer : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
625
|
+
BOOL show = [ShenaiSDK getShowDisclaimer];
|
|
626
|
+
resolve(@(show));
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
// Start After Success
|
|
630
|
+
RCT_EXPORT_METHOD(setEnableStartAfterSuccess : (BOOL)enable) { [ShenaiSDK setEnableStartAfterSuccess:enable]; }
|
|
631
|
+
|
|
632
|
+
RCT_EXPORT_METHOD(getEnableStartAfterSuccess
|
|
633
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
634
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
635
|
+
BOOL enable = [ShenaiSDK getEnableStartAfterSuccess];
|
|
636
|
+
resolve(@(enable));
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
// SDK Face Positioning
|
|
640
|
+
|
|
641
|
+
RCT_EXPORT_METHOD(getFaceState : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
642
|
+
FaceState faceState = [ShenaiSDK getFaceState];
|
|
643
|
+
resolve(@(faceState));
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
RCT_EXPORT_METHOD(getNormalizedFaceBbox : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
647
|
+
NormalizedFaceBbox *faceBbox = [ShenaiSDK getNormalizedFaceBbox];
|
|
648
|
+
if (faceBbox) {
|
|
649
|
+
NSDictionary *bboxDict =
|
|
650
|
+
@{@"x" : @(faceBbox.x),
|
|
651
|
+
@"y" : @(faceBbox.y),
|
|
652
|
+
@"width" : @(faceBbox.width),
|
|
653
|
+
@"height" : @(faceBbox.height)};
|
|
654
|
+
resolve(bboxDict);
|
|
655
|
+
} else {
|
|
656
|
+
resolve([NSNull null]);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
// SDK Measurement State
|
|
661
|
+
|
|
662
|
+
RCT_EXPORT_METHOD(getMeasurementState : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
663
|
+
MeasurementState measurementState = [ShenaiSDK getMeasurementState];
|
|
664
|
+
resolve(@(measurementState));
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
RCT_EXPORT_METHOD(isReadyToStartMeasurement
|
|
668
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
669
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
670
|
+
resolve(@([ShenaiSDK isReadyToStartMeasurement]));
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
RCT_EXPORT_METHOD(areRequiredModelsDownloaded
|
|
674
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
675
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
676
|
+
resolve(@([ShenaiSDK areRequiredModelsDownloaded]));
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
RCT_EXPORT_METHOD(getMeasurementProgressPercentage
|
|
680
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
681
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
682
|
+
float progressPercentage = [ShenaiSDK getMeasurementProgressPercentage];
|
|
683
|
+
resolve(@(progressPercentage));
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
// SDK Measurement Results
|
|
687
|
+
|
|
688
|
+
RCT_EXPORT_METHOD(getHeartRate10s : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
689
|
+
NSNumber *heartRate10s = [ShenaiSDK getHeartRate10s];
|
|
690
|
+
if (heartRate10s) {
|
|
691
|
+
resolve(heartRate10s);
|
|
692
|
+
} else {
|
|
693
|
+
resolve([NSNull null]);
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
RCT_EXPORT_METHOD(getHeartRate4s : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
698
|
+
NSNumber *heartRate4s = [ShenaiSDK getHeartRate4s];
|
|
699
|
+
if (heartRate4s) {
|
|
700
|
+
resolve(heartRate4s);
|
|
701
|
+
} else {
|
|
702
|
+
resolve([NSNull null]);
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
// SDK Signals
|
|
707
|
+
|
|
708
|
+
// The JS API exposes these methods on iOS as well. The underlying iOS SDK currently doesn't provide
|
|
709
|
+
// a native HR time-series, so return an empty array instead of crashing with "undefined is not a function".
|
|
710
|
+
RCT_EXPORT_METHOD(getHeartRateHistory10s
|
|
711
|
+
: (nullable NSNumber *)maxTimeSec resolver
|
|
712
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
713
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
714
|
+
(void)maxTimeSec;
|
|
715
|
+
resolve(@[]);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
RCT_EXPORT_METHOD(getHeartRateHistory4s
|
|
719
|
+
: (nullable NSNumber *)maxTimeSec resolver
|
|
720
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
721
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
722
|
+
(void)maxTimeSec;
|
|
723
|
+
resolve(@[]);
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
RCT_EXPORT_METHOD(getRealtimeHeartbeats
|
|
727
|
+
: (nullable NSNumber *)periodSec resolver
|
|
728
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
729
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
730
|
+
NSArray<Heartbeat *> *heartbeats = [ShenaiSDK getRealtimeHeartbeats:periodSec];
|
|
731
|
+
NSMutableArray *resultArray = [NSMutableArray array];
|
|
732
|
+
for (Heartbeat *heartbeat in heartbeats) {
|
|
733
|
+
[resultArray addObject:@{
|
|
734
|
+
@"startLocationSec" : @(heartbeat.startLocationSec),
|
|
735
|
+
@"endLocationSec" : @(heartbeat.endLocationSec),
|
|
736
|
+
@"durationMs" : @(heartbeat.durationMs)
|
|
737
|
+
}];
|
|
738
|
+
}
|
|
739
|
+
resolve(resultArray);
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
RCT_EXPORT_METHOD(getFullPpgSignal : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
743
|
+
NSArray<NSNumber *> *ppgSignal = [ShenaiSDK getFullPPGSignal];
|
|
744
|
+
resolve(ppgSignal);
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
// SDK Recording
|
|
748
|
+
|
|
749
|
+
RCT_EXPORT_METHOD(setRecordingEnabled : (BOOL)enabled) { [ShenaiSDK setRecordingEnabled:enabled]; }
|
|
750
|
+
|
|
751
|
+
RCT_EXPORT_METHOD(getRecordingEnabled : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
752
|
+
BOOL isEnabled = [ShenaiSDK isRecordingEnabled];
|
|
753
|
+
resolve(@(isEnabled));
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
// SDK Quality Control
|
|
757
|
+
|
|
758
|
+
RCT_EXPORT_METHOD(getTotalBadSignalSeconds : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
759
|
+
float totalBadSeconds = [ShenaiSDK getTotalBadSignalSeconds];
|
|
760
|
+
resolve(@(totalBadSeconds));
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
RCT_EXPORT_METHOD(getCurrentSignalQualityMetric
|
|
764
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
765
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
766
|
+
float signalQuality = [ShenaiSDK getCurrentSignalQualityMetric];
|
|
767
|
+
resolve(@(signalQuality));
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
// SDK Visualizations
|
|
771
|
+
|
|
772
|
+
RCT_EXPORT_METHOD(getSignalQualityMapPng : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
773
|
+
NSData *data = [ShenaiSDK getSignalQualityMapPng];
|
|
774
|
+
if (!data || data.length == 0) {
|
|
775
|
+
resolve([NSNull null]);
|
|
776
|
+
return;
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
const UInt8 *buffer = (const UInt8 *)data.bytes;
|
|
780
|
+
NSUInteger length = data.length;
|
|
781
|
+
NSMutableArray *array = [NSMutableArray arrayWithCapacity:length];
|
|
782
|
+
for (NSUInteger i = 0; i < length; i++) {
|
|
783
|
+
[array addObject:@(buffer[i])];
|
|
784
|
+
}
|
|
785
|
+
resolve(array);
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
RCT_EXPORT_METHOD(getFaceTexturePng : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
789
|
+
NSData *data = [ShenaiSDK getFaceTexturePng];
|
|
790
|
+
if (!data || data.length == 0) {
|
|
791
|
+
resolve([NSNull null]);
|
|
792
|
+
return;
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
const UInt8 *buffer = (const UInt8 *)data.bytes;
|
|
796
|
+
NSUInteger length = data.length;
|
|
797
|
+
NSMutableArray *array = [NSMutableArray arrayWithCapacity:length];
|
|
798
|
+
for (NSUInteger i = 0; i < length; i++) {
|
|
799
|
+
[array addObject:@(buffer[i])];
|
|
800
|
+
}
|
|
801
|
+
resolve(array);
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
RCT_EXPORT_METHOD(setLanguage : (NSString *)language) { [ShenaiSDK setLanguage:language]; }
|
|
805
|
+
|
|
806
|
+
// Utility method to convert RisksFactors JS object to RisksFactors Objective-C object
|
|
807
|
+
- (RisksFactors *)risksFactorsFromDictionary:(NSDictionary *)dict {
|
|
808
|
+
RisksFactors *factors = [[RisksFactors alloc] initWithAge:dict[@"age"]
|
|
809
|
+
cholesterol:dict[@"cholesterol"]
|
|
810
|
+
cholesterolHDL:dict[@"cholesterolHdl"]
|
|
811
|
+
sbp:dict[@"sbp"]
|
|
812
|
+
dbp:dict[@"dbp"]
|
|
813
|
+
isSmoker:dict[@"isSmoker"]
|
|
814
|
+
hypertensionTreatment:[dict[@"hypertensionTreatment"] integerValue]
|
|
815
|
+
hasDiabetes:dict[@"hasDiabetes"]
|
|
816
|
+
bodyHeight:dict[@"bodyHeight"]
|
|
817
|
+
bodyWeight:dict[@"bodyWeight"]
|
|
818
|
+
waistCircumference:dict[@"waistCircumference"]
|
|
819
|
+
neckCircumference:dict[@"neckCircumference"]
|
|
820
|
+
hipCircumference:dict[@"hipCircumference"]
|
|
821
|
+
gender:[dict[@"gender"] integerValue]
|
|
822
|
+
physicalActivity:[dict[@"physicalActivity"] integerValue]
|
|
823
|
+
country:dict[@"country"]
|
|
824
|
+
race:[dict[@"race"] integerValue]
|
|
825
|
+
vegetableFruitDiet:dict[@"vegetableFruitDiet"]
|
|
826
|
+
historyOfHighGlucose:dict[@"historyOfHighGlucose"]
|
|
827
|
+
historyOfHypertension:dict[@"historyOfHypertension"]
|
|
828
|
+
triglyceride:dict[@"triglyceride"]
|
|
829
|
+
fastingGlucose:dict[@"fastingGlucose"]
|
|
830
|
+
familyDiabetes:[dict[@"familyDiabetes"] integerValue]
|
|
831
|
+
parentalHypertension:[dict[@"parentalHypertension"] integerValue]];
|
|
832
|
+
return factors;
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
- (NSDictionary *)dictionaryFromRisksFactors:(RisksFactors *)factors {
|
|
836
|
+
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
|
|
837
|
+
|
|
838
|
+
if (factors.age != nil) dict[@"age"] = factors.age;
|
|
839
|
+
if (factors.cholesterol != nil) dict[@"cholesterol"] = factors.cholesterol;
|
|
840
|
+
if (factors.cholesterolHDL != nil) dict[@"cholesterolHdl"] = factors.cholesterolHDL;
|
|
841
|
+
if (factors.sbp != nil) dict[@"sbp"] = factors.sbp;
|
|
842
|
+
if (factors.dbp != nil) dict[@"dbp"] = factors.dbp;
|
|
843
|
+
if (factors.isSmoker != nil) dict[@"isSmoker"] = factors.isSmoker;
|
|
844
|
+
if (factors.hypertensionTreatment != nil) dict[@"hypertensionTreatment"] = @(factors.hypertensionTreatment);
|
|
845
|
+
if (factors.hasDiabetes != nil) dict[@"hasDiabetes"] = factors.hasDiabetes;
|
|
846
|
+
if (factors.bodyHeight != nil) dict[@"bodyHeight"] = factors.bodyHeight;
|
|
847
|
+
if (factors.bodyWeight != nil) dict[@"bodyWeight"] = factors.bodyWeight;
|
|
848
|
+
if (factors.waistCircumference != nil) dict[@"waistCircumference"] = factors.waistCircumference;
|
|
849
|
+
if (factors.neckCircumference != nil) dict[@"neckCircumference"] = factors.neckCircumference;
|
|
850
|
+
if (factors.hipCircumference != nil) dict[@"hipCircumference"] = factors.hipCircumference;
|
|
851
|
+
if (factors.gender != nil) dict[@"gender"] = @(factors.gender);
|
|
852
|
+
if (factors.physicalActivity != nil) dict[@"physicalActivity"] = @(factors.physicalActivity);
|
|
853
|
+
if (factors.country != nil) dict[@"country"] = factors.country;
|
|
854
|
+
if (factors.race != nil) dict[@"race"] = @(factors.race);
|
|
855
|
+
if (factors.vegetableFruitDiet != nil) dict[@"vegetableFruitDiet"] = factors.vegetableFruitDiet;
|
|
856
|
+
if (factors.historyOfHighGlucose != nil) dict[@"historyOfHighGlucose"] = factors.historyOfHighGlucose;
|
|
857
|
+
if (factors.historyOfHypertension != nil) dict[@"historyOfHypertension"] = factors.historyOfHypertension;
|
|
858
|
+
if (factors.fastingGlucose != nil) dict[@"fastingGlucose"] = factors.fastingGlucose;
|
|
859
|
+
if (factors.triglyceride != nil) dict[@"triglyceride"] = factors.triglyceride;
|
|
860
|
+
if (factors.parentalHypertension != nil) dict[@"parentalHypertension"] = @(factors.parentalHypertension);
|
|
861
|
+
if (factors.familyDiabetes != nil) dict[@"familyDiabetes"] = @(factors.familyDiabetes);
|
|
862
|
+
|
|
863
|
+
return [dict copy];
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
// Convert HealthRisks object to NSDictionary for JS
|
|
867
|
+
- (NSDictionary *)dictionaryFromHealthRisks:(HealthRisks *)risks {
|
|
868
|
+
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
|
|
869
|
+
|
|
870
|
+
// HardAndFatalEventsRisks conversion
|
|
871
|
+
NSMutableDictionary *hardAndFatalEventsDict = [NSMutableDictionary dictionary];
|
|
872
|
+
if (risks.hardAndFatalEvents.coronaryDeathEventRisk != nil) {
|
|
873
|
+
hardAndFatalEventsDict[@"coronaryDeathEventRisk"] = risks.hardAndFatalEvents.coronaryDeathEventRisk;
|
|
874
|
+
}
|
|
875
|
+
if (risks.hardAndFatalEvents.fatalStrokeEventRisk != nil) {
|
|
876
|
+
hardAndFatalEventsDict[@"fatalStrokeEventRisk"] = risks.hardAndFatalEvents.fatalStrokeEventRisk;
|
|
877
|
+
}
|
|
878
|
+
if (risks.hardAndFatalEvents.totalCvMortalityRisk != nil) {
|
|
879
|
+
hardAndFatalEventsDict[@"totalCvMortalityRisk"] = risks.hardAndFatalEvents.totalCvMortalityRisk;
|
|
880
|
+
}
|
|
881
|
+
if (risks.hardAndFatalEvents.hardCvEventRisk != nil) {
|
|
882
|
+
hardAndFatalEventsDict[@"hardCvEventRisk"] = risks.hardAndFatalEvents.hardCvEventRisk;
|
|
883
|
+
}
|
|
884
|
+
dict[@"hardAndFatalEvents"] = [hardAndFatalEventsDict copy];
|
|
885
|
+
|
|
886
|
+
// CVDiseasesRisks conversion
|
|
887
|
+
NSMutableDictionary *cvDiseasesDict = [NSMutableDictionary dictionary];
|
|
888
|
+
if (risks.cvDiseases.overallRisk != nil) {
|
|
889
|
+
cvDiseasesDict[@"overallRisk"] = risks.cvDiseases.overallRisk;
|
|
890
|
+
}
|
|
891
|
+
if (risks.cvDiseases.coronaryHeartDiseaseRisk != nil) {
|
|
892
|
+
cvDiseasesDict[@"coronaryHeartDiseaseRisk"] = risks.cvDiseases.coronaryHeartDiseaseRisk;
|
|
893
|
+
}
|
|
894
|
+
if (risks.cvDiseases.strokeRisk != nil) {
|
|
895
|
+
cvDiseasesDict[@"strokeRisk"] = risks.cvDiseases.strokeRisk;
|
|
896
|
+
}
|
|
897
|
+
if (risks.cvDiseases.heartFailureRisk != nil) {
|
|
898
|
+
cvDiseasesDict[@"heartFailureRisk"] = risks.cvDiseases.heartFailureRisk;
|
|
899
|
+
}
|
|
900
|
+
if (risks.cvDiseases.peripheralVascularDiseaseRisk != nil) {
|
|
901
|
+
cvDiseasesDict[@"peripheralVascularDiseaseRisk"] = risks.cvDiseases.peripheralVascularDiseaseRisk;
|
|
902
|
+
}
|
|
903
|
+
dict[@"cvDiseases"] = [cvDiseasesDict copy];
|
|
904
|
+
|
|
905
|
+
// RisksFactorsScores conversion
|
|
906
|
+
NSMutableDictionary *risksFactorsScoresDict = [NSMutableDictionary dictionary];
|
|
907
|
+
if (risks.scores.ageScore != nil) {
|
|
908
|
+
risksFactorsScoresDict[@"ageScore"] = risks.scores.ageScore;
|
|
909
|
+
}
|
|
910
|
+
if (risks.scores.sbpScore != nil) {
|
|
911
|
+
risksFactorsScoresDict[@"sbpScore"] = risks.scores.sbpScore;
|
|
912
|
+
}
|
|
913
|
+
if (risks.scores.smokingScore != nil) {
|
|
914
|
+
risksFactorsScoresDict[@"smokingScore"] = risks.scores.smokingScore;
|
|
915
|
+
}
|
|
916
|
+
if (risks.scores.diabetesScore != nil) {
|
|
917
|
+
risksFactorsScoresDict[@"diabetesScore"] = risks.scores.diabetesScore;
|
|
918
|
+
}
|
|
919
|
+
if (risks.scores.bmiScore != nil) {
|
|
920
|
+
risksFactorsScoresDict[@"bmiScore"] = risks.scores.bmiScore;
|
|
921
|
+
}
|
|
922
|
+
if (risks.scores.cholesterolScore != nil) {
|
|
923
|
+
risksFactorsScoresDict[@"cholesterolScore"] = risks.scores.cholesterolScore;
|
|
924
|
+
}
|
|
925
|
+
if (risks.scores.cholesterolHdlScore != nil) {
|
|
926
|
+
risksFactorsScoresDict[@"cholesterolHdlScore"] = risks.scores.cholesterolHdlScore;
|
|
927
|
+
}
|
|
928
|
+
if (risks.scores.totalScore != nil) {
|
|
929
|
+
risksFactorsScoresDict[@"totalScore"] = risks.scores.totalScore;
|
|
930
|
+
}
|
|
931
|
+
dict[@"scores"] = [risksFactorsScoresDict copy];
|
|
932
|
+
|
|
933
|
+
// Vascular Age
|
|
934
|
+
if (risks.vascularAge != nil) {
|
|
935
|
+
dict[@"vascularAge"] = risks.vascularAge;
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
// Wellness Score
|
|
939
|
+
if (risks.wellnessScore != nil) {
|
|
940
|
+
dict[@"wellnessScore"] = risks.wellnessScore;
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
// WHtR, BFP, BMR
|
|
944
|
+
if (risks.waistToHeightRatio != nil) {
|
|
945
|
+
dict[@"waistToHeightRatio"] = risks.waistToHeightRatio;
|
|
946
|
+
}
|
|
947
|
+
if (risks.bodyFatPercentage != nil) {
|
|
948
|
+
dict[@"bodyFatPercentage"] = risks.bodyFatPercentage;
|
|
949
|
+
}
|
|
950
|
+
if (risks.basalMetabolicRate != nil) {
|
|
951
|
+
dict[@"basalMetabolicRate"] = risks.basalMetabolicRate;
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
// ABSI, BRI, CI, TDEE
|
|
955
|
+
if (risks.aBodyShapeIndex != nil) {
|
|
956
|
+
dict[@"aBodyShapeIndex"] = risks.aBodyShapeIndex;
|
|
957
|
+
}
|
|
958
|
+
if (risks.bodyRoundnessIndex != nil) {
|
|
959
|
+
dict[@"bodyRoundnessIndex"] = risks.bodyRoundnessIndex;
|
|
960
|
+
}
|
|
961
|
+
if (risks.conicityIndex != nil) {
|
|
962
|
+
dict[@"conicityIndex"] = risks.conicityIndex;
|
|
963
|
+
}
|
|
964
|
+
if (risks.totalDailyEnergyExpenditure != nil) {
|
|
965
|
+
dict[@"totalDailyEnergyExpenditure"] = risks.totalDailyEnergyExpenditure;
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
// HR, DR, NAFLDR
|
|
969
|
+
if (risks.hypertensionRisk != nil) {
|
|
970
|
+
dict[@"hypertensionRisk"] = risks.hypertensionRisk;
|
|
971
|
+
}
|
|
972
|
+
if (risks.diabetesRisk != nil) {
|
|
973
|
+
dict[@"diabetesRisk"] = risks.diabetesRisk;
|
|
974
|
+
}
|
|
975
|
+
if (risks.nonAlcoholicFattyLiverDiseaseRisk != nil) {
|
|
976
|
+
dict[@"nonAlcoholicFattyLiverDiseaseRisk"] = @(risks.nonAlcoholicFattyLiverDiseaseRisk);
|
|
977
|
+
}
|
|
978
|
+
return [dict copy];
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
RCT_EXPORT_METHOD(getHealthRisksFactors : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
982
|
+
RisksFactors *factors = [ShenaiHealthRisks getHealthRisksFactors];
|
|
983
|
+
NSDictionary *resultsDict = [self dictionaryFromRisksFactors:factors];
|
|
984
|
+
resolve(resultsDict);
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
RCT_EXPORT_METHOD(clearHealthRisksFactors : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
988
|
+
[ShenaiHealthRisks clearHealthRisksFactors];
|
|
989
|
+
resolve(nil);
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
RCT_EXPORT_METHOD(getHealthRisks : (RCTPromiseResolveBlock)resolve rejecter : (RCTPromiseRejectBlock)reject) {
|
|
993
|
+
HealthRisks *risks = [ShenaiHealthRisks getHealthRisks];
|
|
994
|
+
NSDictionary *resultsDict = [self dictionaryFromHealthRisks:risks];
|
|
995
|
+
resolve(resultsDict);
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
RCT_EXPORT_METHOD(computeHealthRisks
|
|
999
|
+
: (NSDictionary *)factorsDict resolver
|
|
1000
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
1001
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
1002
|
+
RisksFactors *factors = [self risksFactorsFromDictionary:factorsDict];
|
|
1003
|
+
HealthRisks *risks = [ShenaiHealthRisks computeHealthRisks:factors];
|
|
1004
|
+
NSDictionary *resultsDict = [self dictionaryFromHealthRisks:risks];
|
|
1005
|
+
resolve(resultsDict);
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
RCT_EXPORT_METHOD(getMaximalRisks
|
|
1009
|
+
: (NSDictionary *)factorsDict resolver
|
|
1010
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
1011
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
1012
|
+
RisksFactors *factors = [self risksFactorsFromDictionary:factorsDict];
|
|
1013
|
+
HealthRisks *risks = [ShenaiHealthRisks getMaximalRisks:factors];
|
|
1014
|
+
NSDictionary *resultsDict = [self dictionaryFromHealthRisks:risks];
|
|
1015
|
+
resolve(resultsDict);
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
RCT_EXPORT_METHOD(getMinimalRisks
|
|
1019
|
+
: (NSDictionary *)factorsDict resolver
|
|
1020
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
1021
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
1022
|
+
RisksFactors *factors = [self risksFactorsFromDictionary:factorsDict];
|
|
1023
|
+
HealthRisks *risks = [ShenaiHealthRisks getMinimalRisks:factors];
|
|
1024
|
+
NSDictionary *resultsDict = [self dictionaryFromHealthRisks:risks];
|
|
1025
|
+
resolve(resultsDict);
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
RCT_EXPORT_METHOD(getReferenceRisks
|
|
1029
|
+
: (NSDictionary *)factorsDict resolver
|
|
1030
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
1031
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
1032
|
+
RisksFactors *factors = [self risksFactorsFromDictionary:factorsDict];
|
|
1033
|
+
HealthRisks *risks = [ShenaiHealthRisks getReferenceRisks:factors];
|
|
1034
|
+
NSDictionary *resultsDict = [self dictionaryFromHealthRisks:risks];
|
|
1035
|
+
resolve(resultsDict);
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
RCT_EXPORT_METHOD(openMeasurementResultsPdfInBrowser
|
|
1039
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
1040
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
1041
|
+
[ShenaiSDK openMeasurementResultsPdfInBrowser];
|
|
1042
|
+
resolve(@(YES));
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
RCT_EXPORT_METHOD(sendMeasurementResultsPdfToEmail
|
|
1046
|
+
: (NSString *)email resolver
|
|
1047
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
1048
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
1049
|
+
[ShenaiSDK sendMeasurementResultsPdfToEmail:email];
|
|
1050
|
+
resolve(@(YES));
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
RCT_EXPORT_METHOD(requestMeasurementResultsPdfUrl
|
|
1054
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
1055
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
1056
|
+
[ShenaiSDK requestMeasurementResultsPdfUrl];
|
|
1057
|
+
resolve(@(YES));
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
RCT_EXPORT_METHOD(getMeasurementResultsPdfUrl
|
|
1061
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
1062
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
1063
|
+
NSString *url = [ShenaiSDK getMeasurementResultsPdfUrl];
|
|
1064
|
+
if (url && url.length > 0) {
|
|
1065
|
+
resolve(url);
|
|
1066
|
+
} else {
|
|
1067
|
+
resolve([NSNull null]);
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
RCT_EXPORT_METHOD(requestMeasurementResultsPdfBytes
|
|
1072
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
1073
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
1074
|
+
[ShenaiSDK requestMeasurementResultsPdfBytes];
|
|
1075
|
+
resolve(@(YES));
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
RCT_EXPORT_METHOD(getMeasurementResultsPdfBytes
|
|
1079
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
1080
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
1081
|
+
NSData *data = [ShenaiSDK getMeasurementResultsPdfBytes];
|
|
1082
|
+
if (!data) {
|
|
1083
|
+
resolve([NSNull null]);
|
|
1084
|
+
return;
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
const UInt8 *buffer = (const UInt8 *)data.bytes;
|
|
1088
|
+
NSUInteger length = data.length;
|
|
1089
|
+
NSMutableArray *array = [NSMutableArray arrayWithCapacity:length];
|
|
1090
|
+
for (NSUInteger i = 0; i < length; i++) {
|
|
1091
|
+
[array addObject:@(buffer[i])]; // wrap each byte as NSNumber
|
|
1092
|
+
}
|
|
1093
|
+
resolve(array);
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
RCT_EXPORT_METHOD(getResultAsFhirObservation
|
|
1097
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
1098
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
1099
|
+
NSString *observation = [ShenaiSDK getResultAsFhirObservation];
|
|
1100
|
+
if (observation && observation.length > 0) {
|
|
1101
|
+
resolve(observation);
|
|
1102
|
+
} else {
|
|
1103
|
+
resolve([NSNull null]);
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
RCT_EXPORT_METHOD(sendResultFhirObservation
|
|
1108
|
+
: (NSString *)url resolver
|
|
1109
|
+
: (RCTPromiseResolveBlock)resolve rejecter
|
|
1110
|
+
: (RCTPromiseRejectBlock)reject) {
|
|
1111
|
+
[ShenaiSDK sendResultFhirObservation:url
|
|
1112
|
+
completion:^(NSString *_Nullable response) {
|
|
1113
|
+
if (response && response.length > 0) {
|
|
1114
|
+
resolve(response);
|
|
1115
|
+
} else {
|
|
1116
|
+
resolve([NSNull null]);
|
|
1117
|
+
}
|
|
1118
|
+
}];
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
@end
|