react-native-mytatva-rn-sdk 1.2.18 → 1.2.19
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/android/src/main/java/com/mytatvarnsdk/activity/HelpActivity.kt +5 -0
- package/ios/Database/KLTDatabaseHandler.m +1 -1
- package/ios/Extension/UIImageView+Extension.swift +1 -1
- package/ios/MyReactNativeBridge.m +108 -91
- package/ios/Storyboard/MainCGM.storyboard +131 -0
- package/ios/Support/API.swift +110 -16
- package/ios/TableViewCell/ImageTVC/ImageTVC.swift +2 -0
- package/ios/TableViewCell/ImageTVC/ImageTVC.xib +10 -0
- package/ios/TableViewCell/SearchDeviceTVC/SearchDeviceTVC.swift +1 -1
- package/ios/ViewControllers/BluetoothConnectionViewController.swift +51 -0
- package/ios/ViewControllers/ChatWithExpertViewController.swift +23 -4
- package/ios/ViewControllers/ConnectToTransmitterViewController.swift +47 -7
- package/ios/ViewControllers/ProvidePermissionViewController.swift +6 -0
- package/ios/ViewModel/FinalViewModel.swift +9 -1
- package/ios/icon.xcassets/ic_bluetooth_button.imageset/Contents.json +21 -0
- package/ios/icon.xcassets/ic_bluetooth_button.imageset/secondary button.png +0 -0
- package/ios/icon.xcassets/ic_settings.imageset/Contents.json +21 -0
- package/ios/icon.xcassets/ic_settings.imageset/settings.png +0 -0
- package/package.json +1 -1
|
@@ -39,6 +39,11 @@ class HelpActivity : AppCompatActivity() {
|
|
|
39
39
|
binding.ivBack.setOnClickListener {
|
|
40
40
|
finish()
|
|
41
41
|
}
|
|
42
|
+
|
|
43
|
+
binding.tvBack.setOnClickListener {
|
|
44
|
+
finish()
|
|
45
|
+
}
|
|
46
|
+
|
|
42
47
|
enableDisableBtn(false)
|
|
43
48
|
|
|
44
49
|
binding.helpOptionsGroup.setOnCheckedChangeListener { group, checkedId ->
|
|
@@ -387,7 +387,7 @@
|
|
|
387
387
|
data.TsCount = (int)index + 1;
|
|
388
388
|
|
|
389
389
|
// 校准后的点
|
|
390
|
-
NSArray<ReceiveData*> *needUserBgs = [self queryReceiveDataWithDevice:currentDevice needUserBG:
|
|
390
|
+
NSArray<ReceiveData*> *needUserBgs = [self queryReceiveDataWithDevice:currentDevice needUserBG:NO];
|
|
391
391
|
NSUInteger numberOfUserBgs = needUserBgs.count;
|
|
392
392
|
if (needUserBgs.count > 0) {
|
|
393
393
|
bgToGlucoseIds = malloc(sizeof(int) * numberOfUserBgs);
|
|
@@ -12,7 +12,7 @@ import ImageIO
|
|
|
12
12
|
extension UIImageView {
|
|
13
13
|
func loadGif(named name: String) {
|
|
14
14
|
DispatchQueue.global().async {
|
|
15
|
-
guard let path = Bundle.
|
|
15
|
+
guard let path = Bundle(for: ImageTVC.self).path(forResource: name, ofType: "gif"),
|
|
16
16
|
let data = NSData(contentsOfFile: path) else {
|
|
17
17
|
print("GIF not found: \(name)")
|
|
18
18
|
return
|
|
@@ -17,13 +17,13 @@ RCT_EXPORT_MODULE();
|
|
|
17
17
|
|
|
18
18
|
// Define the supported events
|
|
19
19
|
- (NSArray<NSString *> *)supportedEvents {
|
|
20
|
-
|
|
20
|
+
return @[@"cgmDeviceEvent"]; // Event names to listen to in JS
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
// Example method to emit an event from native to JS
|
|
24
24
|
RCT_EXPORT_METHOD(emitEvent:(NSString *)message) {
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
// Send an event with the name "EventName" and a message payload
|
|
26
|
+
[self sendEventWithName:@"cgmDeviceEvent" body:@{@"status": message}];
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
@end
|
|
@@ -36,136 +36,153 @@ RCT_EXPORT_MODULE();
|
|
|
36
36
|
// This method returns the list of events the module supports
|
|
37
37
|
- (NSArray<NSString *> *)supportedEvents
|
|
38
38
|
{
|
|
39
|
-
|
|
39
|
+
return @[@"cgmDeviceEvent"];
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
// Start listening for notifications
|
|
43
43
|
- (instancetype)init
|
|
44
44
|
{
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
45
|
+
if (self = [super init]) {
|
|
46
|
+
// Add observer for the notification from UIViewController
|
|
47
|
+
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
48
|
+
selector:@selector(handleNotification:)
|
|
49
|
+
name:@"cgmDeviceEvent"
|
|
50
|
+
object:nil];
|
|
51
|
+
}
|
|
52
|
+
return self;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
|
|
56
56
|
// Handle the incoming notification and emit the event to React Native
|
|
57
57
|
- (void)handleNotification:(NSNotification *)notification
|
|
58
58
|
{
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
// Extract data from the notification
|
|
60
|
+
NSDictionary *userInfo = notification.userInfo;
|
|
61
|
+
|
|
62
|
+
// Send the data to React Native via event emitter
|
|
63
63
|
[self sendEventWithName:@"cgmDeviceEvent" body:@{@"status": @"WARM_PERIOD_STARTED"}];
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
// Clean up the observer when the module is deallocated
|
|
67
67
|
- (void)dealloc
|
|
68
68
|
{
|
|
69
|
-
|
|
69
|
+
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
|
|
73
73
|
RCT_EXPORT_METHOD(startCgmTracky:(NSString *)token)
|
|
74
74
|
{
|
|
75
|
-
|
|
76
|
-
[[NSUserDefaults standardUserDefaults] synchronize];
|
|
77
|
-
|
|
78
|
-
dispatch_async(dispatch_get_main_queue(), ^{
|
|
79
|
-
UIWindow *keyWindow = [UIApplication sharedApplication].delegate.window;
|
|
80
|
-
UIViewController *rootVC = keyWindow.rootViewController;
|
|
75
|
+
NSLog(@"Received token: %@", token);
|
|
81
76
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
77
|
+
[[NSUserDefaults standardUserDefaults] setObject:token forKey:@"authToken"];
|
|
78
|
+
[[NSUserDefaults standardUserDefaults] synchronize];
|
|
79
|
+
[self observeTransmitterUnbindStatus:token];
|
|
80
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
81
|
+
UIWindow *keyWindow = [UIApplication sharedApplication].delegate.window;
|
|
82
|
+
UIViewController *rootVC = keyWindow.rootViewController;
|
|
83
|
+
|
|
84
|
+
// Try to get the topmost navigation controller
|
|
85
|
+
|
|
86
|
+
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainCGM" bundle:nil];
|
|
87
|
+
UIViewController *nativeVC = [storyboard instantiateViewControllerWithIdentifier:@"StartConnectionViewController"];
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:nativeVC];
|
|
91
|
+
navController.modalPresentationStyle = UIModalPresentationOverFullScreen;
|
|
92
|
+
if (nativeVC) {
|
|
93
|
+
[rootVC presentViewController:navController animated:YES completion:nil];
|
|
94
|
+
}
|
|
95
|
+
});
|
|
94
96
|
}
|
|
95
97
|
|
|
96
98
|
RCT_EXPORT_METHOD(reconnectCgmTracky:(NSString *)token)
|
|
97
99
|
{
|
|
100
|
+
NSLog(@"Received token: %@", token);
|
|
101
|
+
|
|
98
102
|
[[NSUserDefaults standardUserDefaults] setObject:token forKey:@"authToken"];
|
|
99
103
|
[[NSUserDefaults standardUserDefaults] synchronize];
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
104
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
105
|
+
UIWindow *keyWindow = [UIApplication sharedApplication].delegate.window;
|
|
106
|
+
UIViewController *rootVC = keyWindow.rootViewController;
|
|
107
|
+
// Load the storyboard
|
|
108
|
+
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainCGM" bundle:[NSBundle mainBundle]];
|
|
109
|
+
|
|
110
|
+
// Instantiate the target ViewController
|
|
111
|
+
UIViewController *reconnectVC = [storyboard instantiateViewControllerWithIdentifier:@"ConnectToTransmitterViewController"];
|
|
112
|
+
|
|
113
|
+
// Set presentation style
|
|
114
|
+
reconnectVC.modalPresentationStyle = UIModalPresentationOverFullScreen;
|
|
115
|
+
// Set isForReconnect = YES
|
|
116
|
+
if ([reconnectVC respondsToSelector:@selector(setIsForReconnect:)]) {
|
|
117
|
+
[reconnectVC setValue:@(YES) forKey:@"isForReconnect"];
|
|
118
|
+
}
|
|
119
|
+
// Present it directly without navigation
|
|
120
|
+
if (reconnectVC) {
|
|
121
|
+
[rootVC presentViewController:reconnectVC animated:YES completion:nil];
|
|
122
|
+
}
|
|
123
|
+
});
|
|
120
124
|
}
|
|
121
125
|
|
|
122
126
|
|
|
123
127
|
RCT_EXPORT_METHOD(openHelpSupport)
|
|
124
128
|
{
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
129
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
130
|
+
UIWindow *keyWindow = [UIApplication sharedApplication].delegate.window;
|
|
131
|
+
UIViewController *rootVC = keyWindow.rootViewController;
|
|
132
|
+
|
|
133
|
+
// Load the storyboard
|
|
134
|
+
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainCGM" bundle:nil];
|
|
135
|
+
|
|
136
|
+
// Instantiate the target ViewController
|
|
137
|
+
UIViewController *chatWithExpertVC = [storyboard instantiateViewControllerWithIdentifier:@"ChatWithExpertViewController"];
|
|
138
|
+
if ([chatWithExpertVC respondsToSelector:@selector(setIsOnlyThis:)]) {
|
|
139
|
+
[chatWithExpertVC setValue:@(YES) forKey:@"isOnlyThis"];
|
|
140
|
+
}
|
|
141
|
+
// Set presentation style
|
|
142
|
+
chatWithExpertVC.modalPresentationStyle = UIModalPresentationOverFullScreen;
|
|
143
|
+
|
|
144
|
+
// Present it directly without navigation
|
|
145
|
+
if (chatWithExpertVC) {
|
|
146
|
+
[rootVC presentViewController:chatWithExpertVC animated:YES completion:nil];
|
|
147
|
+
}
|
|
148
|
+
});
|
|
143
149
|
}
|
|
144
150
|
|
|
145
151
|
RCT_EXPORT_METHOD(observeAllGlucoseData:(NSString *)token)
|
|
146
152
|
{
|
|
153
|
+
NSLog(@"Received token: %@", token);
|
|
154
|
+
|
|
147
155
|
FinalViewModelManager *manager = [FinalViewModelManager shared];
|
|
148
|
-
|
|
149
|
-
|
|
156
|
+
[[NSUserDefaults standardUserDefaults] setObject:token forKey:@"authToken"];
|
|
157
|
+
[[NSUserDefaults standardUserDefaults] synchronize];
|
|
150
158
|
|
|
151
159
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
160
|
+
UIWindow *keyWindow = [UIApplication sharedApplication].delegate.window;
|
|
161
|
+
UIViewController *rootVC = keyWindow.rootViewController;
|
|
162
|
+
|
|
163
|
+
// Load the storyboard
|
|
164
|
+
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainCGM" bundle:nil];
|
|
165
|
+
|
|
166
|
+
// Instantiate the target ViewController
|
|
167
|
+
globalAttachTransmitterVC = [storyboard instantiateViewControllerWithIdentifier:@"AttachTransmitterViewController"];
|
|
168
|
+
|
|
169
|
+
// Set presentation style
|
|
170
|
+
// chatWithExpertVC.modalPresentationStyle = UIModalPresentationOverFullScreen;
|
|
171
|
+
|
|
172
|
+
// Present it directly without navigation
|
|
173
|
+
//if (chatWithExpertVC) {
|
|
174
|
+
// [rootVC presentViewController:chatWithExpertVC animated:YES completion:nil];
|
|
175
|
+
// }
|
|
168
176
|
});
|
|
169
177
|
}
|
|
170
178
|
|
|
179
|
+
|
|
180
|
+
RCT_EXPORT_METHOD(observeTransmitterUnbindStatus:(NSString *)token)
|
|
181
|
+
{
|
|
182
|
+
NSLog(@"Received token: %@", token);
|
|
183
|
+
[[NSUserDefaults standardUserDefaults] setObject:token forKey:@"authToken"];
|
|
184
|
+
[[NSUserDefaults standardUserDefaults] synchronize];
|
|
185
|
+
FinalViewModelManager *manager = [FinalViewModelManager shared];
|
|
186
|
+
[manager callForObserveTransmitterUnbindStatus];
|
|
187
|
+
}
|
|
171
188
|
@end
|
|
@@ -838,10 +838,141 @@
|
|
|
838
838
|
</objects>
|
|
839
839
|
<point key="canvasLocation" x="5817.5572519083971" y="-27.464788732394368"/>
|
|
840
840
|
</scene>
|
|
841
|
+
<!--Bluetooth Connection View Controller-->
|
|
842
|
+
<scene sceneID="WDO-2D-8TE">
|
|
843
|
+
<objects>
|
|
844
|
+
<viewController storyboardIdentifier="BluetoothConnectionViewController" id="oE1-oy-zLp" customClass="BluetoothConnectionViewController" customModule="react_native_mytatva_rn_sdk" sceneMemberID="viewController">
|
|
845
|
+
<view key="view" contentMode="scaleToFill" id="9Vb-4A-M16">
|
|
846
|
+
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
|
|
847
|
+
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
848
|
+
<subviews>
|
|
849
|
+
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="acE-9b-zEU" customClass="CustomView" customModule="MyTatvaCare" customModuleProvider="target">
|
|
850
|
+
<rect key="frame" x="16" y="498.33333333333326" width="361" height="80"/>
|
|
851
|
+
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
|
852
|
+
<constraints>
|
|
853
|
+
<constraint firstAttribute="height" constant="80" id="vQ8-VT-xEb"/>
|
|
854
|
+
</constraints>
|
|
855
|
+
<userDefinedRuntimeAttributes>
|
|
856
|
+
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
|
|
857
|
+
<real key="value" value="16"/>
|
|
858
|
+
</userDefinedRuntimeAttribute>
|
|
859
|
+
</userDefinedRuntimeAttributes>
|
|
860
|
+
</view>
|
|
861
|
+
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="jBQ-Ld-Eau">
|
|
862
|
+
<rect key="frame" x="16" y="518.33333333333337" width="361" height="299.66666666666663"/>
|
|
863
|
+
<subviews>
|
|
864
|
+
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="nOY-sn-yyW" customClass="CustomView" customModule="MyTatvaCare" customModuleProvider="target">
|
|
865
|
+
<rect key="frame" x="16" y="133.66666666666663" width="329" height="156"/>
|
|
866
|
+
<subviews>
|
|
867
|
+
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ic_settings" translatesAutoresizingMaskIntoConstraints="NO" id="qyt-bO-X2D">
|
|
868
|
+
<rect key="frame" x="16" y="16" width="297" height="70"/>
|
|
869
|
+
<constraints>
|
|
870
|
+
<constraint firstAttribute="height" constant="70" id="b8T-KV-B1Y"/>
|
|
871
|
+
</constraints>
|
|
872
|
+
</imageView>
|
|
873
|
+
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="ic_bluetooth_button" translatesAutoresizingMaskIntoConstraints="NO" id="igd-Vx-Viq">
|
|
874
|
+
<rect key="frame" x="-218" y="111" width="765" height="20"/>
|
|
875
|
+
<constraints>
|
|
876
|
+
<constraint firstAttribute="height" constant="20" id="9Qt-Gs-HQL"/>
|
|
877
|
+
</constraints>
|
|
878
|
+
</imageView>
|
|
879
|
+
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="SRd-UJ-0aF">
|
|
880
|
+
<rect key="frame" x="10" y="96" width="309" height="50"/>
|
|
881
|
+
<constraints>
|
|
882
|
+
<constraint firstAttribute="height" constant="50" id="q6O-j2-jRG"/>
|
|
883
|
+
</constraints>
|
|
884
|
+
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
|
|
885
|
+
<connections>
|
|
886
|
+
<action selector="openBluetoothSetting:" destination="oE1-oy-zLp" eventType="touchUpInside" id="Rsp-cS-oWa"/>
|
|
887
|
+
</connections>
|
|
888
|
+
</button>
|
|
889
|
+
</subviews>
|
|
890
|
+
<color key="backgroundColor" red="1" green="0.98431372549019602" blue="0.93333333333333335" alpha="1" colorSpace="calibratedRGB"/>
|
|
891
|
+
<constraints>
|
|
892
|
+
<constraint firstItem="igd-Vx-Viq" firstAttribute="centerX" secondItem="SRd-UJ-0aF" secondAttribute="centerX" id="CTf-Em-o7N"/>
|
|
893
|
+
<constraint firstItem="qyt-bO-X2D" firstAttribute="top" secondItem="nOY-sn-yyW" secondAttribute="top" constant="16" id="Mqr-7g-WXE"/>
|
|
894
|
+
<constraint firstAttribute="trailing" secondItem="SRd-UJ-0aF" secondAttribute="trailing" constant="10" id="S8V-Lk-TjG"/>
|
|
895
|
+
<constraint firstItem="igd-Vx-Viq" firstAttribute="centerY" secondItem="SRd-UJ-0aF" secondAttribute="centerY" id="ULT-Mf-eYY"/>
|
|
896
|
+
<constraint firstItem="SRd-UJ-0aF" firstAttribute="leading" secondItem="nOY-sn-yyW" secondAttribute="leading" constant="10" id="X4n-AV-3O7"/>
|
|
897
|
+
<constraint firstAttribute="trailing" secondItem="qyt-bO-X2D" secondAttribute="trailing" constant="16" id="d2b-oE-KLE"/>
|
|
898
|
+
<constraint firstItem="SRd-UJ-0aF" firstAttribute="top" secondItem="qyt-bO-X2D" secondAttribute="bottom" constant="10" id="lBb-mr-zr3"/>
|
|
899
|
+
<constraint firstItem="qyt-bO-X2D" firstAttribute="leading" secondItem="nOY-sn-yyW" secondAttribute="leading" constant="16" id="oc7-p6-s9C"/>
|
|
900
|
+
<constraint firstAttribute="bottom" secondItem="SRd-UJ-0aF" secondAttribute="bottom" constant="10" id="saW-Ho-4SI"/>
|
|
901
|
+
</constraints>
|
|
902
|
+
<userDefinedRuntimeAttributes>
|
|
903
|
+
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
|
|
904
|
+
<real key="value" value="12"/>
|
|
905
|
+
</userDefinedRuntimeAttribute>
|
|
906
|
+
</userDefinedRuntimeAttributes>
|
|
907
|
+
</view>
|
|
908
|
+
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="axE-kI-X3J">
|
|
909
|
+
<rect key="frame" x="16" y="28.33333333333325" width="329" height="81.333333333333314"/>
|
|
910
|
+
<string key="text">If bluetooth permission is turned off. To continue syncing your CGM, please enable Bluetooth access for GoodFlip in your phone Settings</string>
|
|
911
|
+
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
912
|
+
<nil key="textColor"/>
|
|
913
|
+
<nil key="highlightedColor"/>
|
|
914
|
+
</label>
|
|
915
|
+
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Bluetooth Connection" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="oxG-ed-cux">
|
|
916
|
+
<rect key="frame" x="16" y="0.0" width="329" height="20.333333333333332"/>
|
|
917
|
+
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
918
|
+
<nil key="textColor"/>
|
|
919
|
+
<nil key="highlightedColor"/>
|
|
920
|
+
</label>
|
|
921
|
+
</subviews>
|
|
922
|
+
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
|
923
|
+
<constraints>
|
|
924
|
+
<constraint firstItem="axE-kI-X3J" firstAttribute="top" secondItem="oxG-ed-cux" secondAttribute="bottom" constant="8" id="4iq-8i-s5O"/>
|
|
925
|
+
<constraint firstAttribute="bottom" secondItem="nOY-sn-yyW" secondAttribute="bottom" constant="10" id="Fhp-Zh-y26"/>
|
|
926
|
+
<constraint firstItem="oxG-ed-cux" firstAttribute="leading" secondItem="jBQ-Ld-Eau" secondAttribute="leading" constant="16" id="Iad-FW-bv1"/>
|
|
927
|
+
<constraint firstItem="axE-kI-X3J" firstAttribute="leading" secondItem="jBQ-Ld-Eau" secondAttribute="leading" constant="16" id="YSy-uR-fNu"/>
|
|
928
|
+
<constraint firstAttribute="trailing" secondItem="oxG-ed-cux" secondAttribute="trailing" constant="16" id="bYU-Vh-f6j"/>
|
|
929
|
+
<constraint firstAttribute="trailing" secondItem="nOY-sn-yyW" secondAttribute="trailing" constant="16" id="c4n-0w-r5U"/>
|
|
930
|
+
<constraint firstItem="oxG-ed-cux" firstAttribute="top" secondItem="jBQ-Ld-Eau" secondAttribute="top" id="dIx-rh-a3t"/>
|
|
931
|
+
<constraint firstItem="nOY-sn-yyW" firstAttribute="leading" secondItem="jBQ-Ld-Eau" secondAttribute="leading" constant="16" id="dlE-Al-nMb"/>
|
|
932
|
+
<constraint firstAttribute="trailing" secondItem="axE-kI-X3J" secondAttribute="trailing" constant="16" id="liu-TT-BWa"/>
|
|
933
|
+
<constraint firstItem="nOY-sn-yyW" firstAttribute="top" secondItem="axE-kI-X3J" secondAttribute="bottom" constant="24" id="nNJ-Ia-yf7"/>
|
|
934
|
+
</constraints>
|
|
935
|
+
</view>
|
|
936
|
+
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="3VD-WB-QbJ">
|
|
937
|
+
<rect key="frame" x="329" y="512.66666666666663" width="32" height="32"/>
|
|
938
|
+
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
|
|
939
|
+
<state key="normal" image="ic_close_popup"/>
|
|
940
|
+
<connections>
|
|
941
|
+
<action selector="buttonCloseTouchUpInside:" destination="oE1-oy-zLp" eventType="touchUpInside" id="Bms-Pa-Fxq"/>
|
|
942
|
+
</connections>
|
|
943
|
+
</button>
|
|
944
|
+
</subviews>
|
|
945
|
+
<viewLayoutGuide key="safeArea" id="nkT-VN-jfq"/>
|
|
946
|
+
<color key="backgroundColor" white="0.0" alpha="0.70432079079999999" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
|
947
|
+
<constraints>
|
|
948
|
+
<constraint firstItem="nkT-VN-jfq" firstAttribute="trailing" secondItem="jBQ-Ld-Eau" secondAttribute="trailing" constant="16" id="5Ky-GJ-mFU"/>
|
|
949
|
+
<constraint firstItem="acE-9b-zEU" firstAttribute="top" secondItem="jBQ-Ld-Eau" secondAttribute="top" constant="-20" id="FEC-66-QFX"/>
|
|
950
|
+
<constraint firstItem="nkT-VN-jfq" firstAttribute="bottom" secondItem="jBQ-Ld-Eau" secondAttribute="bottom" id="Nh5-w1-yON"/>
|
|
951
|
+
<constraint firstItem="acE-9b-zEU" firstAttribute="leading" secondItem="nkT-VN-jfq" secondAttribute="leading" constant="16" id="PFg-kj-KlC"/>
|
|
952
|
+
<constraint firstItem="nkT-VN-jfq" firstAttribute="trailing" secondItem="acE-9b-zEU" secondAttribute="trailing" constant="16" id="Qui-Rl-Nvy"/>
|
|
953
|
+
<constraint firstItem="3VD-WB-QbJ" firstAttribute="centerY" secondItem="oxG-ed-cux" secondAttribute="centerY" id="Sge-rI-yId"/>
|
|
954
|
+
<constraint firstItem="jBQ-Ld-Eau" firstAttribute="leading" secondItem="nkT-VN-jfq" secondAttribute="leading" constant="16" id="gkz-AU-083"/>
|
|
955
|
+
<constraint firstItem="nkT-VN-jfq" firstAttribute="trailing" secondItem="3VD-WB-QbJ" secondAttribute="trailing" constant="32" id="nMK-UJ-pwQ"/>
|
|
956
|
+
</constraints>
|
|
957
|
+
</view>
|
|
958
|
+
<connections>
|
|
959
|
+
<outlet property="closeButton" destination="3VD-WB-QbJ" id="koF-I5-GvS"/>
|
|
960
|
+
<outlet property="labelDesc" destination="axE-kI-X3J" id="ltM-uk-9Gy"/>
|
|
961
|
+
<outlet property="labelTitle" destination="oxG-ed-cux" id="sDj-hQ-aLa"/>
|
|
962
|
+
<outlet property="openBluetoothImageview" destination="igd-Vx-Viq" id="rEv-Gh-L72"/>
|
|
963
|
+
<outlet property="settingImageView" destination="qyt-bO-X2D" id="ltH-QC-qbT"/>
|
|
964
|
+
</connections>
|
|
965
|
+
</viewController>
|
|
966
|
+
<placeholder placeholderIdentifier="IBFirstResponder" id="3YM-kX-GFu" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
|
967
|
+
</objects>
|
|
968
|
+
<point key="canvasLocation" x="6532" y="-27"/>
|
|
969
|
+
</scene>
|
|
841
970
|
</scenes>
|
|
842
971
|
<resources>
|
|
843
972
|
<image name="ic_back" width="22" height="22"/>
|
|
973
|
+
<image name="ic_bluetooth_button" width="765" height="80"/>
|
|
844
974
|
<image name="ic_close_popup" width="32" height="32"/>
|
|
975
|
+
<image name="ic_settings" width="979" height="213"/>
|
|
845
976
|
<image name="mandala" width="1560" height="776"/>
|
|
846
977
|
<namedColor name="green">
|
|
847
978
|
<color red="0.16078431372549021" green="0.61568627450980395" blue="0.41960784313725491" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
package/ios/Support/API.swift
CHANGED
|
@@ -104,22 +104,24 @@ class API {
|
|
|
104
104
|
onSuccess: @escaping () -> Void,
|
|
105
105
|
onFailure: @escaping (Error?) -> Void
|
|
106
106
|
) {
|
|
107
|
+
|
|
108
|
+
print("ios token:", token)
|
|
107
109
|
Task {
|
|
108
110
|
do {
|
|
109
111
|
let jsonData = try JSONEncoder().encode(data)
|
|
110
112
|
|
|
111
113
|
// Convert to String
|
|
112
114
|
guard let jsonString = String(data: jsonData, encoding: .utf8) else { return }
|
|
113
|
-
print("JSON Payload String:\n\(jsonString)")
|
|
115
|
+
print("===>JSON Payload String:\n\(jsonString)")
|
|
114
116
|
|
|
115
|
-
print("Raw JSON: \(data)")
|
|
117
|
+
print("===>Raw JSON: \(data)")
|
|
116
118
|
|
|
117
119
|
|
|
118
120
|
guard let encrypted = Crypto.shared.getEncryptedText(data: jsonString, encryptionKey: encryptionKey, encryptionIv: encryptionIv) else { return }
|
|
119
|
-
print("Encrypted: \(encrypted)")
|
|
121
|
+
print("===>Encrypted: \(encrypted)")
|
|
120
122
|
|
|
121
123
|
if let decrypted = Crypto.shared.getDecryptedData(cipherText: encrypted, encryptionKey: encryptionKey, encryptionIv: encryptionIv) {
|
|
122
|
-
print("Decrypted (for verification): \(decrypted)")
|
|
124
|
+
print("===>Decrypted (for verification): \(decrypted)")
|
|
123
125
|
}
|
|
124
126
|
|
|
125
127
|
let urlString = (environment == .prod ? PROD_BASE_URL : STAGE_BASE_URL) + "/cgm/logs"
|
|
@@ -141,9 +143,9 @@ class API {
|
|
|
141
143
|
}
|
|
142
144
|
|
|
143
145
|
if let responseStr = String(data: data, encoding: .utf8) {
|
|
144
|
-
print("Server Response: \(responseStr)")
|
|
146
|
+
print("===>Server Response: \(responseStr)")
|
|
145
147
|
if let decrypted = Crypto.shared.getDecryptedData(cipherText: responseStr, encryptionKey: encryptionKey, encryptionIv: encryptionIv) {
|
|
146
|
-
print("Decrypted response (for verification): \(decrypted)")
|
|
148
|
+
print("===>Decrypted response (for verification): \(decrypted)")
|
|
147
149
|
}
|
|
148
150
|
|
|
149
151
|
}
|
|
@@ -153,7 +155,7 @@ class API {
|
|
|
153
155
|
}
|
|
154
156
|
|
|
155
157
|
} catch {
|
|
156
|
-
print("Request failed: \(error.localizedDescription)")
|
|
158
|
+
print("===>Request failed: \(error.localizedDescription)")
|
|
157
159
|
DispatchQueue.main.async {
|
|
158
160
|
onFailure(error)
|
|
159
161
|
}
|
|
@@ -168,16 +170,20 @@ class API {
|
|
|
168
170
|
transmitterName: String = KLTBluetoothManager.shared().currentDevice?.advertise?.localName ?? "",
|
|
169
171
|
encryptionKey: String = PROD_ENC_KEY,
|
|
170
172
|
encryptionIv: String = PROD_ENC_IV) {
|
|
171
|
-
|
|
173
|
+
if sensorId.isEmpty { return }
|
|
174
|
+
|
|
172
175
|
let url = URL(string: "https://api-feature2.mytatva.in/api/v8/cgm/connection")!
|
|
173
176
|
var request = URLRequest(url: url)
|
|
174
177
|
request.httpMethod = "POST"
|
|
175
178
|
|
|
176
179
|
// Set headers
|
|
177
|
-
|
|
180
|
+
request.addValue("text/plain", forHTTPHeaderField: "Content-Type")
|
|
178
181
|
request.addValue(PROD_API_KEY, forHTTPHeaderField: "api-key")
|
|
179
182
|
request.addValue(TOKEN, forHTTPHeaderField: "token")
|
|
180
|
-
|
|
183
|
+
print("===>url:", "https://api-feature2.mytatva.in/api/v8/cgm/connection")
|
|
184
|
+
print("===>api-key:", PROD_API_KEY)
|
|
185
|
+
print("===>httpmMethod:","POST")
|
|
186
|
+
print("===>ios token:", TOKEN)
|
|
181
187
|
// Set request body
|
|
182
188
|
let json: [String: Any] = [
|
|
183
189
|
"sensorId": sensorId,
|
|
@@ -192,13 +198,14 @@ class API {
|
|
|
192
198
|
"timeInMillis": Date().timeIntervalSince1970 * 1000
|
|
193
199
|
]
|
|
194
200
|
]
|
|
201
|
+
print("===>json data:", json)
|
|
195
202
|
guard let jsonData = try? JSONSerialization.data(withJSONObject: json) else { return }
|
|
196
203
|
|
|
197
204
|
// Convert to String
|
|
198
205
|
guard let jsonString = String(data: jsonData, encoding: .utf8) else { return }
|
|
199
206
|
|
|
200
207
|
guard let encrypted = Crypto.shared.getEncryptedText(data: jsonString, encryptionKey: encryptionKey, encryptionIv: encryptionIv) else { return }
|
|
201
|
-
print("Encrypted: \(encrypted)")
|
|
208
|
+
print("===>Encrypted: \(encrypted)")
|
|
202
209
|
|
|
203
210
|
request.httpBody = encrypted.data(using: .utf8)
|
|
204
211
|
|
|
@@ -213,9 +220,9 @@ class API {
|
|
|
213
220
|
return
|
|
214
221
|
}
|
|
215
222
|
if let responseString = String(data: data, encoding: .utf8) {
|
|
216
|
-
print("Server Response: \(responseString)")
|
|
223
|
+
print("===>Server Response: \(responseString)")
|
|
217
224
|
if let decrypted = Crypto.shared.getDecryptedData(cipherText: responseString, encryptionKey: encryptionKey, encryptionIv: encryptionIv) {
|
|
218
|
-
print("Decrypted response (for verification): \(decrypted)")
|
|
225
|
+
print("===>Decrypted response (for verification): \(decrypted)")
|
|
219
226
|
}
|
|
220
227
|
}
|
|
221
228
|
}
|
|
@@ -223,6 +230,78 @@ class API {
|
|
|
223
230
|
|
|
224
231
|
}
|
|
225
232
|
|
|
233
|
+
func getStatus(encryptionKey: String = PROD_ENC_KEY,
|
|
234
|
+
encryptionIv: String = PROD_ENC_IV) {
|
|
235
|
+
print("ios token:", TOKEN)
|
|
236
|
+
let url = URL(string: "https://api-feature2.mytatva.in/api/v8/cgm/status")!
|
|
237
|
+
var request = URLRequest(url: url)
|
|
238
|
+
request.httpMethod = "GET"
|
|
239
|
+
|
|
240
|
+
// Set headers
|
|
241
|
+
//request.addValue("application/json", forHTTPHeaderField: "Content-Type")
|
|
242
|
+
request.addValue(PROD_API_KEY, forHTTPHeaderField: "api-key")
|
|
243
|
+
request.addValue(TOKEN, forHTTPHeaderField: "token")
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
// Set request body
|
|
247
|
+
|
|
248
|
+
// Perform request
|
|
249
|
+
let task = URLSession.shared.dataTask(with: request) { data, response, error in
|
|
250
|
+
if let error = error {
|
|
251
|
+
print("Error: \(error)")
|
|
252
|
+
return
|
|
253
|
+
}
|
|
254
|
+
guard let data = data else {
|
|
255
|
+
print("No data received")
|
|
256
|
+
return
|
|
257
|
+
}
|
|
258
|
+
if let responseString = String(data: data, encoding: .utf8) {
|
|
259
|
+
print("===>Server Response: \(responseString)")
|
|
260
|
+
if let decrypted = Crypto.shared.getDecryptedData(cipherText: responseString, encryptionKey: encryptionKey, encryptionIv: encryptionIv) {
|
|
261
|
+
print("===>Decrypted response (for verification): \(decrypted)")
|
|
262
|
+
|
|
263
|
+
if let decrptedData = decrypted.data(using: .utf8) {
|
|
264
|
+
let decoded = try? JSONDecoder().decode(CGMStatusResponse.self, from: decrptedData)
|
|
265
|
+
|
|
266
|
+
guard let sensor = decoded?.data.first,
|
|
267
|
+
!sensor.startDate.isEmpty,
|
|
268
|
+
!sensor.endDate.isEmpty else {
|
|
269
|
+
print("No valid sensor data")
|
|
270
|
+
return
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
let startDateStr = sensor.startDate
|
|
274
|
+
let endDateStr = sensor.endDate
|
|
275
|
+
|
|
276
|
+
print("Start Date: \(startDateStr)")
|
|
277
|
+
print("End Date: \(endDateStr)")
|
|
278
|
+
|
|
279
|
+
if self.isCurrentDateInRange(startDate: startDateStr, endDate: endDateStr) {
|
|
280
|
+
print("Current date is in range")
|
|
281
|
+
if KLTBluetoothManager.shared().currentDevice.initialEndDate != nil {
|
|
282
|
+
self.sendStatus(status: .transmitterDisconnect)
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
task.resume()
|
|
290
|
+
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Example date range check function (assumes yyyy-MM-dd format)
|
|
294
|
+
func isCurrentDateInRange(startDate: String, endDate: String) -> Bool {
|
|
295
|
+
let formatter = DateFormatter()
|
|
296
|
+
formatter.dateFormat = "yyyy-MM-dd"
|
|
297
|
+
guard let start = formatter.date(from: startDate),
|
|
298
|
+
let end = formatter.date(from: endDate) else {
|
|
299
|
+
return false
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
let now = Date()
|
|
303
|
+
return (now >= start) && (now <= end)
|
|
304
|
+
}
|
|
226
305
|
}
|
|
227
306
|
|
|
228
307
|
class Crypto {
|
|
@@ -241,11 +320,11 @@ class Crypto {
|
|
|
241
320
|
}
|
|
242
321
|
return hash.map { String(format: "%02x", $0) }.joined()
|
|
243
322
|
}
|
|
244
|
-
|
|
323
|
+
|
|
245
324
|
private func truncateKey(_ key: String) -> String {
|
|
246
325
|
return String(key.prefix(32)) // Use only first 32 chars
|
|
247
326
|
}
|
|
248
|
-
|
|
327
|
+
|
|
249
328
|
func getEncryptedText(data: String, encryptionKey: String, encryptionIv: String) -> String? {
|
|
250
329
|
let key = truncateKey(sha256(encryptionKey))
|
|
251
330
|
guard let keyData = key.data(using: .utf8),
|
|
@@ -284,7 +363,7 @@ class Crypto {
|
|
|
284
363
|
}
|
|
285
364
|
return nil
|
|
286
365
|
}
|
|
287
|
-
|
|
366
|
+
|
|
288
367
|
func getDecryptedData(cipherText: String, encryptionKey: String, encryptionIv: String) -> String? {
|
|
289
368
|
let key = truncateKey(sha256(encryptionKey))
|
|
290
369
|
guard let keyData = key.data(using: .utf8),
|
|
@@ -323,5 +402,20 @@ class Crypto {
|
|
|
323
402
|
}
|
|
324
403
|
return nil
|
|
325
404
|
}
|
|
405
|
+
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
struct CGMStatusResponse: Codable {
|
|
409
|
+
let code: Int
|
|
410
|
+
let status: String
|
|
411
|
+
let msg: String
|
|
412
|
+
let data: [CGMStatusItem]
|
|
413
|
+
}
|
|
326
414
|
|
|
415
|
+
struct CGMStatusItem: Codable {
|
|
416
|
+
let status: String
|
|
417
|
+
let startDate: String
|
|
418
|
+
let endDate: String
|
|
419
|
+
let sensorId: String
|
|
420
|
+
let daysToExpire: Int
|
|
327
421
|
}
|
|
@@ -13,6 +13,7 @@ class ImageTVC: UITableViewCell {
|
|
|
13
13
|
@IBOutlet weak var displayImageView: UIImageView!
|
|
14
14
|
@IBOutlet weak var topConstraint: NSLayoutConstraint!
|
|
15
15
|
|
|
16
|
+
@IBOutlet var gifView: UIImageView!
|
|
16
17
|
@IBOutlet weak var cameraView: CustomView!
|
|
17
18
|
@IBOutlet weak var cameraTitleLabel: UILabel!
|
|
18
19
|
@IBOutlet weak var cameraDescLabel: UILabel!
|
|
@@ -21,6 +22,7 @@ class ImageTVC: UITableViewCell {
|
|
|
21
22
|
var scannerView: QRScannerView!
|
|
22
23
|
override func awakeFromNib() {
|
|
23
24
|
super.awakeFromNib()
|
|
25
|
+
gifView.isHidden = true
|
|
24
26
|
ic_green_arrow.image = loadImage(named: "ic_green_arrow")
|
|
25
27
|
// Initialization code
|
|
26
28
|
cameraTitleLabel.text = "GoodFlip requires camera permission to scan the QR and connect with the sensor"
|
|
@@ -23,6 +23,13 @@
|
|
|
23
23
|
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="gpB-ZQ-qNP">
|
|
24
24
|
<rect key="frame" x="0.0" y="0.0" width="547" height="443"/>
|
|
25
25
|
</imageView>
|
|
26
|
+
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="kkL-FR-IsC">
|
|
27
|
+
<rect key="frame" x="233.66666666666663" y="0.0" width="80" height="80"/>
|
|
28
|
+
<constraints>
|
|
29
|
+
<constraint firstAttribute="width" secondItem="kkL-FR-IsC" secondAttribute="height" id="0SB-xh-jdh"/>
|
|
30
|
+
<constraint firstAttribute="width" constant="80" id="fpv-VN-NbZ"/>
|
|
31
|
+
</constraints>
|
|
32
|
+
</imageView>
|
|
26
33
|
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="qxt-oX-nmU" customClass="CustomView" customModule="react_native_mytatva_rn_sdk">
|
|
27
34
|
<rect key="frame" x="32" y="0.0" width="483" height="443"/>
|
|
28
35
|
<subviews>
|
|
@@ -76,11 +83,13 @@
|
|
|
76
83
|
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
|
77
84
|
<constraints>
|
|
78
85
|
<constraint firstAttribute="trailing" secondItem="qxt-oX-nmU" secondAttribute="trailing" constant="32" id="1Hq-0J-NOw"/>
|
|
86
|
+
<constraint firstItem="kkL-FR-IsC" firstAttribute="top" secondItem="gpB-ZQ-qNP" secondAttribute="top" id="5eL-BY-JMe"/>
|
|
79
87
|
<constraint firstAttribute="bottom" secondItem="gpB-ZQ-qNP" secondAttribute="bottom" id="9ID-Vk-pQJ"/>
|
|
80
88
|
<constraint firstItem="qxt-oX-nmU" firstAttribute="centerX" secondItem="gpB-ZQ-qNP" secondAttribute="centerX" id="PkM-9G-JhR"/>
|
|
81
89
|
<constraint firstItem="qxt-oX-nmU" firstAttribute="leading" secondItem="sXw-JT-KZP" secondAttribute="leading" constant="32" id="beG-vK-pKo"/>
|
|
82
90
|
<constraint firstItem="qxt-oX-nmU" firstAttribute="bottom" secondItem="gpB-ZQ-qNP" secondAttribute="bottom" id="fa8-fo-Kxn"/>
|
|
83
91
|
<constraint firstAttribute="trailing" secondItem="gpB-ZQ-qNP" secondAttribute="trailing" id="haZ-lF-q1J"/>
|
|
92
|
+
<constraint firstItem="kkL-FR-IsC" firstAttribute="centerX" secondItem="sXw-JT-KZP" secondAttribute="centerX" id="lfX-IA-SvJ"/>
|
|
84
93
|
<constraint firstItem="gpB-ZQ-qNP" firstAttribute="top" secondItem="sXw-JT-KZP" secondAttribute="top" id="sWR-bL-fiM"/>
|
|
85
94
|
<constraint firstItem="qxt-oX-nmU" firstAttribute="top" secondItem="gpB-ZQ-qNP" secondAttribute="top" id="uQR-V2-lOw"/>
|
|
86
95
|
<constraint firstItem="gpB-ZQ-qNP" firstAttribute="leading" secondItem="sXw-JT-KZP" secondAttribute="leading" id="zlB-UX-vzo"/>
|
|
@@ -101,6 +110,7 @@
|
|
|
101
110
|
<outlet property="cameraTitleLabel" destination="fgZ-CP-HRE" id="Vju-au-73z"/>
|
|
102
111
|
<outlet property="cameraView" destination="qxt-oX-nmU" id="vS1-ai-9pf"/>
|
|
103
112
|
<outlet property="displayImageView" destination="gpB-ZQ-qNP" id="UK8-8V-ugZ"/>
|
|
113
|
+
<outlet property="gifView" destination="kkL-FR-IsC" id="cWn-h0-m8u"/>
|
|
104
114
|
<outlet property="ic_green_arrow" destination="wjf-zK-XTL" id="OUY-QX-nxb"/>
|
|
105
115
|
<outlet property="topConstraint" destination="cjw-MH-Z86" id="jtg-E5-l6I"/>
|
|
106
116
|
</connections>
|
|
@@ -16,7 +16,7 @@ class SearchDeviceTVC: UITableViewCell {
|
|
|
16
16
|
// Initialization code
|
|
17
17
|
labelDesc.textColor = CustomColor.shared.indigo
|
|
18
18
|
labelDesc.font = FontManager.font(ofSize: 14, weight: .medium)
|
|
19
|
-
imageViewLeft.loadGif(named: "
|
|
19
|
+
imageViewLeft.loadGif(named: "searching")
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
override func setSelected(_ selected: Bool, animated: Bool) {
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
//
|
|
2
|
+
// BluetoothConnectionViewController.swift
|
|
3
|
+
// react-native-mytatva-rn-sdk
|
|
4
|
+
//
|
|
5
|
+
// Created by The Coding Studio on 13/06/25.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import UIKit
|
|
9
|
+
|
|
10
|
+
class BluetoothConnectionViewController: UIViewController {
|
|
11
|
+
|
|
12
|
+
//MARK: - Variables
|
|
13
|
+
@IBOutlet weak var labelTitle: UILabel!
|
|
14
|
+
@IBOutlet weak var labelDesc: UILabel!
|
|
15
|
+
@IBOutlet var settingImageView: UIImageView!
|
|
16
|
+
@IBOutlet var openBluetoothImageview: UIImageView!
|
|
17
|
+
@IBOutlet var closeButton: UIButton!
|
|
18
|
+
|
|
19
|
+
//MARK: - Class Methods
|
|
20
|
+
override func viewDidLoad() {
|
|
21
|
+
super.viewDidLoad()
|
|
22
|
+
|
|
23
|
+
// Do any additional setup after loading the view.
|
|
24
|
+
setupLayout()
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
func setupLayout() {
|
|
28
|
+
settingImageView.image = loadImage(named: "ic_settings")
|
|
29
|
+
openBluetoothImageview.image = loadImage(named: "ic_bluetooth_button")
|
|
30
|
+
closeButton.setImage(loadImage(named: "ic_close_popup"), for: .normal)
|
|
31
|
+
|
|
32
|
+
labelTitle.font = FontManager.font(ofSize: 18, weight: .medium)
|
|
33
|
+
labelTitle.textColor = CustomColor.shared.primaryBlack
|
|
34
|
+
|
|
35
|
+
labelDesc.font = FontManager.font(ofSize: 16, weight: .regular)
|
|
36
|
+
labelDesc.textColor = CustomColor.shared.primaryBlack
|
|
37
|
+
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
//MARK: - Action Methods
|
|
42
|
+
@IBAction func buttonCloseTouchUpInside(_ sender: UIButton) {
|
|
43
|
+
dismiss(animated: true)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@IBAction func openBluetoothSetting(_ sender: UIButton) {
|
|
47
|
+
if let settingsURL = URL(string: UIApplication.openSettingsURLString) {
|
|
48
|
+
UIApplication.shared.open(settingsURL)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -11,7 +11,7 @@ class ChatWithExpertViewController: UIViewController {
|
|
|
11
11
|
@IBOutlet weak var tableView: UITableView!
|
|
12
12
|
@IBOutlet weak var buttonBack: UIButton!
|
|
13
13
|
@IBOutlet weak var bottomButton: CustomOverlayButton!
|
|
14
|
-
|
|
14
|
+
@objc var isOnlyThis: Bool = false
|
|
15
15
|
let chatOptions = ["Purchasing New CGM", "Connecting My CGM", "Having troubles after connection"]
|
|
16
16
|
var selectedIndex = -1
|
|
17
17
|
|
|
@@ -43,14 +43,33 @@ class ChatWithExpertViewController: UIViewController {
|
|
|
43
43
|
bottomButton.labelText = "Proceed"
|
|
44
44
|
bottomButton.showLeftWhatsappImage()
|
|
45
45
|
bottomButton.buttonTapCallback = {
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
|
|
47
|
+
if let url = URL(string: "https://wa.aisensy.com/aaa1qv") {
|
|
48
|
+
if UIApplication.shared.canOpenURL(url) {
|
|
49
|
+
UIApplication.shared.open(url, options: [:], completionHandler: nil)
|
|
50
|
+
} else {
|
|
51
|
+
print("Cannot open URL")
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//let vc = ConnectToTransmitterViewController.instantiate(fromStoryboard: Enum_stroyboard.Main.rawValue)
|
|
55
|
+
//self.navigationController?.pushViewController(vc, animated: false)
|
|
48
56
|
}
|
|
49
57
|
|
|
50
58
|
}
|
|
51
59
|
|
|
52
60
|
@IBAction func buttonBackTouchUpInside(_ sender: UIButton) {
|
|
53
|
-
|
|
61
|
+
if isOnlyThis {
|
|
62
|
+
if let rootVC = UIApplication.shared.connectedScenes
|
|
63
|
+
.compactMap({ ($0 as? UIWindowScene)?.windows.first?.rootViewController })
|
|
64
|
+
.first {
|
|
65
|
+
rootVC.dismiss(animated: true, completion: nil)
|
|
66
|
+
} else if let rootViewController = UIApplication.shared.keyWindow?.rootViewController {
|
|
67
|
+
rootViewController.dismiss(animated: true, completion: nil)
|
|
68
|
+
}
|
|
69
|
+
} else {
|
|
70
|
+
self.navigationController?.popViewController(animated: true)
|
|
71
|
+
}
|
|
72
|
+
|
|
54
73
|
}
|
|
55
74
|
}
|
|
56
75
|
|
|
@@ -64,6 +64,8 @@ class ConnectToTransmitterViewController: UIViewController, KLTBluetoothDelegate
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
func setupLayout() {
|
|
67
|
+
manager?.addObserver(self, forKeyPath: "status", options: [.new], context: nil)
|
|
68
|
+
|
|
67
69
|
//BluetoothManager.shared.delegate = self
|
|
68
70
|
manager?.bluetoothDelegate = self
|
|
69
71
|
manager?.startScan()
|
|
@@ -102,12 +104,17 @@ class ConnectToTransmitterViewController: UIViewController, KLTBluetoothDelegate
|
|
|
102
104
|
rootViewController.dismiss(animated: true, completion: nil)
|
|
103
105
|
}
|
|
104
106
|
} else {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
if self.screenType == .error {
|
|
108
|
+
self.bottomButton.disable()
|
|
109
|
+
self.screenType = .searching
|
|
110
|
+
self.tableView.reloadData()
|
|
111
|
+
} else {
|
|
112
|
+
let vc = ConnectToSensorViewController.instantiate(fromStoryboard: Enum_stroyboard.Main.rawValue)
|
|
113
|
+
vc.connected = {
|
|
114
|
+
//self.showConfirmInsulinUser()
|
|
115
|
+
}
|
|
116
|
+
self.navigationController?.pushViewController(vc, animated: false)
|
|
109
117
|
}
|
|
110
|
-
self.navigationController?.pushViewController(vc, animated: false)
|
|
111
118
|
}
|
|
112
119
|
}
|
|
113
120
|
|
|
@@ -140,12 +147,42 @@ class ConnectToTransmitterViewController: UIViewController, KLTBluetoothDelegate
|
|
|
140
147
|
self.tableView.reloadData()
|
|
141
148
|
}
|
|
142
149
|
}
|
|
143
|
-
|
|
150
|
+
override func observeValue(forKeyPath keyPath: String?,
|
|
151
|
+
of object: Any?,
|
|
152
|
+
change: [NSKeyValueChangeKey : Any]?,
|
|
153
|
+
context: UnsafeMutableRawPointer?) {
|
|
154
|
+
if keyPath == "status" && context == nil {
|
|
155
|
+
if let newValue = change?[.newKey] as? Int {
|
|
156
|
+
//let btStatus = newValue
|
|
157
|
+
let btStatus: BluetoothManagerStatus = BluetoothManagerStatus(rawValue: newValue) ?? .scanStart
|
|
158
|
+
|
|
159
|
+
if btStatus == .timeOut ||
|
|
160
|
+
btStatus == .disconnected ||
|
|
161
|
+
btStatus == .handshakeFail ||
|
|
162
|
+
btStatus == .selfCheckFail ||
|
|
163
|
+
btStatus == .closed ||
|
|
164
|
+
btStatus == .modifyVoltageFailed ||
|
|
165
|
+
btStatus == .sensorLostPower ||
|
|
166
|
+
btStatus == .bindWatchTimeOut {
|
|
167
|
+
self.screenType = .error
|
|
168
|
+
bottomButton.labelText = screenType == .error ? "Retry" : "Proceed"
|
|
169
|
+
bottomButton.enable()
|
|
170
|
+
self.tableView.reloadData()
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
} else if keyPath == "status", context != nil {
|
|
174
|
+
|
|
175
|
+
} else {
|
|
176
|
+
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
|
|
177
|
+
}
|
|
178
|
+
}
|
|
144
179
|
}
|
|
145
180
|
|
|
146
181
|
extension ConnectToTransmitterViewController: UITableViewDelegate, UITableViewDataSource {
|
|
147
182
|
|
|
148
183
|
func numberOfSections(in tableView: UITableView) -> Int {
|
|
184
|
+
self.contactSupport.isHidden = screenType != .error
|
|
185
|
+
|
|
149
186
|
return enumTableSection.allCases.count
|
|
150
187
|
}
|
|
151
188
|
|
|
@@ -213,6 +250,7 @@ extension ConnectToTransmitterViewController: UITableViewDelegate, UITableViewDa
|
|
|
213
250
|
let cell: ImageTVC = tableView.dequeueReusableCell(for: indexPath)
|
|
214
251
|
cell.displayImageView.image = loadImage(named: "Take_out_transmitter")
|
|
215
252
|
cell.displayImageView.contentMode = .scaleAspectFill
|
|
253
|
+
cell.displayImageView.isHidden = false
|
|
216
254
|
return cell
|
|
217
255
|
case .searchForDevice:
|
|
218
256
|
let cell: SearchDeviceTVC = tableView.dequeueReusableCell(for: indexPath)
|
|
@@ -279,8 +317,10 @@ extension ConnectToTransmitterViewController: UITableViewDelegate, UITableViewDa
|
|
|
279
317
|
switch enumFailureTableRow(rawValue: indexPath.row)! {
|
|
280
318
|
case .failAnimation:
|
|
281
319
|
let cell: ImageTVC = tableView.dequeueReusableCell(for: indexPath)
|
|
282
|
-
cell.displayImageView.loadGif(named: "failure")
|
|
283
320
|
cell.bottomConstraint.constant = 11
|
|
321
|
+
cell.gifView.isHidden = false
|
|
322
|
+
cell.gifView.loadGif(named: "failure")
|
|
323
|
+
cell.displayImageView.isHidden = true
|
|
284
324
|
return cell
|
|
285
325
|
case .details:
|
|
286
326
|
let cell: VerticalLabelsTVC = tableView.dequeueReusableCell(for: indexPath)
|
|
@@ -210,6 +210,11 @@ class ProvidePermissionViewController: UIViewController {
|
|
|
210
210
|
updateBottomButtonState()
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
+
@objc func showTrouble(_ sender: UIButton) {
|
|
214
|
+
let vc = BluetoothConnectionViewController.instantiate(fromStoryboard: Enum_stroyboard.Main.rawValue)
|
|
215
|
+
vc.modalPresentationStyle = .overFullScreen
|
|
216
|
+
self.present(vc, animated: true, completion: nil)
|
|
217
|
+
}
|
|
213
218
|
}
|
|
214
219
|
|
|
215
220
|
extension ProvidePermissionViewController: UITableViewDelegate, UITableViewDataSource {
|
|
@@ -247,6 +252,7 @@ extension ProvidePermissionViewController: UITableViewDelegate, UITableViewDataS
|
|
|
247
252
|
cell.viewTrouble.isHidden = false
|
|
248
253
|
cell.switchUI.addTarget(self, action: #selector(bluetoothSwitchChanged(_:)), for: .valueChanged)
|
|
249
254
|
cell.switchUI.isOn = isBluetoothEnabled
|
|
255
|
+
cell.buttonTrouble.addTarget(self, action: #selector(showTrouble(_:)), for: .touchUpInside)
|
|
250
256
|
return cell
|
|
251
257
|
case .location:
|
|
252
258
|
let cell: SwitchTVC = tableView.dequeueReusableCell(for: indexPath)
|
|
@@ -14,6 +14,12 @@ import Foundation
|
|
|
14
14
|
super.init()
|
|
15
15
|
viewModel.initialize()
|
|
16
16
|
}
|
|
17
|
+
@objc public func callForObserveTransmitterUnbindStatus() {
|
|
18
|
+
let sensorID = UserDefaults.standard.string(forKey: "sensorId") ?? ""
|
|
19
|
+
if !sensorID.isEmpty {
|
|
20
|
+
API.shared.getStatus()
|
|
21
|
+
}
|
|
22
|
+
}
|
|
17
23
|
}
|
|
18
24
|
|
|
19
25
|
class FinalViewModel: NSObject {
|
|
@@ -129,7 +135,7 @@ class FinalViewModel: NSObject {
|
|
|
129
135
|
print("===> all data count: ", data.count)
|
|
130
136
|
KLTDatabaseHandler.shared().reloadQueryHistoryData()
|
|
131
137
|
if let device = KLTBluetoothManager.shared().currentDevice {
|
|
132
|
-
let arrayFromInitial = KLTDatabaseHandler.shared().queryReceiveData(with: device, needUserBG:
|
|
138
|
+
let arrayFromInitial = KLTDatabaseHandler.shared().queryReceiveData(with: device, needUserBG: false) as! [ReceiveData]
|
|
133
139
|
print(arrayFromInitial)
|
|
134
140
|
print("===> arrayFromInitial count: ", arrayFromInitial.count)
|
|
135
141
|
self.uploadData(data: arrayFromInitial)
|
|
@@ -294,6 +300,8 @@ class FinalViewModel: NSObject {
|
|
|
294
300
|
|
|
295
301
|
|
|
296
302
|
}
|
|
303
|
+
|
|
304
|
+
|
|
297
305
|
|
|
298
306
|
}
|
|
299
307
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"images" : [
|
|
3
|
+
{
|
|
4
|
+
"filename" : "secondary button.png",
|
|
5
|
+
"idiom" : "universal",
|
|
6
|
+
"scale" : "1x"
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"idiom" : "universal",
|
|
10
|
+
"scale" : "2x"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"idiom" : "universal",
|
|
14
|
+
"scale" : "3x"
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
"info" : {
|
|
18
|
+
"author" : "xcode",
|
|
19
|
+
"version" : 1
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"images" : [
|
|
3
|
+
{
|
|
4
|
+
"filename" : "settings.png",
|
|
5
|
+
"idiom" : "universal",
|
|
6
|
+
"scale" : "1x"
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"idiom" : "universal",
|
|
10
|
+
"scale" : "2x"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"idiom" : "universal",
|
|
14
|
+
"scale" : "3x"
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
"info" : {
|
|
18
|
+
"author" : "xcode",
|
|
19
|
+
"version" : 1
|
|
20
|
+
}
|
|
21
|
+
}
|
|
Binary file
|