react-native-mytatva-rn-sdk 1.2.36 → 1.2.38

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.
@@ -0,0 +1,648 @@
1
+ //
2
+ // FinalViewModel.swift
3
+ // MyTatvaCare
4
+ //
5
+ // Created by Nirav Ramani on 31/05/25.
6
+ //
7
+
8
+ import Foundation
9
+ @objc public class FinalViewModelManager: NSObject {
10
+ @objc public static let shared = FinalViewModelManager()
11
+ @objc let viewModel = FinalViewModel()
12
+
13
+ private override init() {
14
+ super.init()
15
+ viewModel.initialize()
16
+ }
17
+
18
+ // @objc public func callForObserveTransmitterUnbindStatus() {
19
+ // let sensorID = UserDefaults.standard.string(forKey: "sensorId") ?? ""
20
+ // if !sensorID.isEmpty {
21
+ // viewModel.getStatus()
22
+ // }
23
+ // }
24
+
25
+ @objc public func callForObserveTransmitterUnbindStatusWithCompletion(
26
+ _ completion: @escaping (_ finalResponse: [String: Any]?, _ error: Error?) -> Void
27
+ ) {
28
+ // Load JSON data from UserDefaults
29
+ guard let data = UserDefaults.standard.data(forKey: "CGMStatusItem") else {
30
+ let error = NSError(
31
+ domain: "SensorData",
32
+ code: 404,
33
+ userInfo: [NSLocalizedDescriptionKey: "No cached response found"]
34
+ )
35
+ completion(nil, error)
36
+ return
37
+ }
38
+
39
+ do {
40
+ let json = try JSONSerialization.jsonObject(with: data, options: [])
41
+ // Forward to actual handler, which includes a safety check
42
+ self.callForObserveTransmitterUnbindStatusWithResponse(json, completion: completion)
43
+ } catch {
44
+ completion(nil, NSError(domain: "SensorData", code: 405, userInfo: [NSLocalizedDescriptionKey: "Failed to parse cached JSON"]))
45
+ }
46
+ }
47
+
48
+
49
+ @objc public func callForObserveTransmitterUnbindStatusWithResponse(
50
+ _ response: Any, // Changed from [String: Any] to Any to add type safety
51
+ completion: @escaping (_ finalResponse: [String: Any]?, _ error: Error?) -> Void
52
+ ) {
53
+ // Ensure response is a dictionary
54
+ guard let responseDict = response as? [String: Any] else {
55
+ let error = NSError(
56
+ domain: "SensorData",
57
+ code: 406,
58
+ userInfo: [NSLocalizedDescriptionKey: "Response is not a dictionary"]
59
+ )
60
+ completion(nil, error)
61
+ return
62
+ }
63
+
64
+ guard let status = responseDict["status"] as? String, status == "success",
65
+ let dataArray = responseDict["data"] as? [[String: Any]],
66
+ let data = dataArray.first else {
67
+ let error = NSError(
68
+ domain: "SensorData",
69
+ code: 400,
70
+ userInfo: [NSLocalizedDescriptionKey: "Invalid status or missing data"]
71
+ )
72
+ completion(nil, error)
73
+ return
74
+ }
75
+
76
+ guard let sensorId = data["sensorId"] as? String,
77
+ let startDate = data["startDate"] as? String,
78
+ let endDate = data["endDate"] as? String,
79
+ let statusValue = data["status"] as? String,
80
+ let daysToExpire = data["daysToExpire"] as? Int else {
81
+ let error = NSError(
82
+ domain: "SensorData",
83
+ code: 401,
84
+ userInfo: [NSLocalizedDescriptionKey: "Missing or invalid sensor data in 'data'"]
85
+ )
86
+ completion(nil, error)
87
+ return
88
+ }
89
+
90
+ let baseResponse: [String: Any] = [
91
+ "sensorId": sensorId,
92
+ "startDate": startDate,
93
+ "endDate": endDate,
94
+ "status": statusValue,
95
+ "daysToExpire": daysToExpire
96
+ ]
97
+
98
+ let finalResponse = self.evaluateUnbindStatus(response: baseResponse, startDate: startDate, endDate: endDate)
99
+ completion(finalResponse, nil)
100
+ }
101
+
102
+ // MARK: - Main Logic
103
+ @objc public func evaluateUnbindStatus(
104
+ response: [String: Any],
105
+ startDate: String,
106
+ endDate: String
107
+ ) -> [String: Any] {
108
+ let updatedResponse = response
109
+
110
+ if viewModel.isCurrentDateInRange(startDate: startDate, endDate: endDate) {
111
+ print("Current date is in range")
112
+ if ((viewModel.manager.connectedPeripheral == nil) && !KLTLocalSettingManager.shareInstance().canConnectOtherDevice) {
113
+ viewModel.manager.startScan()
114
+ viewModel.debouncer.update(with: .disconnected)
115
+ } else {
116
+ print("here")
117
+ //debouncer.update(with: .connected)
118
+ //API.shared.sendStatus(status: .connected) 计算 算法入参
119
+ if let last = viewModel.manager.currentDevice { }
120
+ else {
121
+ //self.manager.closeBleSensor()
122
+ //manager.startScan()
123
+ //self.debouncer.update(with: .disconnected)
124
+ //debouncer.update(with: .transmitterDisconnectBox)
125
+ }
126
+ }
127
+ // if KLTBluetoothManager.shared().currentDevice.initialEndDate != nil {
128
+ //
129
+ }
130
+
131
+ return updatedResponse
132
+ }
133
+ }
134
+
135
+ class FinalViewModel: NSObject {
136
+ var initialPeriod = 0
137
+ var totalSeconds : TimeInterval = 60 * 60
138
+ let manager: KLTBluetoothManager!
139
+ var countdownTimer: Timer?
140
+ var startScanTimer: Timer?
141
+ let debouncer = EnumDebouncer<CGMConnectionStatus>()
142
+
143
+
144
+ @objc public override init() {
145
+ self.manager = KLTBluetoothManager.shared()
146
+ super.init()
147
+ debouncer.onDebounceSuccess = { value in
148
+ API.shared.sendStatus(status: value)
149
+ print("Same type held for an hour!")
150
+ }
151
+ }
152
+
153
+ @objc public func initialize() {
154
+ //getStatus()
155
+ startCountDown()
156
+
157
+ if ((manager.connectedPeripheral == nil) && !KLTLocalSettingManager.shareInstance().canConnectOtherDevice) {
158
+ manager.startScan()
159
+ debouncer.update(with: .disconnected)
160
+ } else {
161
+ print("here")
162
+ //debouncer.update(with: .connected)
163
+ //API.shared.sendStatus(status: .connected) 计算 算法入参
164
+ if let last = manager.currentDevice { }
165
+ else {
166
+ //self.manager.closeBleSensor()
167
+ //manager.startScan()
168
+ debouncer.update(with: .disconnected)
169
+ //debouncer.update(with: .transmitterDisconnectBox)
170
+ }
171
+ }
172
+ }
173
+
174
+ func getStatus(encryptionKey: String = PROD_ENC_KEY,
175
+ encryptionIv: String = PROD_ENC_IV) {
176
+ print("ios token:", TOKEN)
177
+ let url = URL(string: "https://api-feature2.mytatva.in/api/v8/cgm/status")!
178
+ var request = URLRequest(url: url)
179
+ request.httpMethod = "GET"
180
+
181
+ // Set headers
182
+ //request.addValue("application/json", forHTTPHeaderField: "Content-Type")
183
+ request.addValue(PROD_API_KEY, forHTTPHeaderField: "api-key")
184
+ request.addValue(TOKEN, forHTTPHeaderField: "token")
185
+
186
+
187
+ // Set request body
188
+
189
+ // Perform request
190
+ let task = URLSession.shared.dataTask(with: request) { data, response, error in
191
+ if let error = error {
192
+ print("Error: \(error)")
193
+ return
194
+ }
195
+ guard let data = data else {
196
+ print("No data received")
197
+ return
198
+ }
199
+ if let responseString = String(data: data, encoding: .utf8) {
200
+ print("===>Server Response: \(responseString)")
201
+ if let decrypted = Crypto.shared.getDecryptedData(cipherText: responseString, encryptionKey: encryptionKey, encryptionIv: encryptionIv) {
202
+ print("===>Decrypted response (for verification): \(decrypted)")
203
+
204
+ if let decrptedData = decrypted.data(using: .utf8) {
205
+ let decoded = try? JSONDecoder().decode(CGMStatusResponse.self, from: decrptedData)
206
+
207
+ guard let sensor = decoded?.data.first,
208
+ !sensor.startDate.isEmpty,
209
+ !sensor.endDate.isEmpty else {
210
+ print("No valid sensor data")
211
+ return
212
+ }
213
+
214
+ let startDateStr = sensor.startDate
215
+ let endDateStr = sensor.endDate
216
+
217
+ print("Start Date: \(startDateStr)")
218
+ print("End Date: \(endDateStr)")
219
+ UserDefaults.standard.set(sensor.sensorId, forKey: "sensorId")
220
+ if self.isCurrentDateInRange(startDate: startDateStr, endDate: endDateStr) {
221
+ print("Current date is in range")
222
+ if ((self.manager.connectedPeripheral == nil) && !KLTLocalSettingManager.shareInstance().canConnectOtherDevice) {
223
+ self.manager.startScan()
224
+ self.debouncer.update(with: .disconnected)
225
+ } else {
226
+ print("here")
227
+ //debouncer.update(with: .connected)
228
+ //API.shared.sendStatus(status: .connected) 计算 算法入参
229
+ if let last = self.manager.currentDevice { }
230
+ else {
231
+ //self.manager.closeBleSensor()
232
+ //manager.startScan()
233
+ //self.debouncer.update(with: .disconnected)
234
+ //debouncer.update(with: .transmitterDisconnectBox)
235
+ }
236
+ }
237
+ // if KLTBluetoothManager.shared().currentDevice.initialEndDate != nil {
238
+ // self.sendStatus(status: .transmitterDisconnect)
239
+ // }
240
+ }
241
+ }
242
+ }
243
+ }
244
+ }
245
+ task.resume()
246
+
247
+ }
248
+
249
+ func isCurrentDateInRange(startDate: String, endDate: String) -> Bool {
250
+ let formatter = DateFormatter()
251
+ formatter.dateFormat = "yyyy-MM-dd"
252
+ guard let start = formatter.date(from: startDate),
253
+ let end = formatter.date(from: endDate) else {
254
+ return false
255
+ }
256
+
257
+ let now = Date()
258
+ return (now >= start) && (now <= end)
259
+ }
260
+
261
+ func startCountDown() {
262
+
263
+ // Most recently connected device
264
+ if let last = manager.currentDevice {
265
+ let eDevice = EDevice.getEnumDevice(last.advertise?.localName ?? "")
266
+ initialPeriod = Int(eDevice.initNumber * 3 * 60)
267
+ // Calculate initialization countdown time
268
+ if let beginDate = KLTDateFormatter.shared.getDateFromWholeString(last.initialBeginDate ?? "") {
269
+ let time = Date().timeIntervalSince(beginDate)
270
+ if Int(time) > self.initialPeriod {
271
+ // Initialization completed, normal use
272
+
273
+ } else {
274
+
275
+ // During initialization, notify the initialization page to restart the countdown
276
+ totalSeconds = Double(initialPeriod) - TimeInterval(time)
277
+
278
+ //for countdownlabel
279
+ print(String.getTimeString(with: Int(totalSeconds)))
280
+
281
+ if countdownTimer != nil {
282
+ countdownTimer?.invalidate()
283
+ countdownTimer = nil
284
+ }
285
+ countdownTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(countdown), userInfo: nil, repeats: true)
286
+
287
+ }
288
+ }
289
+ } else {
290
+ // no device is connected
291
+ print("no device is connected")
292
+ }
293
+
294
+ addAllObservers()
295
+ }
296
+
297
+ func addAllObservers() {
298
+ manager.addObserver(self, forKeyPath: "status", options: .new, context: nil)
299
+
300
+ NotificationCenter.default.addObserver(self, selector: #selector(bluetoothEnable(_:)), name: NSNotification.Name("BluetoothEnable"), object: nil)
301
+
302
+ NotificationCenter.default.addObserver(self, selector: #selector(errorStatusFromTransmitter(_:)), name: NSNotification.Name("ErrorStatusFromTransmitter"), object: nil)
303
+
304
+ NotificationCenter.default.addObserver(self, selector: #selector(handleLatestReceiveData(_:)), name: NSNotification.Name(KLTAlertCurrentInInitialNotify), object: nil)
305
+
306
+ NotificationCenter.default.addObserver(self, selector: #selector(updateData(_:)), name: NSNotification.Name(KLTUpdateDataNotify), object: nil)
307
+ }
308
+
309
+ func removeAllObservers() {
310
+ manager.removeObserver(self, forKeyPath: "status")
311
+
312
+ NotificationCenter.default.removeObserver(self, name: NSNotification.Name("BluetoothEnable"), object: nil)
313
+
314
+ NotificationCenter.default.removeObserver(self, name: NSNotification.Name("ErrorStatusFromTransmitter"), object: nil)
315
+
316
+ NotificationCenter.default.removeObserver(self, name: NSNotification.Name(KLTAlertCurrentInInitialNotify), object: nil)
317
+
318
+ NotificationCenter.default.removeObserver(self, name: NSNotification.Name(KLTUpdateDataNotify), object: nil)
319
+ }
320
+
321
+
322
+ func uploadData(data: [ReceiveData]) {
323
+ let batchSize = 40
324
+ let batches = stride(from: 0, to: data.count, by: batchSize).map {
325
+ Array(data[$0..<min($0 + batchSize, data.count)])
326
+ }
327
+ uploadBatch(batches: batches, index: 0)
328
+ }
329
+
330
+ private func uploadBatch(batches: [[ReceiveData]], index: Int) {
331
+ guard index < batches.count else {
332
+ print("✅ All batches uploaded")
333
+ return
334
+ }
335
+
336
+ let batch = batches[index]
337
+ let cgmLogs = batch.map { ReceiveDataToLog(data: $0) }
338
+ let payload = Payload(logs: cgmLogs)
339
+
340
+ API.shared.postCGMData(environment: .stage, data: payload) {
341
+ print("✅ Batch \(index + 1) uploaded successfully")
342
+ KLTDatabaseHandler.shared().deleteReceiveDataArray(batch)
343
+ self.uploadBatch(batches: batches, index: index + 1)
344
+ } onFailure: { error in
345
+ print("❌ Failed to upload batch \(index + 1): \(String(describing: error?.localizedDescription))")
346
+ // Optionally retry or stop here
347
+ }
348
+ }
349
+
350
+ @objc func updateData(_ notification: Notification) {
351
+ let data = KLTDatabaseHandler.shared().queryAllReceiveData() as! [ReceiveData]
352
+ print(data)
353
+ print("===> all data count: ", data.count)
354
+ KLTDatabaseHandler.shared().reloadQueryHistoryData()
355
+ if let device = KLTBluetoothManager.shared().currentDevice {
356
+ let arrayFromInitial = KLTDatabaseHandler.shared().queryReceiveData(with: device, needUserBG: true) as! [ReceiveData]
357
+ print(arrayFromInitial)
358
+ print("===> arrayFromInitial count: ", arrayFromInitial.count)
359
+ self.uploadData(data: arrayFromInitial)
360
+ }
361
+ }
362
+
363
+ @objc func errorStatusFromTransmitter(_ notification: Notification) {
364
+ guard let receiveData = notification.object as? ReceiveData else { return }
365
+
366
+ let errorCode = ErrorCode(rawValue: Int32(receiveData.error?.intValue ?? 0))
367
+ if errorCode == ErrorCode.ERROR_CODE_FLOODING_WATER {
368
+ debouncer.update(with: CGMConnectionStatus.moistureDetect)
369
+ //API.shared.sendStatus(status: .moistureDetect)
370
+ } else if errorCode == ErrorCode.ERROR_CODE_CURRENT_SMALL || errorCode == ErrorCode.ERROR_CODE_NOISE || errorCode == ErrorCode.ERROR_CODE_SENSITIVITY_ATTENUATION {
371
+ debouncer.update(with: CGMConnectionStatus.weakSignal)
372
+ //API.shared.sendStatus(status: .weakSignal)
373
+ } else if errorCode != ErrorCode.ERROR_CODE_NONE {
374
+ debouncer.update(with: CGMConnectionStatus.errorCommon)
375
+ //API.shared.sendStatus(status: .errorCommon)
376
+ }
377
+ if receiveData.countdownDays == 0 && receiveData.countdownHours == 0 && receiveData.countdownMinutes == 0 {
378
+ debouncer.update(with: CGMConnectionStatus.expired)
379
+ //API.shared.sendStatus(status: .expired)
380
+ }
381
+ }
382
+
383
+ @objc func handleLatestReceiveData(_ notification: Notification) {
384
+ print("====> handleLatestReceiveData")
385
+ guard let receiveData = notification.object as? ReceiveData else { return }
386
+
387
+ let errorCode = ErrorCode(rawValue: Int32(receiveData.error?.intValue ?? 0))
388
+
389
+ let hasExceptionCurrent: Bool = (errorCode == ErrorCode.ERROR_CODE_CURRENT_SMALL || errorCode == ErrorCode.ERROR_CODE_NOISE ||
390
+ errorCode == ErrorCode.ERROR_CODE_SENSITIVITY_ATTENUATION || errorCode == ErrorCode.ERROR_CODE_TAKE_OFF ||
391
+ errorCode == ErrorCode.ERROR_CODE_BREAKAGE || errorCode == ErrorCode.ERROR_CODE_TOUCH ||
392
+ errorCode == ErrorCode.ERROR_CODE_FLOODING_WATER)
393
+
394
+ if hasExceptionCurrent {
395
+ guard let startDate = KLTFormat.getDate(from: manager.currentDevice.initialBeginDate ?? "") else { return }
396
+
397
+ // Get current UTC date from local date string
398
+ let now = Date()
399
+ let nowString = KLTDateFormatter.shared.getWholeString(from: now)
400
+ let utcDateString = KLTDateFormatter.shared.getUTCFormatDate(from: nowString) ?? ""
401
+ guard let currentDate = KLTDateFormatter.shared.getDateFromWholeString(utcDateString) else { return }
402
+
403
+ let seconds = Calendar(identifier: .gregorian)
404
+ .dateComponents([.second], from: startDate, to: currentDate).second ?? 0
405
+
406
+ let minutes = seconds / 60
407
+ if minutes > 17 {
408
+
409
+ }
410
+ }
411
+ }
412
+
413
+ @objc func bluetoothEnable(_ notification: Notification) {
414
+ if let isBluetoothEnabled = notification.object as? Bool {
415
+ if !isBluetoothEnabled {
416
+ debouncer.update(with: CGMConnectionStatus.bluetoothOff)
417
+ //API.shared.sendStatus(status: .bluetoothOff)
418
+ }
419
+ }
420
+ if ((manager.connectedPeripheral == nil) && !KLTLocalSettingManager.shareInstance().canConnectOtherDevice) {
421
+ manager.startScan()
422
+ }
423
+ }
424
+
425
+ @objc func countdown() {
426
+ if let last = KLTDatabaseHandler.shared().isLatestDeviceDisconnected() {
427
+ if let beginDate = KLTDateFormatter.shared.getDateFromWholeString(last.initialBeginDate ?? "") {
428
+ let time = Date().timeIntervalSince(beginDate)
429
+ totalSeconds = TimeInterval(3600 - Int(time))
430
+ }
431
+ }
432
+
433
+ if totalSeconds <= 0 {
434
+ countdownTimer?.invalidate()
435
+ countdownTimer = nil
436
+
437
+ startScanTimer?.invalidate()
438
+ startScanTimer = nil
439
+
440
+ //removeAllObservers()
441
+
442
+ //KLTLaunchConfiguration.sharedManager.resetRootViewController(type: .normalUsed)
443
+ return
444
+ }
445
+
446
+ totalSeconds -= 1
447
+ print(String.getTimeString(with: Int(totalSeconds)))
448
+ //countDownValueLabel.text =
449
+ }
450
+
451
+ override func observeValue(
452
+ forKeyPath keyPath: String?,
453
+ of object: Any?,
454
+ change: [NSKeyValueChangeKey : Any]?,
455
+ context: UnsafeMutableRawPointer?
456
+ ) {
457
+ guard keyPath == "status",
458
+ let newValue = change?[.newKey] as? Int,
459
+ let status = BluetoothManagerStatus(rawValue: newValue) else {
460
+ return
461
+ }
462
+
463
+ print("===>device status is -> \(status)")
464
+
465
+ switch status {
466
+
467
+ case .disconnected:
468
+ if KLTLocalSettingManager.shareInstance().canConnectOtherDevice {
469
+ // Unbind then disconnect
470
+ endBleSensorCycle()
471
+ } else {
472
+ if UserDefaults.standard.integer(forKey: "bgmode") != 1 {
473
+ manager.startScan()
474
+ }
475
+ }
476
+ //API.shared.sendStatus(status: .disconnected)
477
+ print("===>device is disconnected")
478
+ debouncer.update(with: CGMConnectionStatus.disconnected)
479
+ case .tryToConnect:
480
+ // if UserDefaults.standard.integer(forKey: "bgmode") != 1 {
481
+ // DispatchQueue.main.asyncAfter(deadline: .now() + 20) {
482
+ // self.manager.startScan()
483
+ // }
484
+ // }
485
+ break
486
+ case .connected:
487
+ if let timer = startScanTimer {
488
+ timer.invalidate()
489
+ startScanTimer = nil
490
+ }
491
+ //API.shared.sendStatus(status: .connected)
492
+ print("===>device is connected")
493
+ debouncer.update(with: CGMConnectionStatus.connected)
494
+ case .timeOut:
495
+ // if !KLTLocalSettingManager.shareInstance().canConnectOtherDevice {
496
+ // startScanTimer = Timer.scheduledTimer(timeInterval: 20,
497
+ // target: self,
498
+ // selector: #selector(startScan),
499
+ // userInfo: nil,
500
+ // repeats: false)
501
+ // }
502
+ print("===>time out")
503
+ break
504
+ case .sensorLostPower:
505
+ sensorLostPower()
506
+ print("===>sensor lost power")
507
+ case .updateBindWatchSuccess:
508
+ //KLTLaunchConfiguration.sharedManager.bindSuccessRootViewController()
509
+ startCountDown()
510
+ print("===>Success done")
511
+ case .closed:
512
+ debouncer.update(with: CGMConnectionStatus.transmitterDisconnectBox)
513
+ //API.shared.sendStatus(status: .transmitterDisconnectBox)
514
+ print("===>closed")
515
+ default:
516
+ break
517
+ }
518
+ }
519
+
520
+ func sensorLostPower() {
521
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
522
+ // Will trigger `BluetoothManagerStatusDisconnected` due to forced disconnection
523
+ self.manager.forceEndBleSensor()
524
+ }
525
+ }
526
+
527
+ @objc func startScan() {
528
+ manager.startScan()
529
+ }
530
+
531
+ func endBleSensorCycle() {
532
+ if let timer = countdownTimer {
533
+ timer.invalidate()
534
+ countdownTimer = nil
535
+ }
536
+
537
+ removeAllObservers()
538
+
539
+ print("initial State all end")
540
+ // KLTLaunchConfiguration.sharedManager.resetRootViewController(.beforeUse)
541
+ }
542
+ }
543
+
544
+
545
+ struct KLTDateFormatter {
546
+ static let shared = KLTDateFormatter()
547
+
548
+ private let calendar = Calendar(identifier: .gregorian)
549
+ private let locale = Locale(identifier: "en_GB")
550
+
551
+ private func configuredFormatter(withFormat format: String, timeZone: TimeZone? = nil) -> DateFormatter {
552
+ let formatter = DateFormatter()
553
+ formatter.calendar = calendar
554
+ formatter.locale = locale
555
+ formatter.dateFormat = format
556
+ if let tz = timeZone {
557
+ formatter.timeZone = tz
558
+ }
559
+ return formatter
560
+ }
561
+
562
+ func getWholeString(from date: Date) -> String {
563
+ return configuredFormatter(withFormat: "yyyy-MM-dd HH:mm:ss").string(from: date)
564
+ }
565
+
566
+ func getDayString(from date: Date) -> String {
567
+ return configuredFormatter(withFormat: "MM-dd").string(from: date)
568
+ }
569
+
570
+ func getHourString(from date: Date) -> String {
571
+ let hour = configuredFormatter(withFormat: "HH").string(from: date)
572
+ return "\(hour):00"
573
+ }
574
+
575
+ func getMinuteString(from date: Date) -> String {
576
+ return configuredFormatter(withFormat: "HH:mm").string(from: date)
577
+ }
578
+
579
+ func getMinuteDate(from string: String) -> Date? {
580
+ return configuredFormatter(withFormat: "HH:mm").date(from: string)
581
+ }
582
+
583
+ func getHourDate(from string: String) -> Date? {
584
+ return configuredFormatter(withFormat: "HH:00").date(from: string)
585
+ }
586
+
587
+ func getDayDate(from string: String) -> Date? {
588
+ return configuredFormatter(withFormat: "MM-dd").date(from: string)
589
+ }
590
+
591
+ func getDateTime(from string: String) -> Date? {
592
+ return configuredFormatter(withFormat: "yyyy-MM-dd HH:mm").date(from: string)
593
+ }
594
+
595
+ func getDateFromWholeString(_ string: String) -> Date? {
596
+ return configuredFormatter(withFormat: "yyyy-MM-dd HH:mm:ss").date(from: string)
597
+ }
598
+
599
+ func getUTCFormatDate(from localDate: String) -> String? {
600
+ guard let date = getDateFromWholeString(localDate) else { return nil }
601
+ return configuredFormatter(withFormat: "yyyy-MM-dd HH:mm:ss", timeZone: TimeZone(abbreviation: "UTC")).string(from: date)
602
+ }
603
+
604
+ func getLocalFromUTC(_ utc: String) -> String? {
605
+ let formatter = configuredFormatter(withFormat: "yyyy-MM-dd HH:mm:ss", timeZone: TimeZone.current)
606
+ guard let date = formatter.date(from: utc) else { return nil }
607
+ return getWholeString(from: date)
608
+ }
609
+ }
610
+ extension String {
611
+ func klt_contains(_ other: String) -> Bool {
612
+ return self.range(of: other) != nil
613
+ }
614
+
615
+ func klt_hasValidTransmit() -> Bool {
616
+ guard self.count >= 2 else { return false }
617
+ let lastHex = String(self.suffix(2))
618
+ return lastHex == "00"
619
+ }
620
+
621
+ func reverseToString(groupSize: Int) -> String {
622
+ guard groupSize > 0 && self.count > groupSize else { return self }
623
+
624
+ var result = ""
625
+ var index = self.count
626
+
627
+ while index >= groupSize {
628
+ let start = self.index(self.startIndex, offsetBy: index - groupSize)
629
+ let end = self.index(self.startIndex, offsetBy: index)
630
+ result += self[start..<end]
631
+ index -= groupSize
632
+ }
633
+
634
+ if index > 0 {
635
+ let leftover = self.prefix(index)
636
+ result += leftover
637
+ }
638
+
639
+ return result
640
+ }
641
+
642
+ static func getTimeString(with count: Int) -> String {
643
+ let hours = String(format: "%02d", count / 3600)
644
+ let minutes = String(format: "%02d", (count % 3600) / 60)
645
+ let seconds = String(format: "%02d", count % 60)
646
+ return "\(hours):\(minutes):\(seconds)"
647
+ }
648
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-mytatva-rn-sdk",
3
- "version": "1.2.36",
3
+ "version": "1.2.38",
4
4
  "description": "a package to inject data into visit health pwa",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",