react-native-mytatva-rn-sdk 1.2.53 → 1.2.55

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.
@@ -63,7 +63,7 @@ class CgmTrackyLibModule(reactContext: ReactApplicationContext) :
63
63
  var authenticateSDKService: AuthenticateSDKService
64
64
  private val job = Job()
65
65
  private val scope = CoroutineScope(Dispatchers.IO + job)
66
- var prefsHelper: SharedPreferencesLibraryUtil
66
+ var prefsHelper: SharedPreferencesLibraryUtil? = null
67
67
  private val apiScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
68
68
  private var debounceJob: Job? = null
69
69
  private var isBatchProcessing = false
@@ -184,18 +184,17 @@ class CgmTrackyLibModule(reactContext: ReactApplicationContext) :
184
184
  }
185
185
  }
186
186
  )*/
187
-
188
187
  val response = Gson().fromJson(apiResponse, CgmSensorResponse::class.java)
189
188
  val sensor = response.data?.firstOrNull()
190
189
 
190
+
191
191
  if (sensor != null && !sensor.startDate.isNullOrEmpty() && !sensor.endDate.isNullOrEmpty()) {
192
192
  val startDate = sensor.startDate
193
193
  val endDate = sensor.endDate
194
194
  val sensorId = sensor.sensorId
195
195
  val currentPatientId = patientId
196
-
197
- val lastPatientId = prefsHelper.lastPatientId
198
- val lastSensorId = prefsHelper.qrInformation.sensor
196
+ val lastPatientId = prefsHelper?.lastPatientId
197
+ val lastSensorId = prefsHelper?.qrInformation?.sensor
199
198
 
200
199
  if (lastPatientId != null && lastSensorId != null && (lastPatientId != currentPatientId || lastSensorId != sensorId)) {
201
200
  mModel.clearAllGlucoseAndDeviceData()
@@ -216,8 +215,8 @@ class CgmTrackyLibModule(reactContext: ReactApplicationContext) :
216
215
  pocDevice.qrMessage, envType
217
216
  )
218
217
  } else {
219
- prefsHelper.lastPatientId = currentPatientId
220
- prefsHelper.qrInformation.sensor = sensorId
218
+ prefsHelper?.lastPatientId = currentPatientId
219
+ prefsHelper?.qrInformation?.sensor = sensorId
221
220
  }
222
221
  } else {
223
222
  postEventDataToAPI(
@@ -425,7 +424,7 @@ class CgmTrackyLibModule(reactContext: ReactApplicationContext) :
425
424
  val currentTime = System.currentTimeMillis()
426
425
  var dataAge = System.currentTimeMillis()
427
426
 
428
- val lastSyncData = prefsHelper.lastSyncData
427
+ val lastSyncData = prefsHelper?.lastSyncData
429
428
  val currentSyncTimeInMillis = lastSyncData?.timeInMillis
430
429
 
431
430
  if (lastSyncData != null) {
@@ -606,7 +605,7 @@ class CgmTrackyLibModule(reactContext: ReactApplicationContext) :
606
605
 
607
606
  Handler(Looper.getMainLooper()).postDelayed({
608
607
  try {
609
- val lastSyncData = prefsHelper.lastSyncData
608
+ val lastSyncData = prefsHelper?.lastSyncData
610
609
  Log.d("lastSyncData: ", Gson().toJson(lastSyncData).toString())
611
610
 
612
611
  val currentTime = System.currentTimeMillis()
@@ -720,7 +719,7 @@ class CgmTrackyLibModule(reactContext: ReactApplicationContext) :
720
719
  lastDeviceStatus = null
721
720
 
722
721
  // Clear any cached data if needed
723
- prefsHelper.clearQRInformation() // if you have such method
722
+ prefsHelper?.clearQRInformation() // if you have such method
724
723
 
725
724
  // Reset last processed sync time
726
725
  lastProcessedSyncTimeInMillis = null
@@ -915,7 +914,7 @@ class CgmTrackyLibModule(reactContext: ReactApplicationContext) :
915
914
  it.deviceId,
916
915
  it.glucoseId
917
916
  )
918
- prefsHelper.lastSyncData = syncData
917
+ prefsHelper?.lastSyncData = syncData
919
918
  lastProcessedSyncTimeInMillis = null
920
919
  Log.d(
921
920
  "Sync Metadata",
@@ -31,7 +31,17 @@ NS_ASSUME_NONNULL_BEGIN
31
31
  @property (nullable, nonatomic, copy) NSNumber *trend;
32
32
  @property (nullable, nonatomic, copy) NSNumber *userBG;
33
33
  @property (nullable, nonatomic, retain) Device *device;
34
-
34
+ @property (nullable, nonatomic, copy) NSNumber *glucoseId;
35
+ @property (nullable, nonatomic, copy) NSNumber *isDelete;
36
+ @property (nullable, nonatomic, copy) NSNumber *year;
37
+ @property (nullable, nonatomic, copy) NSNumber *countdownDays;
38
+ @property (nullable, nonatomic, copy) NSNumber *countdownHours;
39
+ @property (nullable, nonatomic, copy) NSNumber *countdownMinutes;
40
+ @property (nullable, nonatomic, copy) NSNumber *minute;
41
+ @property (nullable, nonatomic, copy) NSNumber *month;
42
+ @property (nullable, nonatomic, copy) NSNumber *day;
43
+ @property (nullable, nonatomic, copy) NSNumber *hour;
44
+ @property (nullable, nonatomic, copy) NSNumber *error;
35
45
  @end
36
46
 
37
47
  NS_ASSUME_NONNULL_END
@@ -24,11 +24,21 @@
24
24
  @dynamic initialBeginDate;
25
25
  @dynamic iw;
26
26
  @dynamic k;
27
+ @dynamic error;
27
28
  @dynamic operatingCurrent;
28
29
  @dynamic receiveDateTime;
29
30
  @dynamic temperature;
30
31
  @dynamic trend;
31
32
  @dynamic userBG;
32
33
  @dynamic device;
33
-
34
+ @dynamic year;
35
+ @dynamic countdownDays;
36
+ @dynamic countdownHours;
37
+ @dynamic countdownMinutes;
38
+ @dynamic isDelete;
39
+ @dynamic glucoseId;
40
+ @dynamic minute;
41
+ @dynamic month;
42
+ @dynamic day;
43
+ @dynamic hour;
34
44
  @end
@@ -383,6 +383,7 @@
383
383
  #pragma mark - 发射器通用接受数据处理、算法计算处理
384
384
 
385
385
  // 发射器处理单条血糖数据的算法调用保存
386
+ //Is the algorithm used by the transmitter to process a single glucose data point also responsible for saving it?
386
387
  - (void)handleCommonCT3GlucoseDataWithReceiveData:(ReceiveData *)receiveData {
387
388
  int glucoseId = receiveData.glucoseId.intValue;
388
389
  if (glucoseId >= self.eDevice.initNumber - 1) {
@@ -508,6 +509,7 @@
508
509
  }
509
510
 
510
511
  // CT3 CT4重传的数据,pullGlucose_series_request 22的返回
512
+ //Retransmitted data from CT3 and CT4, response of pullGlucose_series_request 0x22
511
513
  - (void)handleResendDataWithPrefix22:(NSData *)resendData {
512
514
  NSArray<Glucose *> *glucoseList = [ProtocalTools getGlucose_series:resendData andEDevice:self.eDevice];
513
515
  if (glucoseList.count == 0) {
@@ -524,8 +526,7 @@
524
526
  self.isFromPrefix22 = YES;
525
527
  [self handleCommonCT3GlucoseDataWithReceiveData:receive];
526
528
  }
527
-
528
-
529
+
529
530
  [Notification_Center postNotificationName:KLTUpdateDataNotify object:NULL];
530
531
  NSLog(@"----------------------------------------------called handleResendDataWithPrefix22 for KLTUpdateDataNotify");
531
532
  NSInteger maxGlucoseId = [KLTDatabaseHandler.shared getLatestAndMaxGlucoseIdOfDevice:self.currentDevice];
@@ -63,7 +63,7 @@
63
63
  data.countdownHours = @(currentGlucose.countdownHours);
64
64
  data.countdownMinutes = @(currentGlucose.countdownMinutes);
65
65
 
66
- [Notification_Center postNotificationName:@"ErrorStatusFromTransmitter" object:data];
66
+ // [Notification_Center postNotificationName:@"ErrorStatusFromTransmitter" object:data];
67
67
  [self.appDelegate saveContext];
68
68
  }
69
69
 
@@ -123,6 +123,8 @@
123
123
  GlucoseData *glucose = [NSEntityDescription insertNewObjectForEntityForName:@"GlucoseData" inManagedObjectContext:self.context];
124
124
  glucose.userBG = data.userBG;
125
125
  glucose.dataId = data.glucoseId;
126
+ glucose.device = data.device;
127
+ glucose.isDelete = 0;
126
128
 
127
129
  glucose.receiveDateTime = [NSString stringWithFormat:@"%@-%02d-%02d %02d:%02d",data.year,[data.month intValue],[data.day intValue],[data.hour intValue],[data.minute intValue]];
128
130
  glucose.initialBeginDate = data.device.initialBeginDate;
@@ -177,7 +179,20 @@
177
179
  data.countdownHours = @(currentGlucose.countdownHours);
178
180
  data.countdownMinutes = @(currentGlucose.countdownMinutes);
179
181
 
180
- [Notification_Center postNotificationName:@"ErrorStatusFromTransmitter" object:data];
182
+ glucose.countdownDays = @(currentGlucose.countdownDays);
183
+ glucose.countdownHours = @(currentGlucose.countdownHours);
184
+ glucose.countdownMinutes = @(currentGlucose.countdownMinutes);
185
+ glucose.year = data.year;
186
+ glucose.glucoseId = data.glucoseId;
187
+ glucose.month = data.month;
188
+ glucose.day = data.day;
189
+ glucose.minute = data.minute;
190
+ glucose.hour = data.hour;
191
+ glucose.error = data.error;
192
+
193
+ // [Notification_Center postNotificationName:@"ErrorStatusFromTransmitter" object: glucose];
194
+ [Notification_Center postNotificationName:@"CheckErrorStatusFromLastBatchData" object: glucose];
195
+
181
196
  [self.appDelegate saveContext];
182
197
  return glucose;
183
198
  }
@@ -216,7 +231,7 @@
216
231
  // 🖨️ Add single-line logging for each GlucoseData entry
217
232
  NSLog(@"==== GlucoseData (Fetched %lu records) for Device: %@ ====", (unsigned long)resendDatas.count, currentDevice.identifier);
218
233
  for (GlucoseData *g in resendDatas) {
219
- NSLog(@"[ID:%@] Date:%@ | glu:%@ mmol/L | gluADC:%@ mg/dL | BG:%@ | T:%@°C | Ib:%@ | Iw:%@ | Trend:%@ | Err:%@ | CalStatus:%@",
234
+ NSLog(@"[ID:%@] Date:%@ | glu:%@ mmol/L | gluADC:%@ mg/dL | BG:%@ | T:%@°C | Ib:%@ | Iw:%@ | Trend:%@ | Err:%@ | CalStatus:%@ | countdownMinut:%@ | countdownHours:%@ | countdownDays:%@" ,
220
235
  g.dataId,
221
236
  g.receiveDateTime,
222
237
  g.glu,
@@ -227,7 +242,11 @@
227
242
  g.operatingCurrent,
228
243
  g.trend,
229
244
  g.errorCode,
230
- g.calibrationStatus
245
+ g.calibrationStatus,
246
+ g.countdownMinutes,
247
+ g.countdownHours,
248
+ g.countdownDays
249
+
231
250
  );
232
251
  }
233
252
 
@@ -396,6 +415,7 @@
396
415
  }
397
416
 
398
417
  // 查询最近一次连接的最大的血糖ID
418
+ //Query the highest glucose ID from the most recent connection.
399
419
  - (NSInteger)getLatestAndMaxGlucoseIdOfDevice:(Device *)currentDevice {
400
420
  NSArray *array = [self queryReceiveDataWithDevice:currentDevice needUserBG:NO];
401
421
  if (array.count > 0) {
@@ -406,6 +426,7 @@
406
426
  }
407
427
 
408
428
  // 获取距离某个设备的到期时间还剩多少数据没有接收完
429
+ //Get how much data remains to be received before the device reaches its expiration time
409
430
  - (NSInteger)numberOfLifeCycleSensorWithDevice:(Device *)currentDevice endNumber:(int)endNumber {
410
431
  if (currentDevice) {
411
432
  NSArray *array = [self queryReceiveDataWithDevice:currentDevice needUserBG:NO];
@@ -415,7 +436,7 @@
415
436
  }
416
437
 
417
438
  #pragma mark - APP重启后需要手动调用历史数据
418
-
439
+ //After restarting the app, is it necessary to manually request historical data?
419
440
  - (void)reloadQueryHistoryData {
420
441
  Device *currentDevice = KLTBluetoothManager.sharedManager.currentDevice;
421
442
  if (nil == currentDevice) {
@@ -459,6 +480,7 @@
459
480
  data.TsCount = (int)index + 1;
460
481
 
461
482
  // 校准后的点
483
+ //Point after calibration
462
484
  NSArray<ReceiveData*> *needUserBgs = [self queryReceiveDataWithDevice:currentDevice needUserBG:YES];
463
485
  NSUInteger numberOfUserBgs = needUserBgs.count;
464
486
  if (needUserBgs.count > 0) {
@@ -1,5 +1,5 @@
1
1
  <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
- <model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="23605" systemVersion="24C101" minimumToolsVersion="Automatic" sourceLanguage="Swift" usedWithSwiftData="YES" userDefinedModelVersionIdentifier="">
2
+ <model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="23788.4" systemVersion="24F74" minimumToolsVersion="Automatic" sourceLanguage="Swift" usedWithSwiftData="YES" userDefinedModelVersionIdentifier="">
3
3
  <entity name="Advertise" representedClassName="Advertise" syncable="YES">
4
4
  <attribute name="advertiseDateTime" optional="YES" attributeType="String"/>
5
5
  <attribute name="isConnectable" optional="YES" attributeType="Boolean" usesScalarValueType="NO"/>
@@ -24,18 +24,29 @@
24
24
  <entity name="GlucoseData" representedClassName="GlucoseData" syncable="YES">
25
25
  <attribute name="blankCurrent" optional="YES" attributeType="Double" defaultValueString="0" usesScalarValueType="NO"/>
26
26
  <attribute name="calibrationStatus" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="NO"/>
27
+ <attribute name="countdownDays" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
28
+ <attribute name="countdownHours" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
29
+ <attribute name="countdownMinutes" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
27
30
  <attribute name="dataId" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="NO"/>
31
+ <attribute name="day" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
32
+ <attribute name="error" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
28
33
  <attribute name="errorCode" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="NO"/>
29
34
  <attribute name="glu" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="NO"/>
30
35
  <attribute name="gluADC" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="NO"/>
36
+ <attribute name="glucoseId" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
37
+ <attribute name="hour" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
31
38
  <attribute name="initialBeginDate" optional="YES" attributeType="String"/>
39
+ <attribute name="isDelete" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
32
40
  <attribute name="iw" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="NO"/>
33
41
  <attribute name="k" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="NO"/>
42
+ <attribute name="minute" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
43
+ <attribute name="month" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
34
44
  <attribute name="operatingCurrent" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="NO"/>
35
45
  <attribute name="receiveDateTime" optional="YES" attributeType="String"/>
36
46
  <attribute name="temperature" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="NO"/>
37
47
  <attribute name="trend" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="NO"/>
38
48
  <attribute name="userBG" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="NO"/>
49
+ <attribute name="year" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
39
50
  <relationship name="device" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Device"/>
40
51
  </entity>
41
52
  <entity name="ReceiveDataInfo" representedClassName="ReceiveData" syncable="YES">
@@ -10,6 +10,7 @@ import CommonCrypto
10
10
 
11
11
  let PROD_API_KEY = "lChjFRJce3bxmoS3TSQk5w=="
12
12
  let STAGE_API_KEY = "lChjFRJce3bxmoS3TSQk5w=="
13
+
13
14
  let PROD_BASE_URL = "https://api.mytatva.in/api/v8"
14
15
  let STAGE_BASE_URL = "https://api-uat.mytatva.in/api/v8"
15
16
 
@@ -97,6 +98,7 @@ class API {
97
98
 
98
99
  func postCGMData(
99
100
  data: Payload,
101
+ environment: TatvaEnvironment,
100
102
  token: String = TOKEN,
101
103
  encryptionKey: String = PROD_ENC_KEY,
102
104
  encryptionIv: String = PROD_ENC_IV,
@@ -124,6 +126,7 @@ class API {
124
126
  }
125
127
 
126
128
  let urlString = (envType.lowercased() == "uat" ? STAGE_BASE_URL : PROD_BASE_URL) + "/cgm/logs"
129
+ // let urlString = (environment == .stage ? STAGE_BASE_URL : PROD_BASE_URL) + "/cgm/logs"
127
130
  guard let url = URL(string: urlString) else {
128
131
  throw URLError(.badURL)
129
132
  }
@@ -131,10 +134,11 @@ class API {
131
134
  var request = URLRequest(url: url)
132
135
  request.httpMethod = "POST"
133
136
  request.setValue(envType.lowercased() == "uat" ? STAGE_API_KEY : PROD_API_KEY, forHTTPHeaderField: "api-key")
137
+ // request.setValue(environment == .stage ? STAGE_API_KEY : PROD_API_KEY, forHTTPHeaderField: "api-key")
134
138
  request.setValue(token, forHTTPHeaderField: "token")
135
139
  request.setValue("text/plain", forHTTPHeaderField: "Content-Type")
136
140
  request.httpBody = encrypted.data(using: .utf8)
137
-
141
+ print("===>url:", urlString)
138
142
  let (data, response) = try await URLSession.shared.data(for: request)
139
143
 
140
144
  if let httpResponse = response as? HTTPURLResponse {
@@ -144,7 +148,7 @@ class API {
144
148
  if let responseStr = String(data: data, encoding: .utf8) {
145
149
  print("===>Server Response: \(responseStr)")
146
150
  if let decrypted = Crypto.shared.getDecryptedData(cipherText: responseStr, encryptionKey: encryptionKey, encryptionIv: encryptionIv) {
147
- print("===>Decrypted response (for verification): \(decrypted)")
151
+ print("===>Decrypted post cgm data response (for verification): \(decrypted)")
148
152
  }
149
153
 
150
154
  }
@@ -165,13 +169,16 @@ class API {
165
169
  //addCT3GlucoseDataWithReceiveData
166
170
  //updatePOCAlgoBeforeRef
167
171
  func sendStatus(sensorId: String = UserDefaults.standard.string(forKey: "sensorId") ?? "",
172
+ environment: TatvaEnvironment,
168
173
  status: CGMConnectionStatus,
169
174
  transmitterName: String = KLTBluetoothManager.shared().currentDevice?.advertise?.localName ?? "",
170
175
  encryptionKey: String = PROD_ENC_KEY,
171
176
  encryptionIv: String = PROD_ENC_IV) {
172
177
  if sensorId.isEmpty { return }
173
-
178
+ // let envType = UserDefaults.standard.string(forKey: "envType") ?? "uat"
179
+ print("envType: \(envType.lowercased())")
174
180
  let urlString = (envType.lowercased() == "uat" ? STAGE_BASE_URL : PROD_BASE_URL) + "/cgm/connection"
181
+ //let urlString = (environment == .stage ? STAGE_BASE_URL : PROD_BASE_URL) + "/cgm/connection"
175
182
  let url = URL(string: urlString)!
176
183
  var request = URLRequest(url: url)
177
184
  request.httpMethod = "POST"
@@ -179,15 +186,15 @@ class API {
179
186
  // Set headers
180
187
  request.addValue("text/plain", forHTTPHeaderField: "Content-Type")
181
188
  request.setValue(envType.lowercased() == "uat" ? STAGE_API_KEY : PROD_API_KEY, forHTTPHeaderField: "api-key")
189
+ //request.setValue(environment == .stage ? STAGE_API_KEY : PROD_API_KEY, forHTTPHeaderField: "api-key")
182
190
  request.addValue(TOKEN, forHTTPHeaderField: "token")
183
- print("===>url:", "https://api-feature2.mytatva.in/api/v8/cgm/connection")
191
+ print("===>url:", urlString)
184
192
  print("===>api-key:", PROD_API_KEY)
185
193
  print("===>httpmMethod:","POST")
186
194
  print("===>ios token:", TOKEN)
187
195
  // Set request body
188
196
  let json: [String: Any] = [
189
197
  "sensorId": sensorId,
190
- // "sensorName": sensorId,
191
198
  "status": status.rawValue,
192
199
  "rawData": [
193
200
  "transmitterName": transmitterName,
@@ -222,7 +229,7 @@ class API {
222
229
  if let responseString = String(data: data, encoding: .utf8) {
223
230
  print("===>Server Response: \(responseString)")
224
231
  if let decrypted = Crypto.shared.getDecryptedData(cipherText: responseString, encryptionKey: encryptionKey, encryptionIv: encryptionIv) {
225
- print("===>Decrypted response (for verification): \(decrypted)")
232
+ print("===>Decrypted connection api response (for verification): \(decrypted)")
226
233
  }
227
234
  }
228
235
  }
@@ -7,28 +7,43 @@
7
7
 
8
8
  import Foundation
9
9
 
10
- func ReceiveDataToLog(data: ReceiveData) -> CGMLog {
10
+ func ReceiveDataToLog(data: GlucoseData) -> CGMLog {
11
+ let cgmLogs = CGMLog(
12
+ timeInMillis: Double(Date().timeIntervalSince1970 * 1000),
13
+ countdownMinutes: (data.countdownMinutes as? Int) ?? 0,
14
+ countdownDays: (data.countdownDays as? Int) ?? 0,
15
+ hypoglycemiaEarlyWarnMinutes: 0, // still missing, you can map if available
16
+ showGlucoseMG: (data.gluADC as? Int) ?? 0,
17
+ glucoseId: Int(truncating: data.glucoseId ?? 0),
18
+ name: data.device?.advertise?.localName ?? "",
19
+ bytes: [], // still missing: need raw data source
20
+ showGlucose: (data.glu as? Float) ?? 0,
21
+ Ib: (data.blankCurrent as? Float) ?? 0,
22
+ Iw: (data.operatingCurrent as? Float) ?? 0,
23
+ countdownHours: (data.countdownHours as? Int) ?? 0,
24
+ T: (data.temperature as? Float) ?? 0.0,
25
+ year: (data.year as? Int32) ?? 0,
26
+ month: (data.month as? Int32) ?? 0,
27
+ day: (data.day as? Int32) ?? 0,
28
+ hour: (data.hour as? Int32) ?? 0,
29
+ minute: (data.minute as? Int32) ?? 0,
30
+
31
+ trendObject: TrendObject(
32
+ trendId: (data.trend as? Int) ?? 0,
33
+ drawableId: 2103818652, // customize if needed
34
+ widgetImg: -1,
35
+ apsChangeRate: "FLAT" // you could map a real value if available
36
+ ),
37
+
38
+ glucoseStatusObject: GlucoseStatusObject(
39
+ statusId: 1 // you may derive this from a field like `calibrationStatus`
40
+ ),
41
+
42
+ errorObject: ErrorObject(
43
+ errorId: (data.errorCode as? Int) ?? 0,
44
+ sound: "None"
45
+ )
46
+ )
11
47
 
12
- let cgmLogs = CGMLog(timeInMillis: Double(Date().timeIntervalSince1970 * 1000),
13
- countdownMinutes: (data.countdownMinutes as? Int) ?? 0,
14
- countdownDays: (data.countdownDays as? Int) ?? 0,
15
- hypoglycemiaEarlyWarnMinutes: 0, //missing
16
- showGlucoseMG: (data.gluADC as? Int) ?? 0,
17
- glucoseId: Int(truncating: data.glucoseId ?? 0),
18
- name: data.device?.advertise?.localName ?? "",
19
- bytes: [], //missing
20
- showGlucose: (data.glu as? Float) ?? 0 ,
21
- Ib: (data.blankCurrent as? Float) ?? 0,
22
- Iw: (data.operatingCurrent as? Float) ?? 0,
23
- countdownHours: (data.countdownHours as? Int) ?? 0,
24
- T: (data.temperature as? Float) ?? 0.0,
25
- year: (data.year as? Int32) ?? 0,
26
- month: (data.month as? Int32) ?? 0,
27
- day: (data.day as? Int32) ?? 0,
28
- hour: (data.hour as? Int32) ?? 0,
29
- minute: (data.minute as? Int32) ?? 0,
30
- trendObject: TrendObject(trendId: (data.trend as? Int) ?? 0, drawableId: 2103818652, widgetImg: -1, apsChangeRate: "FLAT"), //missing
31
- glucoseStatusObject: GlucoseStatusObject(statusId: 1), //missing
32
- errorObject: ErrorObject(errorId: (data.error as? Int) ?? 0, sound: "None"))
33
48
  return cgmLogs
34
49
  }
@@ -72,13 +72,15 @@ class AttachTransmitterViewController: UIViewController {
72
72
  print(data)
73
73
  print("===> all data count: ", data.count)
74
74
  // KLTDatabaseHandler.shared().reloadQueryHistoryData()
75
+
75
76
  if let device = KLTBluetoothManager.shared().currentDevice {
76
- let arrayFromInitial = KLTDatabaseHandler.shared().queryReceiveData(with: device, needUserBG: true) as! [ReceiveData]
77
+ let arrayFromInitial = KLTDatabaseHandler.shared().queryGlucoseData(with: device) as! [GlucoseData]
77
78
  print(arrayFromInitial)
78
79
  print("===> arrayFromInitial count: ", arrayFromInitial.count)
79
80
 
80
81
  self.viewModel.uploadData(data: arrayFromInitial)
81
82
  }
83
+
82
84
  NotificationCenter.default.post(name: Notification.Name("cgmDeviceEvent"), object: nil, userInfo: ["a":"a"])
83
85
  if let rootVC = UIApplication.shared.connectedScenes
84
86
  .compactMap({ ($0 as? UIWindowScene)?.windows.first?.rootViewController })
@@ -214,6 +214,7 @@ class ConnectToSensorViewController: UIViewController {
214
214
 
215
215
  func connectSensor(value: String, controller: ConnectToSensorViewController) {
216
216
  UserDefaults.standard.set(value, forKey: "sensorId")
217
+
217
218
  var isMatch = false
218
219
 
219
220
  var regex = #"^[A-Z0-9][0-9](0[1-9]|[1-9][0-9]|[A-Z][1-9A-Z])(00[1-9]|0[1-9][0-9]|[1-9][0-9][0-9]){2}[0-9]{4,5}[0-9A-Z]{3}$"#
@@ -123,6 +123,8 @@ import Foundation
123
123
  if device.connectedDateTime == nil && device.disconnectedDateTime == nil {
124
124
  viewModel.manager.startScan()
125
125
  viewModel.debouncer.update(with: .transmitterDisconnect)
126
+ } else {
127
+
126
128
  }
127
129
  } else {
128
130
  print("⚠️ currentDevice is nil")
@@ -153,7 +155,7 @@ class FinalViewModel: NSObject {
153
155
  super.init()
154
156
  debouncer.onDebounceSuccess = { value in
155
157
  print("Blutooth is------------------->>>>>>>>>> \(value)")
156
- API.shared.sendStatus(status: value)
158
+ API.shared.sendStatus(environment: .stage, status: value)
157
159
  // if value == .errorCommon {
158
160
  // self.manager.startScan()
159
161
  // }
@@ -311,11 +313,13 @@ class FinalViewModel: NSObject {
311
313
 
312
314
  NotificationCenter.default.addObserver(self, selector: #selector(bluetoothEnable(_:)), name: NSNotification.Name("BluetoothEnable"), object: nil)
313
315
 
314
- NotificationCenter.default.addObserver(self, selector: #selector(errorStatusFromTransmitter(_:)), name: NSNotification.Name("ErrorStatusFromTransmitter"), object: nil)
316
+ // NotificationCenter.default.addObserver(self, selector: #selector(errorStatusFromTransmitter(_:)), name: NSNotification.Name("ErrorStatusFromTransmitter"), object: nil)
315
317
 
316
318
  NotificationCenter.default.addObserver(self, selector: #selector(handleLatestReceiveData(_:)), name: NSNotification.Name(KLTAlertCurrentInInitialNotify), object: nil)
317
319
 
318
320
  NotificationCenter.default.addObserver(self, selector: #selector(updateData(_:)), name: NSNotification.Name(KLTUpdateDataNotify), object: nil)
321
+
322
+ NotificationCenter.default.addObserver(self, selector: #selector(checkErrorStatusFromLastBatchData(_:)), name: NSNotification.Name("CheckErrorStatusFromLastBatchData"), object: nil)
319
323
  }
320
324
 
321
325
  func removeAllObservers() {
@@ -323,15 +327,17 @@ class FinalViewModel: NSObject {
323
327
 
324
328
  NotificationCenter.default.removeObserver(self, name: NSNotification.Name("BluetoothEnable"), object: nil)
325
329
 
326
- NotificationCenter.default.removeObserver(self, name: NSNotification.Name("ErrorStatusFromTransmitter"), object: nil)
330
+ // NotificationCenter.default.removeObserver(self, name: NSNotification.Name("ErrorStatusFromTransmitter"), object: nil)
327
331
 
328
332
  NotificationCenter.default.removeObserver(self, name: NSNotification.Name(KLTAlertCurrentInInitialNotify), object: nil)
329
333
 
330
334
  NotificationCenter.default.removeObserver(self, name: NSNotification.Name(KLTUpdateDataNotify), object: nil)
335
+
336
+ NotificationCenter.default.removeObserver(self, name: NSNotification.Name("CheckErrorStatusFromLastBatchData"), object: nil)
331
337
  }
332
338
 
333
339
 
334
- func uploadData(data: [ReceiveData]) {
340
+ func uploadData(data: [GlucoseData]) {
335
341
  let batchSize = 40
336
342
  let batches = stride(from: 0, to: data.count, by: batchSize).map {
337
343
  Array(data[$0..<min($0 + batchSize, data.count)])
@@ -340,9 +346,11 @@ class FinalViewModel: NSObject {
340
346
  uploadBatch(batches: batches, index: 0)
341
347
  }
342
348
 
343
- private func uploadBatch(batches: [[ReceiveData]], index: Int) {
349
+ private func uploadBatch(batches: [[GlucoseData]], index: Int) {
344
350
  guard index < batches.count else {
345
- print("====================================> All batches uploaded")
351
+ if index != 0 {
352
+ NotificationCenter.default.post(name: Notification.Name("CheckErrorStatusFromLastBatchData"), object: batches.last?.last)
353
+ }
346
354
  print("✅ All batches uploaded")
347
355
  return
348
356
  }
@@ -352,7 +360,7 @@ class FinalViewModel: NSObject {
352
360
  let payload = Payload(logs: cgmLogs)
353
361
 
354
362
  print("====================================> called uploadBatch")
355
- API.shared.postCGMData(data: payload) {//environment: .stage
363
+ API.shared.postCGMData(data: payload, environment: .stage) {
356
364
  print("====================================> uploaded successfully")
357
365
  print("✅ Batch \(index + 1) uploaded successfully")
358
366
  KLTDatabaseHandler.shared().deleteReceiveDataArray(batch)
@@ -362,22 +370,50 @@ class FinalViewModel: NSObject {
362
370
  // Optionally retry or stop here
363
371
  }
364
372
  }
365
-
373
+ //
374
+ // @objc func updateData(_ notification: Notification) {
375
+ // let data = KLTDatabaseHandler.shared().queryAllReceiveData() as! [ReceiveData]
376
+ // print(data)
377
+ // print("===> all data count: ", data.count)
378
+ //// KLTDatabaseHandler.shared().reloadQueryHistoryData()
379
+ // if let device = KLTBluetoothManager.shared().currentDevice {
380
+ // let arrayFromInitial = KLTDatabaseHandler.shared().queryGlucoseData(with: device) as! [GlucoseData]
381
+ // print(arrayFromInitial)
382
+ // print("======================> arrayFromInitial count: ", arrayFromInitial.count)
383
+ // self.uploadData(data: arrayFromInitial)
384
+ // }
385
+ // }
386
+
366
387
  @objc func updateData(_ notification: Notification) {
367
- let data = KLTDatabaseHandler.shared().queryAllReceiveData() as! [ReceiveData]
388
+ // Safely cast to [ReceiveData]
389
+ guard let data = KLTDatabaseHandler.shared().queryAllReceiveData() as? [ReceiveData] else {
390
+ print("⚠️ Failed to cast queryAllReceiveData() to [ReceiveData]")
391
+ return
392
+ }
393
+
368
394
  print(data)
369
- print("===> all data count: ", data.count)
370
- // KLTDatabaseHandler.shared().reloadQueryHistoryData()
371
- if let device = KLTBluetoothManager.shared().currentDevice {
372
- let arrayFromInitial = KLTDatabaseHandler.shared().queryReceiveData(with: device, needUserBG: true) as! [ReceiveData]
373
- print(arrayFromInitial)
374
- print("======================> arrayFromInitial count: ", arrayFromInitial.count)
375
- self.uploadData(data: arrayFromInitial)
395
+ print("===> all data count: \(data.count)")
396
+
397
+ // Ensure device exists
398
+ guard let device = KLTBluetoothManager.shared().currentDevice else {
399
+ print("⚠️ No current device found")
400
+ return
401
+ }
402
+
403
+ // Get glucose data array
404
+ guard let arrayFromInitial = KLTDatabaseHandler.shared().queryGlucoseData(with: device) else {
405
+ print("⚠️ Failed to cast queryGlucoseData to [GlucoseData]")
406
+ return
376
407
  }
408
+
409
+ print("======================> arrayFromInitial count: \(arrayFromInitial.count)")
410
+
411
+ // Call upload
412
+ self.uploadData(data: arrayFromInitial)
377
413
  }
378
-
379
- @objc func errorStatusFromTransmitter(_ notification: Notification) {
380
- guard let receiveData = notification.object as? ReceiveData else { return }
414
+
415
+ @objc func checkErrorStatusFromLastBatchData(_ notification: Notification) {
416
+ guard let receiveData = notification.object as? GlucoseData else { return }
381
417
 
382
418
  let errorCode = ErrorCode(rawValue: Int32(receiveData.error?.intValue ?? 0))
383
419
  if errorCode == ErrorCode.ERROR_CODE_FLOODING_WATER {
@@ -396,6 +432,26 @@ class FinalViewModel: NSObject {
396
432
  }
397
433
  }
398
434
 
435
+ // @objc func errorStatusFromTransmitter(_ notification: Notification) {
436
+ // guard let receiveData = notification.object as? ReceiveData else { return }
437
+ //
438
+ // let errorCode = ErrorCode(rawValue: Int32(receiveData.error?.intValue ?? 0))
439
+ // if errorCode == ErrorCode.ERROR_CODE_FLOODING_WATER {
440
+ // debouncer.update(with: CGMConnectionStatus.moistureDetect)
441
+ // //API.shared.sendStatus(status: .moistureDetect)
442
+ // } else if errorCode == ErrorCode.ERROR_CODE_CURRENT_SMALL || errorCode == ErrorCode.ERROR_CODE_NOISE || errorCode == ErrorCode.ERROR_CODE_SENSITIVITY_ATTENUATION {
443
+ // debouncer.update(with: CGMConnectionStatus.weakSignal)
444
+ // //API.shared.sendStatus(status: .weakSignal)
445
+ // } else if errorCode != ErrorCode.ERROR_CODE_NONE {
446
+ // debouncer.update(with: CGMConnectionStatus.errorCommon)
447
+ // //API.shared.sendStatus(status: .errorCommon)
448
+ // }
449
+ // if receiveData.countdownDays == 0 && receiveData.countdownHours == 0 && receiveData.countdownMinutes == 0 {
450
+ // debouncer.update(with: CGMConnectionStatus.expired)
451
+ // //API.shared.sendStatus(status: .expired)
452
+ // }
453
+ // }
454
+
399
455
  @objc func handleLatestReceiveData(_ notification: Notification) {
400
456
  print("====> handleLatestReceiveData")
401
457
  guard let receiveData = notification.object as? ReceiveData else { return }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-mytatva-rn-sdk",
3
- "version": "1.2.53",
3
+ "version": "1.2.55",
4
4
  "description": "a package to inject data into visit health pwa",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",