react-native-mytatva-rn-sdk 1.2.37 → 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,415 @@
1
+ //
2
+ // ConnectToSensorViewController.swift
3
+ // MyTatvaCare
4
+ //
5
+ // Created by Nirav Ramani on 08/05/25.
6
+ //
7
+
8
+ import UIKit
9
+ import AVFoundation
10
+ class ConnectToSensorViewController: UIViewController {
11
+ @IBOutlet weak var contactSupport: CustomOverlayButton!
12
+ @IBOutlet weak var customTopView: CustomTopUIView!
13
+ @IBOutlet weak var tableView: UITableView!
14
+ @IBOutlet weak var bottomButton: CustomOverlayButton!
15
+
16
+ enum enumTableSection: Int, CaseIterable {
17
+ case details
18
+ case success
19
+ case error
20
+ }
21
+
22
+ enum enumTableRow: Int, CaseIterable {
23
+ case separator
24
+ case verticalLabel
25
+ case image
26
+ case camera
27
+ }
28
+
29
+ enum enumSuccessTableRow: Int, CaseIterable {
30
+ case success
31
+ case note
32
+ }
33
+
34
+ enum enumFailureTableRow: Int, CaseIterable {
35
+ case failAnimation
36
+ case details
37
+ case image
38
+ case watchVideo
39
+ }
40
+
41
+ enum enumScreenType {
42
+ case camera
43
+ case success
44
+ case error
45
+ }
46
+
47
+ var isFromReconnect: Bool = false
48
+ var connectedTime: Date?
49
+ var connected:(()->())?
50
+ var screenType: enumScreenType = .camera
51
+ var isCodeDetected = false
52
+ var isPermissionGiven: Bool = false
53
+ let manager = KLTBluetoothManager.shared()
54
+
55
+ override func viewDidLoad() {
56
+ super.viewDidLoad()
57
+ // Do any additional setup after loading the view.
58
+ setupLayout()
59
+ }
60
+
61
+ func setupLayout() {
62
+ manager?.addObserver(self, forKeyPath: "status", options: [.new], context: nil)
63
+
64
+
65
+ tableView.delegate = self
66
+ tableView.dataSource = self
67
+ tableView.registerNibs([VerticalLabelsTVC.self,
68
+ SeparatorTVC.self,
69
+ ImageTVC.self,
70
+ SearchDeviceTVC.self,
71
+ ConnectDeviceTVC.self,
72
+ ConnectSuccessTVC.self,
73
+ NoteTVC.self,
74
+ PodDetailsTVC.self,
75
+ WatchVideoTVC.self])
76
+ tableView.reloadData()
77
+ contactSupport.isHidden = screenType != .error
78
+ contactSupport.labelText = "Contact Support"
79
+ contactSupport.setBorderOnly()
80
+ contactSupport.buttonTapCallback = {
81
+ }
82
+
83
+ bottomButton.labelText = screenType == .error ? "Retry" : "Proceed"
84
+
85
+ if screenType == .error {
86
+ bottomButton.hideRightArrow()
87
+ }
88
+
89
+ bottomButton.buttonTapCallback = {
90
+ let isForReconnect = UserDefaults.standard.bool(forKey: "isForReconnect")
91
+ if isForReconnect {
92
+ let vc = AttachTransmitterViewController.instantiate(fromStoryboard: Enum_stroyboard.Main.rawValue)
93
+ self.navigationController?.pushViewController(vc, animated: false)
94
+ } else {
95
+ let vc = PutOnTheSensorViewController.instantiate(fromStoryboard: Enum_stroyboard.Main.rawValue)
96
+ self.navigationController?.pushViewController(vc, animated: false)
97
+ }
98
+ }
99
+
100
+ customTopView.onDemoTapped = {
101
+ let webVC = WebViewController()
102
+ webVC.modalPresentationStyle = .formSheet
103
+ webVC.videoURL = URL(string: watchCGMVideo)
104
+ self.present(webVC, animated: true, completion: nil)
105
+ }
106
+ customTopView.onCloseTapped = {
107
+ let vc = ExitJourneyViewController.instantiate(fromStoryboard: Enum_stroyboard.Main.rawValue)
108
+ vc.modalPresentationStyle = .overFullScreen
109
+ self.present(vc, animated: true, completion: nil)
110
+ }
111
+ customTopView.onWhatsAppTapped = {
112
+ let vc = ChatWithExpertViewController.instantiate(fromStoryboard: Enum_stroyboard.Main.rawValue)
113
+ self.navigationController?.pushViewController(vc, animated: false)
114
+ }
115
+ checkCameraPermission()
116
+ bottomButton.disable()
117
+ }
118
+
119
+ func checkCameraPermission() {
120
+ let status = AVCaptureDevice.authorizationStatus(for: .video)
121
+
122
+ switch status {
123
+ case .authorized:
124
+ self.isPermissionGiven = true
125
+ print("Camera access is authorized")
126
+ case .notDetermined:
127
+ AVCaptureDevice.requestAccess(for: .video) { granted in
128
+ if granted {
129
+ self.isPermissionGiven = true
130
+ DispatchQueue.main.async {
131
+ self.tableView.reloadData()
132
+ }
133
+ print("Camera access granted")
134
+ } else {
135
+ print("Camera access denied")
136
+ self.showCameraAccessAlert()
137
+ }
138
+ }
139
+ case .denied, .restricted:
140
+ print("Camera access denied or restricted")
141
+ self.showCameraAccessAlert()
142
+ @unknown default:
143
+ self.showCameraAccessAlert()
144
+ print("Unknown camera authorization status")
145
+ }
146
+ DispatchQueue.main.async {
147
+ self.tableView.reloadData()
148
+ }
149
+
150
+ }
151
+
152
+ func showCameraAccessAlert() {
153
+ let alert = UIAlertController(
154
+ title: "Camera Access Needed",
155
+ message: "Please enable camera access in Settings to use this feature.",
156
+ preferredStyle: .alert
157
+ )
158
+ alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))
159
+ alert.addAction(UIAlertAction(title: "Open Settings", style: .default) { _ in
160
+ if let settingsURL = URL(string: UIApplication.openSettingsURLString) {
161
+ UIApplication.shared.open(settingsURL)
162
+ }
163
+ })
164
+
165
+ DispatchQueue.main.async {
166
+ self.present(alert, animated: true)
167
+ }
168
+ }
169
+
170
+ func connectSensor(value: String, controller: ConnectToSensorViewController) {
171
+ UserDefaults.standard.set(value, forKey: "sensorId")
172
+ var isMatch = false
173
+
174
+ 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}$"#
175
+ var predicate = NSPredicate(format: "SELF MATCHES %@", regex)
176
+
177
+ if predicate.evaluate(with: value) {
178
+ isMatch = true
179
+ } else {
180
+ regex = #"^[A-Z1-9][1-9][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]{6}[0-9A-Z]{3}$"#
181
+ predicate = NSPredicate(format: "SELF MATCHES %@", regex)
182
+ if predicate.evaluate(with: value) {
183
+ isMatch = true
184
+ }
185
+ }
186
+
187
+ if isMatch {
188
+ let data = AlgorithmTools.decodeCT(value)
189
+
190
+ if data.k > 0 || data.r > 0 {
191
+ //KLTLocalSettingManager.shareInstance.deviceInfoSensor = value
192
+ UserDefaults.standard.set(data.k, forKey: "algo_k")
193
+ UserDefaults.standard.set(data.r, forKey: "algo_r")
194
+ UserDefaults.standard.synchronize()
195
+ //self.connected?()
196
+ //controller.navigationController?.popViewController(animated: true)
197
+ self.showConfirmInsulinUser()
198
+ //showConfirmInsulinUser()
199
+ return
200
+ }
201
+ }
202
+
203
+ //controller.resumeScanning()
204
+ }
205
+ func connectThisSensor() {
206
+ // Connect the transmitter
207
+ manager?.connectPeripheral(manager?.readyToConnectedPeripheral)
208
+ }
209
+
210
+ func showConfirmInsulinUser() {
211
+ let typeOfDiabetes = UserDefaults.standard.object(forKey: "profilePatientType") as? NSNumber
212
+
213
+ if let diabetesType = typeOfDiabetes {
214
+ // LocalizedString(@"user_diabete_no") index is 0
215
+ if diabetesType.intValue == 0 {
216
+ // No
217
+ UserDefaults.standard.set(2, forKey: "algo_user_type")
218
+ } else {
219
+ // Yes
220
+ UserDefaults.standard.set(1, forKey: "algo_user_type")
221
+ }
222
+ } else {
223
+ // Not selected
224
+ UserDefaults.standard.set(0, forKey: "algo_user_type")
225
+ }
226
+
227
+ UserDefaults.standard.synchronize() // Optional, rarely needed in modern iOS
228
+
229
+ connectThisSensor()
230
+ }
231
+ override func observeValue(forKeyPath keyPath: String?,
232
+ of object: Any?,
233
+ change: [NSKeyValueChangeKey : Any]?,
234
+ context: UnsafeMutableRawPointer?) {
235
+ if keyPath == "status" && context == nil {
236
+ if let newValue = change?[.newKey] as? Int {
237
+ //let btStatus = newValue
238
+ let btStatus: BluetoothManagerStatus = BluetoothManagerStatus(rawValue: newValue) ?? .scanStart
239
+
240
+ if btStatus == .initialStart {
241
+ self.connectedTime = Date()
242
+ print("Success")
243
+ screenType = .success
244
+ tableView.reloadData()
245
+ bottomButton.enable()
246
+ if self.isFromReconnect {
247
+ let _ = FinalViewModelManager.shared
248
+ NotificationCenter.default.post(name: Notification.Name("cgmDeviceEvent"), object: nil, userInfo: ["a":"a"])
249
+ if let rootVC = UIApplication.shared.connectedScenes
250
+ .compactMap({ ($0 as? UIWindowScene)?.windows.first?.rootViewController })
251
+ .first {
252
+ rootVC.dismiss(animated: true, completion: nil)
253
+ } else if let rootViewController = UIApplication.shared.keyWindow?.rootViewController {
254
+ rootViewController.dismiss(animated: true, completion: nil)
255
+ }
256
+ }
257
+ } else if btStatus == .closed || btStatus == .modifyVoltageFailed {
258
+ // Handle failed or closed status
259
+
260
+ navigationController?.popToRootViewController(animated: true)
261
+ }
262
+ }
263
+ } else if keyPath == "status", context != nil {
264
+ if let playerItem = object as? AVPlayerItem {
265
+ if playerItem.status == .readyToPlay {
266
+ if UserDefaults.standard.integer(forKey: "bgmode") == 0 {
267
+ // player?.play()
268
+ }
269
+ }
270
+ }
271
+ } else {
272
+ super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
273
+ }
274
+ }
275
+
276
+ }
277
+
278
+ extension ConnectToSensorViewController: UITableViewDelegate, UITableViewDataSource {
279
+
280
+ func numberOfSections(in tableView: UITableView) -> Int {
281
+ return enumTableSection.allCases.count
282
+ }
283
+
284
+ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
285
+ switch enumTableSection(rawValue: section)! {
286
+ case .details:
287
+ return (screenType == .camera) ? enumTableRow.allCases.count : 0
288
+ case .success:
289
+ return screenType == .success ? enumSuccessTableRow.allCases.count : 0
290
+ case .error:
291
+ return screenType == .error ? enumFailureTableRow.allCases.count : 0
292
+ }
293
+ }
294
+
295
+ func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
296
+ switch enumTableSection(rawValue: indexPath.section)! {
297
+ case .details:
298
+ switch enumTableRow(rawValue: indexPath.row) {
299
+ case .image:
300
+ return (UIScreen.main.bounds.width * 120 / 390) + 40
301
+ case .camera:
302
+ return 220
303
+ default:
304
+ return UITableView.automaticDimension
305
+ }
306
+ case .error:
307
+ switch enumFailureTableRow(rawValue: indexPath.row) {
308
+ case .failAnimation:
309
+ return 120
310
+ case .image:
311
+ return (UIScreen.main.bounds.width * 120 / 390) + 20
312
+ default:
313
+ return UITableView.automaticDimension
314
+ }
315
+ default:
316
+ return UITableView.automaticDimension
317
+ }
318
+ }
319
+
320
+ func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
321
+ switch enumTableSection(rawValue: indexPath.section)! {
322
+ case .details:
323
+ switch enumTableRow(rawValue: indexPath.row)! {
324
+ case .separator:
325
+ let cell: SeparatorTVC = tableView.dequeueReusableCell(for: indexPath)
326
+ return cell
327
+ case .verticalLabel:
328
+ let cell: VerticalLabelsTVC = tableView.dequeueReusableCell(for: indexPath)
329
+ cell.label1.text = "STEP 3"
330
+ cell.label2.text = "Connect to your Sensor"
331
+ cell.label3.text = "Scan the QR on the back of the sensor to connect with the GoodFlip app"
332
+ return cell
333
+ case .image:
334
+ let cell: ImageTVC = tableView.dequeueReusableCell(for: indexPath)
335
+ cell.displayImageView.image = loadImage(named: "flip_the_reference")
336
+ cell.displayImageView.contentMode = .scaleAspectFill
337
+ cell.displayImageView.isHidden = false
338
+ cell.cameraView.isHidden = true
339
+ return cell
340
+ case .camera:
341
+ let cell: ImageTVC = tableView.dequeueReusableCell(for: indexPath)
342
+ cell.displayImageView.contentMode = .scaleAspectFill
343
+ cell.displayImageView.isHidden = true
344
+ cell.cameraView.isHidden = false
345
+ if isPermissionGiven {
346
+ DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
347
+ cell.setupQRView()
348
+ cell.scannerView?.onCodeDetected = { data in
349
+ if !self.isCodeDetected {
350
+ self.isCodeDetected = true
351
+ self.connectSensor(value: data, controller: self)
352
+ }
353
+ }
354
+ }
355
+ }
356
+ return cell
357
+ }
358
+ case .success:
359
+ switch enumSuccessTableRow(rawValue: indexPath.row)! {
360
+ case .success:
361
+ let cell: ConnectSuccessTVC = tableView.dequeueReusableCell(for: indexPath)
362
+ let dateFormatter = DateFormatter()
363
+ dateFormatter.dateFormat = "dd-MM-yyyy hh:mm a"
364
+ dateFormatter.timeZone = TimeZone.current
365
+ if let connectedTime = connectedTime {
366
+ // Convert the Date to a String
367
+ let dateString = dateFormatter.string(from: connectedTime)
368
+ cell.labelDate.text = "Connected on \(String(describing: dateString))"
369
+ } else {
370
+ cell.labelDate.text = ""
371
+ }
372
+ cell.labelDesc.isHidden = true
373
+ cell.labelTitle.text = "Sensor Connected Successfully"
374
+ cell.setImageForCGM()
375
+ return cell
376
+
377
+ case .note:
378
+ let cell: NoteTVC = tableView.dequeueReusableCell(for: indexPath)
379
+ cell.setImportantNote(isFromSuccessConnection: true)
380
+ return cell
381
+ }
382
+ case .error:
383
+ switch enumFailureTableRow(rawValue: indexPath.row)! {
384
+ case .failAnimation:
385
+ let cell: ImageTVC = tableView.dequeueReusableCell(for: indexPath)
386
+ cell.displayImageView.loadGif(named: "failure")
387
+ cell.bottomConstraint.constant = 11
388
+ return cell
389
+ case .details:
390
+ let cell: VerticalLabelsTVC = tableView.dequeueReusableCell(for: indexPath)
391
+ cell.topConstraint.constant = 0
392
+ cell.label1.isHidden = true
393
+ cell.label2.text = "Unable to detect sensor"
394
+ cell.label3.text = "Make sure there is proper lighting in the room"
395
+ return cell
396
+ case .image:
397
+ let cell: ImageTVC = tableView.dequeueReusableCell(for: indexPath)
398
+ cell.topConstraint.constant = 0
399
+ cell.displayImageView.image = loadImage(named: "flip_the_reference")
400
+ cell.displayImageView.contentMode = .scaleAspectFill
401
+ return cell
402
+ case .watchVideo:
403
+ let cell: WatchVideoTVC = tableView.dequeueReusableCell(for: indexPath)
404
+ cell.onPlayVideo = {
405
+ let webVC = WebViewController()
406
+ webVC.modalPresentationStyle = .formSheet
407
+ webVC.videoURL = URL(string: qrScanFailed)
408
+ self.present(webVC, animated: true, completion: nil)
409
+ }
410
+ return cell
411
+ }
412
+ }
413
+ }
414
+ }
415
+
@@ -0,0 +1,219 @@
1
+ //
2
+ // ViewController.swift
3
+ // MyTatvaCare
4
+ //
5
+ // Created by Nirav Ramani on 05/05/25.
6
+ //
7
+
8
+ import UIKit
9
+ import WebKit
10
+ import CoreBluetooth
11
+ import CoreLocation
12
+
13
+ class StartConnectionViewController: UIViewController {
14
+
15
+ @IBOutlet weak var customTopView: CustomTopUIView!
16
+ @IBOutlet weak var tableView: UITableView!
17
+ @IBOutlet weak var startConnectionJourneyButton: CustomOverlayButton!
18
+ @objc var isForReconnect: Bool = false
19
+ var webView: WKWebView!
20
+ // Declare the CBCentralManager
21
+ var centralManager: CBCentralManager?
22
+ var isBluetoothEnabled: Bool = false
23
+
24
+ // Declare the CLLocationManager
25
+ var locationManager: CLLocationManager?
26
+ var isLocationEnabled: Bool = false
27
+
28
+ enum enumTableRow: Int, CaseIterable {
29
+ case separator
30
+ case verticalLabel
31
+ case image
32
+ case chargingIndicator
33
+ }
34
+
35
+ override func viewDidLoad() {
36
+ super.viewDidLoad()
37
+ // Do any additional setup after loading the view.
38
+ setupLayout()
39
+ //checkForDevice()
40
+ }
41
+
42
+ func setupLayout() {
43
+ navigationController?.navigationBar.isHidden = true
44
+ tableView.delegate = self
45
+ tableView.dataSource = self
46
+ tableView.registerNibs([VerticalLabelsTVC.self,
47
+ SeparatorTVC.self,
48
+ ImageTVC.self,
49
+ ChargingIndicatorTVC.self])
50
+ tableView.reloadData()
51
+
52
+ UserDefaults.standard.set(isForReconnect, forKey: "isForReconnect")
53
+ let isForReconnect = UserDefaults.standard.bool(forKey: "isForReconnect")
54
+
55
+ if isForReconnect {
56
+ startConnectionJourneyButton.labelText = "Start Reconnection Journey"
57
+ } else {
58
+ startConnectionJourneyButton.labelText = "Start Connection Journey"
59
+ }
60
+
61
+ checkLocationPermission()
62
+ centralManager = CBCentralManager(delegate: self, queue: nil)
63
+ checkBluetoothPermission()
64
+
65
+ startConnectionJourneyButton.buttonTapCallback = {
66
+ let isForReconnect = UserDefaults.standard.bool(forKey: "isForReconnect")
67
+ if isForReconnect {
68
+ self.updateBottomButtonState()
69
+ } else {
70
+ let vc = ProvidePermissionViewController.instantiate(fromStoryboard: Enum_stroyboard.Main.rawValue)
71
+ self.navigationController?.pushViewController(vc, animated: false)
72
+ }
73
+ }
74
+
75
+ customTopView.onDemoTapped = {
76
+ let webVC = WebViewController()
77
+ webVC.modalPresentationStyle = .formSheet // or .pageSheet, .fullScreen
78
+ webVC.videoURL = URL(string: watchCGMVideo)
79
+ self.present(webVC, animated: true, completion: nil)
80
+ }
81
+
82
+ customTopView.onCloseTapped = {
83
+ let vc = ExitJourneyViewController.instantiate(fromStoryboard: Enum_stroyboard.Main.rawValue)
84
+ vc.modalPresentationStyle = .overFullScreen
85
+ self.present(vc, animated: true, completion: nil)
86
+ }
87
+
88
+ customTopView.onWhatsAppTapped = {
89
+ let vc = ChatWithExpertViewController.instantiate(fromStoryboard: Enum_stroyboard.Main.rawValue)
90
+ self.navigationController?.pushViewController(vc, animated: false)
91
+ }
92
+ }
93
+
94
+ func checkForDevice() {
95
+ let manager = KLTBluetoothManager.shared()
96
+ let currentDevice = manager?.currentDevice
97
+
98
+ if (currentDevice != nil) {
99
+ let eDevice : EDevice = EDevice.getEnumDevice(currentDevice?.advertise?.localName ?? "")
100
+ let viewModel = FinalViewModel()
101
+ viewModel.initialPeriod = Int(eDevice.initNumber * 3 * 60)
102
+
103
+ let vc = AttachTransmitterViewController.instantiate(fromStoryboard: Enum_stroyboard.Main.rawValue)
104
+ vc.viewModel = viewModel
105
+ self.navigationController?.pushViewController(vc, animated: false)
106
+ } else {
107
+ // 未连接任何发射器
108
+ // stay on this screen
109
+ }
110
+ }
111
+
112
+ private func updateBottomButtonState() {
113
+ if isBluetoothEnabled && isLocationEnabled {
114
+ let vc = ConnectToTransmitterViewController.instantiate(fromStoryboard: Enum_stroyboard.Main.rawValue)
115
+ self.navigationController?.pushViewController(vc, animated: false)
116
+ } else {
117
+ let vc = ProvidePermissionViewController.instantiate(fromStoryboard: Enum_stroyboard.Main.rawValue)
118
+ self.navigationController?.pushViewController(vc, animated: false)
119
+ }
120
+ }
121
+
122
+ // Function to check Location Permission and State
123
+ private func checkLocationPermission() {
124
+ // Check if location services are enabled
125
+
126
+ let status = CLLocationManager.authorizationStatus()
127
+
128
+ switch status {
129
+ case .notDetermined:
130
+ print("Location permission is not determined.")
131
+ // Request permission to use location services
132
+ locationManager?.requestWhenInUseAuthorization()
133
+ case .restricted, .denied:
134
+ print("Location permission is restricted or denied.")
135
+ case .authorizedWhenInUse, .authorizedAlways:
136
+ print("Location is authorized.")
137
+ isLocationEnabled = true
138
+
139
+ @unknown default:
140
+ print("Unknown location status.")
141
+ }
142
+ }
143
+
144
+ // Function to check Bluetooth Permission and State
145
+ private func checkBluetoothPermission() {
146
+ isBluetoothEnabled = false
147
+ switch centralManager?.state {
148
+ case .unknown:
149
+ print("Bluetooth state is unknown.")
150
+ case .resetting:
151
+ print("Bluetooth state is resetting.")
152
+ case .unsupported:
153
+ print("Bluetooth is unsupported on this device.")
154
+ case .unauthorized:
155
+ print("Bluetooth is unauthorized.")
156
+ case .poweredOff:
157
+ print("Bluetooth is powered off.")
158
+ case .poweredOn:
159
+ print("Bluetooth is powered on and available.")
160
+ isBluetoothEnabled = true
161
+ case .none:
162
+ print("Unknown Bluetooth state.")
163
+ @unknown default:
164
+ print("Unknown Bluetooth state.")
165
+ }
166
+ }
167
+ }
168
+
169
+ extension StartConnectionViewController: UITableViewDelegate, UITableViewDataSource {
170
+
171
+ func numberOfSections(in tableView: UITableView) -> Int {
172
+ return 1
173
+ }
174
+
175
+ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
176
+ return enumTableRow.allCases.count
177
+ }
178
+
179
+ func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
180
+ switch enumTableRow(rawValue: indexPath.row) {
181
+ case .image:
182
+ return 205
183
+ default:
184
+ return UITableView.automaticDimension
185
+ }
186
+ }
187
+
188
+ func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
189
+ switch enumTableRow(rawValue: indexPath.row)! {
190
+ case .separator:
191
+ let cell: SeparatorTVC = tableView.dequeueReusableCell(for: indexPath)
192
+ return cell
193
+ case .verticalLabel:
194
+ let cell: VerticalLabelsTVC = tableView.dequeueReusableCell(for: indexPath)
195
+ cell.label1.text = "STEP1"
196
+ cell.label1.isHidden = true
197
+ cell.label2.text = "Before You Start"
198
+ cell.label3.text = "Make sure your transmitter is fully charged. Put it in the charging pod until the blinking white light turns blue. This takes about 15 minutes"
199
+ return cell
200
+ case .image:
201
+ let cell: ImageTVC = tableView.dequeueReusableCell(for: indexPath)
202
+ cell.displayImageView.image = loadImage(named: "charging_pod")
203
+ return cell
204
+ case .chargingIndicator:
205
+ let cell: ChargingIndicatorTVC = tableView.dequeueReusableCell(for: indexPath)
206
+ return cell
207
+ }
208
+ }
209
+ }
210
+
211
+
212
+ extension StartConnectionViewController: CBCentralManagerDelegate {
213
+
214
+ // Delegate method called when Bluetooth state changes
215
+ func centralManagerDidUpdateState(_ central: CBCentralManager) {
216
+ checkBluetoothPermission()
217
+ }
218
+ }
219
+