Manos Chorianopoulos

Telematics functionality with temporary ui

...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
7 <key>Pods-SwiftWarplyFramework.xcscheme_^#shared#^_</key> 7 <key>Pods-SwiftWarplyFramework.xcscheme_^#shared#^_</key>
8 <dict> 8 <dict>
9 <key>orderHint</key> 9 <key>orderHint</key>
10 - <integer>0</integer> 10 + <integer>1</integer>
11 </dict> 11 </dict>
12 </dict> 12 </dict>
13 </dict> 13 </dict>
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
7 <key>SwiftWarplyFramework.xcscheme_^#shared#^_</key> 7 <key>SwiftWarplyFramework.xcscheme_^#shared#^_</key>
8 <dict> 8 <dict>
9 <key>orderHint</key> 9 <key>orderHint</key>
10 - <integer>1</integer> 10 + <integer>0</integer>
11 </dict> 11 </dict>
12 </dict> 12 </dict>
13 </dict> 13 </dict>
......
...@@ -207,9 +207,188 @@ ...@@ -207,9 +207,188 @@
207 <view key="view" contentMode="scaleToFill" id="VXV-92-AN4"> 207 <view key="view" contentMode="scaleToFill" id="VXV-92-AN4">
208 <rect key="frame" x="0.0" y="0.0" width="414" height="896"/> 208 <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
209 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> 209 <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
210 + <subviews>
211 + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="sqF-9o-yrt" userLabel="Main View">
212 + <rect key="frame" x="0.0" y="48" width="414" height="848"/>
213 + <subviews>
214 + <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" ambiguous="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qS7-w4-Ndd">
215 + <rect key="frame" x="0.0" y="0.0" width="414" height="848"/>
216 + <subviews>
217 + <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="kWM-gy-2YQ">
218 + <rect key="frame" x="0.0" y="0.0" width="414" height="848"/>
219 + <subviews>
220 + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Acceleration" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="OyC-mT-xus">
221 + <rect key="frame" x="20" y="30" width="374" height="20"/>
222 + <fontDescription key="fontDescription" name="PeridotPE-Regular" family="Peridot PE" pointSize="16"/>
223 + <color key="textColor" red="0.12941176469999999" green="0.12941176469999999" blue="0.12941176469999999" alpha="1" colorSpace="calibratedRGB"/>
224 + <nil key="highlightedColor"/>
225 + </label>
226 + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="0.0 m/s²" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tgP-fo-JIb">
227 + <rect key="frame" x="20" y="65" width="374" height="21"/>
228 + <fontDescription key="fontDescription" name="PeridotPE-Bold" family="Peridot PE" pointSize="17"/>
229 + <color key="textColor" red="0.12941176469999999" green="0.12941176469999999" blue="0.12941176469999999" alpha="1" colorSpace="calibratedRGB"/>
230 + <nil key="highlightedColor"/>
231 + </label>
232 + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Velocity" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="c66-2s-8OX">
233 + <rect key="frame" x="20" y="116" width="374" height="20"/>
234 + <fontDescription key="fontDescription" name="PeridotPE-Regular" family="Peridot PE" pointSize="16"/>
235 + <color key="textColor" red="0.12941176469999999" green="0.12941176469999999" blue="0.12941176469999999" alpha="1" colorSpace="calibratedRGB"/>
236 + <nil key="highlightedColor"/>
237 + </label>
238 + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="0.0 km/h" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vix-aW-Fo4">
239 + <rect key="frame" x="20" y="151" width="374" height="21"/>
240 + <fontDescription key="fontDescription" name="PeridotPE-Bold" family="Peridot PE" pointSize="17"/>
241 + <color key="textColor" red="0.12941176469999999" green="0.12941176469999999" blue="0.12941176469999999" alpha="1" colorSpace="calibratedRGB"/>
242 + <nil key="highlightedColor"/>
243 + </label>
244 + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Orientation Count" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="nIl-Tk-yrn">
245 + <rect key="frame" x="20" y="202" width="187" height="20"/>
246 + <fontDescription key="fontDescription" name="PeridotPE-Regular" family="Peridot PE" pointSize="16"/>
247 + <color key="textColor" red="0.12941176469999999" green="0.12941176469999999" blue="0.12941176469999999" alpha="1" colorSpace="calibratedRGB"/>
248 + <nil key="highlightedColor"/>
249 + </label>
250 + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Touch Count" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="y6m-dK-ijX">
251 + <rect key="frame" x="207" y="202" width="187" height="20"/>
252 + <fontDescription key="fontDescription" name="PeridotPE-Regular" family="Peridot PE" pointSize="16"/>
253 + <color key="textColor" red="0.12941176469999999" green="0.12941176469999999" blue="0.12941176469999999" alpha="1" colorSpace="calibratedRGB"/>
254 + <nil key="highlightedColor"/>
255 + </label>
256 + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VGj-qa-qFN">
257 + <rect key="frame" x="20" y="237" width="187" height="0.0"/>
258 + <fontDescription key="fontDescription" name="PeridotPE-Bold" family="Peridot PE" pointSize="17"/>
259 + <color key="textColor" red="0.12941176469999999" green="0.12941176469999999" blue="0.12941176469999999" alpha="1" colorSpace="calibratedRGB"/>
260 + <nil key="highlightedColor"/>
261 + </label>
262 + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="z8p-ZO-TCw">
263 + <rect key="frame" x="207" y="237" width="187" height="0.0"/>
264 + <fontDescription key="fontDescription" name="PeridotPE-Bold" family="Peridot PE" pointSize="17"/>
265 + <color key="textColor" red="0.12941176469999999" green="0.12941176469999999" blue="0.12941176469999999" alpha="1" colorSpace="calibratedRGB"/>
266 + <nil key="highlightedColor"/>
267 + </label>
268 + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Records Saved" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="CdA-Ls-g0v">
269 + <rect key="frame" x="20" y="267" width="374" height="20"/>
270 + <fontDescription key="fontDescription" name="PeridotPE-Regular" family="Peridot PE" pointSize="16"/>
271 + <color key="textColor" red="0.12941176469999999" green="0.12941176469999999" blue="0.12941176469999999" alpha="1" colorSpace="calibratedRGB"/>
272 + <nil key="highlightedColor"/>
273 + </label>
274 + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9Hn-O1-emD">
275 + <rect key="frame" x="20" y="302" width="374" height="0.0"/>
276 + <fontDescription key="fontDescription" name="PeridotPE-Bold" family="Peridot PE" pointSize="17"/>
277 + <color key="textColor" red="0.12941176469999999" green="0.12941176469999999" blue="0.12941176469999999" alpha="1" colorSpace="calibratedRGB"/>
278 + <nil key="highlightedColor"/>
279 + </label>
280 + <textField opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="248" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="50" borderStyle="roundedRect" placeholder="Cut off in m/s²" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="IP1-S1-DNr">
281 + <rect key="frame" x="20" y="332" width="139" height="34"/>
282 + <color key="textColor" red="0.12941176470588234" green="0.12941176470588234" blue="0.12941176470588234" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
283 + <fontDescription key="fontDescription" name="PeridotPE-Bold" family="Peridot PE" pointSize="16"/>
284 + <textInputTraits key="textInputTraits"/>
285 + </textField>
286 + <textField opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="248" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="2000" borderStyle="roundedRect" placeholder="Sample Interval in ms" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="584-5E-eSX">
287 + <rect key="frame" x="201.5" y="332" width="192.5" height="34"/>
288 + <color key="textColor" red="0.12941176469999999" green="0.12941176469999999" blue="0.12941176469999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
289 + <fontDescription key="fontDescription" name="PeridotPE-Bold" family="Peridot PE" pointSize="16"/>
290 + <textInputTraits key="textInputTraits"/>
291 + </textField>
292 + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="MvU-5a-Atz">
293 + <rect key="frame" x="170.5" y="416" width="73" height="50"/>
294 + <constraints>
295 + <constraint firstAttribute="height" constant="50" id="R5R-YR-Huo"/>
296 + </constraints>
297 + <fontDescription key="fontDescription" name="PeridotPE-SBold" family="Peridot PE" pointSize="16"/>
298 + <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
299 + <state key="normal" title="Start Trip">
300 + <color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
301 + </state>
302 + <connections>
303 + <action selector="redeemButtomAction:" destination="CDt-eI-msA" eventType="touchUpInside" id="ZgM-FV-cPH"/>
304 + <action selector="tripButtonTapped:" destination="CkE-e6-QAc" eventType="touchUpInside" id="hmd-Ue-s8Z"/>
305 + </connections>
306 + </button>
307 + </subviews>
308 + <color key="backgroundColor" systemColor="systemBackgroundColor"/>
309 + <constraints>
310 + <constraint firstItem="y6m-dK-ijX" firstAttribute="leading" secondItem="nIl-Tk-yrn" secondAttribute="trailing" id="0qh-ML-W1Q"/>
311 + <constraint firstItem="tgP-fo-JIb" firstAttribute="leading" secondItem="kWM-gy-2YQ" secondAttribute="leading" constant="20" id="1Kg-CH-xU2"/>
312 + <constraint firstAttribute="trailing" secondItem="OyC-mT-xus" secondAttribute="trailing" constant="20" id="4x6-9C-8Tv"/>
313 + <constraint firstAttribute="trailing" secondItem="CdA-Ls-g0v" secondAttribute="trailing" constant="20" id="7dL-tX-p68"/>
314 + <constraint firstItem="CdA-Ls-g0v" firstAttribute="leading" secondItem="kWM-gy-2YQ" secondAttribute="leading" constant="20" id="8NU-Oj-tNl"/>
315 + <constraint firstAttribute="trailing" secondItem="9Hn-O1-emD" secondAttribute="trailing" constant="20" id="8Ra-o7-DYO"/>
316 + <constraint firstAttribute="trailing" secondItem="584-5E-eSX" secondAttribute="trailing" constant="20" id="8xe-26-AVj"/>
317 + <constraint firstItem="584-5E-eSX" firstAttribute="width" secondItem="IP1-S1-DNr" secondAttribute="width" multiplier="1.38489" id="A6e-PC-oAg"/>
318 + <constraint firstAttribute="trailing" secondItem="tgP-fo-JIb" secondAttribute="trailing" constant="20" id="DLP-ku-HX6"/>
319 + <constraint firstItem="y6m-dK-ijX" firstAttribute="centerY" secondItem="nIl-Tk-yrn" secondAttribute="centerY" id="EZZ-E7-a22"/>
320 + <constraint firstAttribute="trailing" secondItem="y6m-dK-ijX" secondAttribute="trailing" constant="20" id="Eym-3p-grC"/>
321 + <constraint firstItem="vix-aW-Fo4" firstAttribute="leading" secondItem="kWM-gy-2YQ" secondAttribute="leading" constant="20" id="GY2-FB-IdB"/>
322 + <constraint firstItem="nIl-Tk-yrn" firstAttribute="top" secondItem="vix-aW-Fo4" secondAttribute="bottom" constant="30" id="HuK-OB-d7y"/>
323 + <constraint firstItem="IP1-S1-DNr" firstAttribute="top" secondItem="9Hn-O1-emD" secondAttribute="bottom" constant="30" id="IRY-R0-wUm"/>
324 + <constraint firstAttribute="trailing" secondItem="z8p-ZO-TCw" secondAttribute="trailing" constant="20" id="Jj5-iy-AYQ"/>
325 + <constraint firstItem="584-5E-eSX" firstAttribute="centerY" secondItem="IP1-S1-DNr" secondAttribute="centerY" id="KvU-dj-vbw"/>
326 + <constraint firstItem="vix-aW-Fo4" firstAttribute="top" secondItem="c66-2s-8OX" secondAttribute="bottom" constant="15" id="MQX-aY-rrW"/>
327 + <constraint firstItem="9Hn-O1-emD" firstAttribute="top" secondItem="CdA-Ls-g0v" secondAttribute="bottom" constant="15" id="Og6-4L-n1G"/>
328 + <constraint firstAttribute="trailing" secondItem="c66-2s-8OX" secondAttribute="trailing" constant="20" id="QNQ-LI-4NC"/>
329 + <constraint firstItem="CdA-Ls-g0v" firstAttribute="top" secondItem="z8p-ZO-TCw" secondAttribute="bottom" constant="30" id="QpO-H6-GAq"/>
330 + <constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="MvU-5a-Atz" secondAttribute="bottom" constant="50" id="R9d-KG-W0F"/>
331 + <constraint firstItem="MvU-5a-Atz" firstAttribute="centerX" secondItem="kWM-gy-2YQ" secondAttribute="centerX" id="R9y-Fy-xHC"/>
332 + <constraint firstItem="584-5E-eSX" firstAttribute="leading" secondItem="IP1-S1-DNr" secondAttribute="trailing" constant="42.5" id="SeS-ip-IOR"/>
333 + <constraint firstItem="9Hn-O1-emD" firstAttribute="leading" secondItem="kWM-gy-2YQ" secondAttribute="leading" constant="20" id="TMl-1P-t8N"/>
334 + <constraint firstItem="OyC-mT-xus" firstAttribute="leading" secondItem="kWM-gy-2YQ" secondAttribute="leading" constant="20" id="XsG-GD-bis"/>
335 + <constraint firstItem="VGj-qa-qFN" firstAttribute="leading" secondItem="kWM-gy-2YQ" secondAttribute="leading" constant="20" id="ZYK-kd-tnY"/>
336 + <constraint firstItem="c66-2s-8OX" firstAttribute="top" secondItem="tgP-fo-JIb" secondAttribute="bottom" constant="30" id="cY4-ke-q8J"/>
337 + <constraint firstItem="z8p-ZO-TCw" firstAttribute="centerY" secondItem="VGj-qa-qFN" secondAttribute="centerY" id="cgo-Xi-lD8"/>
338 + <constraint firstItem="y6m-dK-ijX" firstAttribute="width" secondItem="nIl-Tk-yrn" secondAttribute="width" id="fuR-gd-NWJ"/>
339 + <constraint firstItem="z8p-ZO-TCw" firstAttribute="width" secondItem="VGj-qa-qFN" secondAttribute="width" id="gBO-X4-9I8"/>
340 + <constraint firstItem="c66-2s-8OX" firstAttribute="leading" secondItem="kWM-gy-2YQ" secondAttribute="leading" constant="20" id="gu8-Gm-HFa"/>
341 + <constraint firstItem="tgP-fo-JIb" firstAttribute="top" secondItem="OyC-mT-xus" secondAttribute="bottom" constant="15" id="jK2-hs-0sc"/>
342 + <constraint firstItem="nIl-Tk-yrn" firstAttribute="leading" secondItem="kWM-gy-2YQ" secondAttribute="leading" constant="20" id="koC-NW-nTa"/>
343 + <constraint firstItem="MvU-5a-Atz" firstAttribute="top" secondItem="IP1-S1-DNr" secondAttribute="bottom" constant="50" id="lJ2-FW-mOz"/>
344 + <constraint firstItem="VGj-qa-qFN" firstAttribute="top" secondItem="nIl-Tk-yrn" secondAttribute="bottom" constant="15" id="niZ-yq-QFl"/>
345 + <constraint firstItem="OyC-mT-xus" firstAttribute="top" secondItem="kWM-gy-2YQ" secondAttribute="top" constant="30" id="oQJ-Ua-9Sd"/>
346 + <constraint firstAttribute="trailing" secondItem="vix-aW-Fo4" secondAttribute="trailing" constant="20" id="vKX-e9-9UQ"/>
347 + <constraint firstItem="z8p-ZO-TCw" firstAttribute="leading" secondItem="VGj-qa-qFN" secondAttribute="trailing" id="vOY-Gw-zuk"/>
348 + <constraint firstItem="IP1-S1-DNr" firstAttribute="leading" secondItem="kWM-gy-2YQ" secondAttribute="leading" constant="20" id="ySe-j9-Nnb"/>
349 + </constraints>
350 + </view>
351 + </subviews>
352 + <constraints>
353 + <constraint firstItem="kWM-gy-2YQ" firstAttribute="top" secondItem="Tp2-D9-hLR" secondAttribute="top" id="7aC-oz-4Ws"/>
354 + <constraint firstItem="kWM-gy-2YQ" firstAttribute="leading" secondItem="Tp2-D9-hLR" secondAttribute="leading" id="83P-IW-XKr"/>
355 + <constraint firstItem="kWM-gy-2YQ" firstAttribute="width" secondItem="wyK-Dv-Soq" secondAttribute="width" id="B4e-3T-X0X"/>
356 + <constraint firstItem="kWM-gy-2YQ" firstAttribute="trailing" secondItem="Tp2-D9-hLR" secondAttribute="trailing" id="aho-VS-Wx8"/>
357 + <constraint firstItem="kWM-gy-2YQ" firstAttribute="bottom" secondItem="Tp2-D9-hLR" secondAttribute="bottom" id="jzR-f9-vqQ"/>
358 + </constraints>
359 + <viewLayoutGuide key="contentLayoutGuide" id="Tp2-D9-hLR"/>
360 + <viewLayoutGuide key="frameLayoutGuide" id="wyK-Dv-Soq"/>
361 + </scrollView>
362 + </subviews>
363 + <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
364 + <constraints>
365 + <constraint firstItem="kWM-gy-2YQ" firstAttribute="height" relation="greaterThanOrEqual" secondItem="sqF-9o-yrt" secondAttribute="height" id="8Qb-iP-Kp1"/>
366 + <constraint firstAttribute="trailing" secondItem="qS7-w4-Ndd" secondAttribute="trailing" id="GrT-8n-ffy"/>
367 + <constraint firstItem="qS7-w4-Ndd" firstAttribute="leading" secondItem="sqF-9o-yrt" secondAttribute="leading" id="LT4-VB-Czf"/>
368 + <constraint firstItem="qS7-w4-Ndd" firstAttribute="top" secondItem="sqF-9o-yrt" secondAttribute="top" id="bID-hI-Z8D"/>
369 + <constraint firstAttribute="bottom" secondItem="qS7-w4-Ndd" secondAttribute="bottom" id="pk6-as-PEl"/>
370 + </constraints>
371 + </view>
372 + </subviews>
210 <viewLayoutGuide key="safeArea" id="rlo-j5-Zjf"/> 373 <viewLayoutGuide key="safeArea" id="rlo-j5-Zjf"/>
211 <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> 374 <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
375 + <constraints>
376 + <constraint firstAttribute="trailing" secondItem="sqF-9o-yrt" secondAttribute="trailing" id="D0d-SZ-XDb"/>
377 + <constraint firstAttribute="bottom" secondItem="sqF-9o-yrt" secondAttribute="bottom" id="Oo5-RW-LpY"/>
378 + <constraint firstItem="sqF-9o-yrt" firstAttribute="top" secondItem="rlo-j5-Zjf" secondAttribute="top" id="VI6-8R-32f"/>
379 + <constraint firstItem="sqF-9o-yrt" firstAttribute="leading" secondItem="VXV-92-AN4" secondAttribute="leading" id="uM4-ua-sIa"/>
380 + </constraints>
212 </view> 381 </view>
382 + <connections>
383 + <outlet property="accelerationLabel" destination="tgP-fo-JIb" id="vLl-F1-yH1"/>
384 + <outlet property="accelerationLimitTextField" destination="IP1-S1-DNr" id="b7V-Pu-Hh7"/>
385 + <outlet property="avgVelocityLabel" destination="vix-aW-Fo4" id="auk-dd-MaT"/>
386 + <outlet property="orientationCountLabel" destination="VGj-qa-qFN" id="qMs-AT-mU9"/>
387 + <outlet property="recordsSavedLabel" destination="9Hn-O1-emD" id="itE-j4-3av"/>
388 + <outlet property="sampleTimeTextField" destination="584-5E-eSX" id="Nnd-Le-yEP"/>
389 + <outlet property="touchCountLabel" destination="z8p-ZO-TCw" id="gZt-md-5em"/>
390 + <outlet property="tripButton" destination="MvU-5a-Atz" id="ZCO-gZ-11O"/>
391 + </connections>
213 </viewController> 392 </viewController>
214 <placeholder placeholderIdentifier="IBFirstResponder" id="MGA-l3-4Jz" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/> 393 <placeholder placeholderIdentifier="IBFirstResponder" id="MGA-l3-4Jz" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
215 </objects> 394 </objects>
...@@ -2353,7 +2532,7 @@ ...@@ -2353,7 +2532,7 @@
2353 <rect key="frame" x="0.0" y="947.5" width="414" height="44"/> 2532 <rect key="frame" x="0.0" y="947.5" width="414" height="44"/>
2354 <autoresizingMask key="autoresizingMask"/> 2533 <autoresizingMask key="autoresizingMask"/>
2355 <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="TeS-tP-Ilh" id="FFV-uA-HHA"> 2534 <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="TeS-tP-Ilh" id="FFV-uA-HHA">
2356 - <rect key="frame" x="0.0" y="0.0" width="414" height="44"/> 2535 + <rect key="frame" x="0.0" y="0.0" width="600" height="44"/>
2357 <autoresizingMask key="autoresizingMask"/> 2536 <autoresizingMask key="autoresizingMask"/>
2358 <subviews> 2537 <subviews>
2359 <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="AV7-t1-eK0"> 2538 <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="AV7-t1-eK0">
...@@ -2580,7 +2759,7 @@ ...@@ -2580,7 +2759,7 @@
2580 <rect key="frame" x="0.0" y="991.5" width="414" height="404"/> 2759 <rect key="frame" x="0.0" y="991.5" width="414" height="404"/>
2581 <autoresizingMask key="autoresizingMask"/> 2760 <autoresizingMask key="autoresizingMask"/>
2582 <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="fgI-zL-RPZ" id="gNB-PU-R1J"> 2761 <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="fgI-zL-RPZ" id="gNB-PU-R1J">
2583 - <rect key="frame" x="0.0" y="0.0" width="414" height="404"/> 2762 + <rect key="frame" x="0.0" y="0.0" width="600" height="404"/>
2584 <autoresizingMask key="autoresizingMask"/> 2763 <autoresizingMask key="autoresizingMask"/>
2585 <subviews> 2764 <subviews>
2586 <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="IZz-Fy-5Iv"> 2765 <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="IZz-Fy-5Iv">
......
...@@ -118,6 +118,10 @@ ...@@ -118,6 +118,10 @@
118 - (void)updateRefreshTokenMA:(NSString*)access_token :(NSString*)refresh_token; 118 - (void)updateRefreshTokenMA:(NSString*)access_token :(NSString*)refresh_token;
119 - (NSString*)getAccessTokenM; 119 - (NSString*)getAccessTokenM;
120 - (long)getNetworkStatusM; 120 - (long)getNetworkStatusM;
121 +- (void)sendAccelerationDataAsync:(NSArray*)accelerationTimestamps :(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure;
122 +- (void)getTelematicsHistoryAsync:(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure;
123 +- (void)getTripMetricsAsync:(NSNumber*)tripId :(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure;
124 +- (void)rateTripAsync:(NSNumber*)tripId :(NSNumber*)rating :(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure;
121 125
122 @end 126 @end
123 #endif /* MyApi_h */ 127 #endif /* MyApi_h */
......
...@@ -1820,6 +1820,58 @@ NSString *VERIFY_URL = @"/partners/cosmote/verify"; ...@@ -1820,6 +1820,58 @@ NSString *VERIFY_URL = @"/partners/cosmote/verify";
1820 }]; 1820 }];
1821 } 1821 }
1822 1822
1823 +- (void)sendAccelerationDataAsync:(NSArray*)accelerationTimestamps :(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure
1824 +{
1825 + [[Warply sharedService] sendAccelerationDataWithSuccessBlock:accelerationTimestamps :^(NSDictionary *response) {
1826 + if (success) {
1827 + success(response);
1828 + }
1829 + } failureBlock:^(NSError *error) {
1830 + if (failure) {
1831 + failure(error);
1832 + }
1833 + }];
1834 +}
1835 +
1836 +- (void)getTelematicsHistoryAsync:(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure
1837 +{
1838 + [[Warply sharedService] getTelematicsHistoryWithSuccessBlock:^(NSDictionary *response) {
1839 + if (success) {
1840 + success(response);
1841 + }
1842 + } failureBlock:^(NSError *error) {
1843 + if (failure) {
1844 + failure(error);
1845 + }
1846 + }];
1847 +}
1848 +
1849 +- (void)getTripMetricsAsync:(NSNumber*)tripId :(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure
1850 +{
1851 + [[Warply sharedService] getTripMetricsWithSuccessBlock:tripId :^(NSDictionary *response) {
1852 + if (success) {
1853 + success(response);
1854 + }
1855 + } failureBlock:^(NSError *error) {
1856 + if (failure) {
1857 + failure(error);
1858 + }
1859 + }];
1860 +}
1861 +
1862 +- (void)rateTripAsync:(NSNumber*)tripId :(NSNumber*)rating :(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure
1863 +{
1864 + [[Warply sharedService] rateTripWithSuccessBlock:tripId :rating :^(NSDictionary *response) {
1865 + if (success) {
1866 + success(response);
1867 + }
1868 + } failureBlock:^(NSError *error) {
1869 + if (failure) {
1870 + failure(error);
1871 + }
1872 + }];
1873 +}
1874 +
1823 - (void) sendEvent: (NSString *) eventName priority: (BOOL) priority { 1875 - (void) sendEvent: (NSString *) eventName priority: (BOOL) priority {
1824 NSString *event_Name = eventName; 1876 NSString *event_Name = eventName;
1825 NSNumber *time_submitted = [NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]]; 1877 NSNumber *time_submitted = [NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]];
......
...@@ -6,24 +6,491 @@ ...@@ -6,24 +6,491 @@
6 // 6 //
7 7
8 import UIKit 8 import UIKit
9 +import CoreLocation
10 +import CoreMotion
9 11
10 -class TelematicsViewController: UIViewController { 12 +@objc public class TelematicsViewController: UIViewController, CLLocationManagerDelegate, UITextFieldDelegate {
13 +
14 + // MARK: Constants and Properties
15 +
16 + private var mIsTripStarted = false
17 + private var mAccelerationTimestamps = [[String: Any]]()
18 + private var locationManager: CLLocationManager!
19 + private var motionManager: CMMotionManager!
20 + private var lastUpdate: TimeInterval = 0
21 + private var lastX: Double = 0.0
22 + private var lastY: Double = 0.0
23 + private var lastZ: Double = 0.0
24 + private var velocity: Double = 0.0
25 + private var mAcceleration: Double = 0.0
26 + private let ALPHA: Double = 0.8 // Filter factor
27 + private let STOP_THRESHOLD: Double = 8.0 // Stop threshold in m/s²
28 + private let RECORDS_INTERVAL: Int = 5000
29 + private var mLatitude: Double = 0.0
30 + private var mLongitude: Double = 0.0
31 + private var mSpeed: Double = 0.0
32 + private let EARTH_RADIUS: Double = 6371000.0
33 + private let LOCATION_UPDATE_INTERVAL: Double = 1000.0
34 + private var mStartTimestamp: String = ""
35 + private var mStopTimestamp: String = ""
36 + private var orientationCount: Int = 0
37 + private var touchCount: Int = 0
38 + var oldOrientationIsLandscape: Bool = true
39 + private var timerTel: DispatchSourceTimer?
40 + private var recordsSaved: Int = 0
41 +
42 + // MARK: Outlets
11 43
12 - override func viewDidLoad() { 44 + @IBOutlet private weak var tripButton: UIButton!
45 + @IBOutlet private weak var sensorDataLabel: UILabel!
46 +// @IBOutlet private weak var velocityLabel: UILabel!
47 + @IBOutlet private weak var accelerationLabel: UILabel!
48 + @IBOutlet private weak var avgVelocityLabel: UILabel!
49 + @IBOutlet private weak var recordsSavedLabel: UILabel!
50 + @IBOutlet private weak var orientationCountLabel: UILabel!
51 + @IBOutlet private weak var touchCountLabel: UILabel!
52 + @IBOutlet private weak var accelerationLimitTextField: UITextField!
53 + @IBOutlet private weak var sampleTimeTextField: UITextField!
54 +
55 + public override func viewDidLoad() {
13 super.viewDidLoad() 56 super.viewDidLoad()
14 57
15 - // Do any additional setup after loading the view. 58 + self.hidesBottomBarWhenPushed = true
59 +
60 +// self.setupToHideKeyboardOnTapOnView()
61 +
62 + setBackButton()
63 + setNavigationTitle("Telematics")
64 +
65 + locationManager = CLLocationManager()
66 + motionManager = CMMotionManager()
67 + locationManager.delegate = self
68 + accelerationLimitTextField.delegate = self
69 + sampleTimeTextField.delegate = self
70 +
71 + orientationCountLabel.text = "0"
72 + touchCountLabel.text = "0"
73 + recordsSavedLabel.text = "0"
74 +
75 + tripButton.titleLabel?.font = UIFont(name: "PeridotPE-Bold", size: 17)
76 + tripButton.setTitle("Start Trip", for: .normal)
77 + tripButton.setTitleColor(UIColor(red: 0.05, green: 0.65, blue: 0.00, alpha: 1.00), for: .normal)
78 + tripButton.layer.cornerRadius = 15.0
79 + tripButton.frame = CGRect(x: 0.0, y: 0.0, width: tripButton.intrinsicContentSize.width, height: 50)
80 + tripButton.contentEdgeInsets = UIEdgeInsets(top: 0, left: 25, bottom: 0, right: 25)
81 + tripButton.backgroundColor = .clear
82 + tripButton.layer.borderWidth = 2
83 + tripButton.layer.borderColor = UIColor(red: 0.05, green: 0.65, blue: 0.00, alpha: 1.00).cgColor
84 +
85 + setupOrientationChangeDetection()
86 +
87 + let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.didTapView(sender:)))
88 +// tapGesture.cancelsTouchesInView = false
89 + self.view.addGestureRecognizer(tapGesture)
90 + }
91 +
92 + public override func viewWillAppear(_ animated: Bool) {
93 + super.viewWillAppear(animated)
94 +
95 + swiftApi().logTrackersEvent("screen", "TelematicsScreen")
96 +
97 + self.navigationController?.hideHairline()
98 + }
99 +
100 + public override func viewWillDisappear(_ animated: Bool) {
101 + super.viewWillDisappear(animated)
102 +
103 + if (self.mIsTripStarted == true) {
104 + self.stopTrip()
105 + }
106 + }
107 +
108 + deinit {
109 + NotificationCenter.default.removeObserver(self, name: UIDevice.orientationDidChangeNotification, object: nil)
110 + }
111 +
112 + // MARK: Actions
113 +
114 + @IBAction private func tripButtonTapped(_ sender: UIButton) {
115 + if (mIsTripStarted == true) {
116 + // Stop trip
117 + stopTrip()
118 +
119 + } else {
120 + // Start trip
121 + if let limitText = accelerationLimitTextField.text, limitText.isEmpty {
122 + // Handle empty limit field
123 + return
124 + }
125 +
126 + // Disable UI elements
127 + accelerationLimitTextField.isEnabled = false
128 + sampleTimeTextField.isEnabled = false
129 +
130 + // Start location and sensor updates
131 + requestLocationUpdates()
132 +// registerSensor()
133 +
134 + mIsTripStarted = true
135 + orientationCountLabel.text = "0"
136 + touchCountLabel.text = "0"
137 + tripButton.setTitle("Stop Trip", for: .normal)
138 + mStartTimestamp = String(Int(Date().timeIntervalSince1970 * 1000)) // time in milliseconds since January 1, 1970
139 + initializeOrientation()
140 + startTimer()
141 + }
142 + }
143 +
144 +
145 + private func stopTrip() {
146 + mIsTripStarted = false
147 + stopTimer()
148 + unregisterSensor()
149 + stopLocationUpdates()
150 + tripButton.setTitle("Start Trip", for: .normal)
151 +
152 + mStopTimestamp = String(Int(Date().timeIntervalSince1970 * 1000)) // time in milliseconds since January 1, 1970
153 + initViews()
154 +
155 + // Disable UI elements
156 + accelerationLimitTextField.isEnabled = true
157 + sampleTimeTextField.isEnabled = true
158 +
159 + saveAccelerationDataToFile()
160 +
161 + orientationCount = 0
162 + touchCount = 0
163 + }
164 +
165 + private func saveAccelerationDataToFile() {
166 + var jsonArray = [[String: Any]]()
167 + for var jsonObject in mAccelerationTimestamps {
168 + if let parent = jsonObject.keys.first, var jobj = jsonObject[parent] as? [String: Any] {
169 + jobj["stop_time"] = mStopTimestamp
170 + jsonObject[parent] = jobj
171 + }
172 + jsonArray.append(jsonObject)
173 + }
174 +
175 + mAccelerationTimestamps = jsonArray
176 +
177 + // print("=== mAccelerationTimestamps: ",mAccelerationTimestamps)
178 +
179 + sendAccelerationDataToServer(jsonArray)
180 + }
181 +
182 + func sendAccelerationDataToServer(_ jsonArray: [[String: Any]]) {
183 + if (mAccelerationTimestamps.isEmpty) {
184 + return
185 + }
186 +
187 + swiftApi().sendAccelerationDataAsync(accelerationTimestamps: mAccelerationTimestamps, sendAccelerationDataSuccessCallback, failureCallback: {errorCode in })
188 + }
189 +
190 + func sendAccelerationDataSuccessCallback (_ response: swiftApi.GenericResponseModel?) -> Void {
191 + if (response != nil) {
192 + DispatchQueue.main.async {
193 + if (response?.getStatus == 1) {
194 + self.recordsSaved += 1;
195 + self.recordsSavedLabel.text = String(self.recordsSaved)
196 +
197 + } else {
198 + print("=== sendAccelerationDataAsync error ===")
199 + }
200 + }
201 + } else {
202 + print("=== sendAccelerationDataAsync error ===")
203 + }
204 + }
205 +
206 + private func initializeOrientation() {
207 + if #available(iOS 13.0, *) {
208 + if let newOrientation = UIApplication.shared.windows.first?.windowScene?.interfaceOrientation {
209 + oldOrientationIsLandscape = newOrientation.isLandscape
210 + }
211 +
212 + } else {
213 + let newOrientation = UIDevice.current.orientation
214 + oldOrientationIsLandscape = newOrientation.isLandscape
215 + }
216 + }
217 +
218 + // MARK: Sensor and Location Handling
219 +
220 + private func registerSensor() {
221 + // Register sensor for accelerometer data
222 + if motionManager.isAccelerometerAvailable {
223 + motionManager.accelerometerUpdateInterval = 0.1
224 + motionManager.startAccelerometerUpdates(to: .main) { (data, error) in
225 + if let accelerationData = data {
226 + self.processAccelerometerData(accelerationData)
227 + }
228 + }
229 + }
230 + }
231 +
232 + private func unregisterSensor() {
233 + motionManager.stopAccelerometerUpdates()
16 } 234 }
17 235
236 + private func processAccelerometerData(_ accelerationData: CMAccelerometerData) {
237 + // print("=== accelerationData: ",accelerationData)
238 +
239 +// sensorDataLabel.text = "\(accelerationData.acceleration.x), \(accelerationData.acceleration.y), \(accelerationData.acceleration.z)"
240 +
241 + // timeIntervalSince1970 is the number of seconds since January, 1st, 1970, 12:00 am (mid night)
242 + let currentTime = Date().timeIntervalSince1970
243 + let timeDifference = currentTime - lastUpdate
244 + lastUpdate = currentTime
245 +
246 + let time = timeDifference
247 +
248 + // Apply low-pass filter
249 + let filteredX = ALPHA * lastX + (1 - ALPHA) * accelerationData.acceleration.x
250 + let filteredY = ALPHA * lastY + (1 - ALPHA) * accelerationData.acceleration.y
251 + let filteredZ = ALPHA * lastZ + (1 - ALPHA) * accelerationData.acceleration.z
252 +
253 + // Calculate acceleration in m/s² using filtered values
254 + let accelerationX = (filteredX - lastX) / time
255 + let accelerationY = (filteredY - lastY) / time
256 + let accelerationZ = (filteredZ - lastZ) / time
18 257
19 - /* 258 + // Calculate total acceleration
20 - // MARK: - Navigation 259 + let acceleration = sqrt(pow(accelerationX, 2) + pow(accelerationY, 2) + pow(accelerationZ, 2))
260 + // TODO: CHECK mayby this is correct
261 +// accelerationLabel.text = String(format: "%.1f m/s^2", acceleration)
262 +
263 + // print("=== acceleration: ",acceleration)
21 264
22 - // In a storyboard-based application, you will often want to do a little preparation before navigation 265 + // If acceleration is below the stop threshold, assume we are in a stop
23 - override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 266 +// if acceleration < STOP_THRESHOLD {
24 - // Get the new view controller using segue.destination. 267 +// velocity = 0
25 - // Pass the selected object to the new view controller. 268 +// } else {
269 + // Update velocity
270 + velocity = acceleration * time
271 +// }
272 +
273 + // print("=== velocity: ",velocity)
274 +
275 + // Convert velocity to km/h
276 + mAcceleration = velocity // Convert to km/h
277 +// mAcceleration = velocity * 3.6 // Convert to km/h
278 +// velocityLabel.text = String(format: "%.1f m/s^2", velocity)
279 +// avgVelocityLabel.text = String(format: "%.1f km/h", velocity)
280 + accelerationLabel.text = String(format: "%.1f m/s^2", velocity)
281 + // Update last values
282 + lastX = filteredX
283 + lastY = filteredY
284 + lastZ = filteredZ
285 + }
286 +
287 + private func requestLocationUpdates() {
288 + if CLLocationManager.locationServicesEnabled() {
289 + locationManager.desiredAccuracy = kCLLocationAccuracyBest
290 +// locationManager.requestLocation()
291 +
292 + if (!locationServicesIsEnabled()) {
293 + onLocationServicesIsDisabled();
294 + }
295 + else if (authorizationStatusIsDenied(status: CLLocationManager.authorizationStatus())) {
296 + onAuthorizationStatusIsDenied();
297 + }
298 + else if (authorizationStatusNeedRequest(status: CLLocationManager.authorizationStatus())) {
299 + onAuthorizationStatusNeedRequest();
300 + }
301 + else if (authorizationStatusIsGranted(status: CLLocationManager.authorizationStatus())) {
302 + onAuthorizationStatusIsGranted();
303 + }
304 + }
26 } 305 }
27 - */
28 306
307 + private func stopLocationUpdates() {
308 + locationManager.stopUpdatingLocation()
309 + }
310 +
311 + // MARK: Helper Methods
312 +
313 + private func initViews() {
314 +// velocityLabel.text = "0.0 m/s^2"
315 + accelerationLabel.text = "0.0 m/s^2"
316 + avgVelocityLabel.text = "0.0 km/h"
317 + }
318 +
319 + private func calculateSpeed(lat1: Double, lon1: Double, lat2: Double, lon2: Double, timeDifferenceInSeconds: Double) -> Double {
320 + let distance = calculateDistance(lat1: lat1, lon1: lon1, lat2: lat2, lon2: lon2)
321 + return (distance / timeDifferenceInSeconds) * 3.6 // Convert to km/h
322 + }
323 +
324 + private func calculateDistance(lat1: Double, lon1: Double, lat2: Double, lon2: Double) -> Double {
325 + let x = (lon2 - lon1).toRadians() * cos(((lat1 + lat2) / 2).toRadians())
326 + let y = (lat2 - lat1).toRadians()
327 + return sqrt(x * x + y * y) * EARTH_RADIUS
328 + }
329 +
330 + // Orientation Observer
331 + func setupOrientationChangeDetection() {
332 + NotificationCenter.default.addObserver(self, selector: #selector(orientationDidChange), name: UIDevice.orientationDidChangeNotification, object: nil)
333 + }
334 +
335 + @objc func orientationDidChange() {
336 + if mIsTripStarted {
337 + if #available(iOS 13.0, *) {
338 + if let newOrientation = UIApplication.shared.windows.first?.windowScene?.interfaceOrientation {
339 + if ((newOrientation.isLandscape || newOrientation.isPortrait) && (newOrientation.isLandscape != oldOrientationIsLandscape)) {
340 + orientationCount += 1
341 + orientationCountLabel.text = String(orientationCount)
342 + oldOrientationIsLandscape = !oldOrientationIsLandscape
343 + }
344 + }
345 +
346 + } else {
347 + let newOrientation = UIDevice.current.orientation
348 + if ((newOrientation.isLandscape || newOrientation.isPortrait) && (newOrientation.isLandscape != oldOrientationIsLandscape)) {
349 + orientationCount += 1
350 + orientationCountLabel.text = String(orientationCount)
351 + oldOrientationIsLandscape = !oldOrientationIsLandscape
352 + }
353 + }
354 + }
355 + }
356 +
357 + // MARK: TapGestureRecognizer callback
358 + @objc func didTapView(sender: UITapGestureRecognizer) {
359 + self.view.endEditing(true);
360 +
361 + if (mIsTripStarted == true) {
362 + touchCount += 1;
363 + touchCountLabel.text = String(touchCount);
364 + }
365 + }
366 +
367 + // MARK: Timer
368 + func startTimer() {
369 + let timeInterval = Int(sampleTimeTextField.text ?? String(RECORDS_INTERVAL)) ?? RECORDS_INTERVAL
370 + let queue = DispatchQueue(label: Bundle.main.bundleIdentifier! + ".telematics.timer")
371 + timerTel = DispatchSource.makeTimerSource(queue: queue)
372 + timerTel!.schedule(deadline: .now(), repeating: .milliseconds(timeInterval))
373 + timerTel!.setEventHandler { [weak self] in
374 + // do whatever stuff you want on the background queue here here
375 +
376 + DispatchQueue.main.async {
377 + // update your model objects and/or UI here
378 +
379 + var jsonObject = [String: Any]()
380 + var jsonObjectData = [String: Any]()
381 +
382 + let timestamp = String(Int(Date().timeIntervalSince1970 * 1000))
383 +
384 + jsonObjectData["acceleration"] = self?.mAcceleration
385 + jsonObjectData["speed"] = self?.mSpeed
386 + jsonObjectData["orientation_count"] = self?.orientationCount
387 + jsonObjectData["touch_count"] = self?.touchCount
388 + jsonObjectData["timestamp"] = timestamp
389 + jsonObjectData["start_time"] = self?.mStartTimestamp
390 + jsonObjectData["stop_time"] = self?.mStopTimestamp
391 + jsonObjectData["latitude"] = self?.mLatitude
392 + jsonObjectData["longitude"] = self?.mLongitude
393 + jsonObjectData["limit"] = self?.getCutOffLimit()
394 + jsonObjectData["samples"] = Int(self?.sampleTimeTextField.text ?? String(self?.RECORDS_INTERVAL ?? 5000)) ?? self?.RECORDS_INTERVAL ?? 5000
395 +
396 + jsonObject[timestamp] = jsonObjectData
397 +
398 +// let valid = JSONSerialization.isValidJSONObject(jsonObject)
399 +// print("=== valid JSON: ", valid)
400 +
401 + self?.mAccelerationTimestamps.append(jsonObject)
402 +
403 + // print("=== self?.mAccelerationTimestamps: ", self?.mAccelerationTimestamps)
404 + }
405 + }
406 + timerTel!.resume()
407 + }
408 +
409 + func stopTimer() {
410 + timerTel?.cancel()
411 + timerTel = nil
412 + }
413 +
414 + func getCutOffLimit() -> String {
415 + if let limitText = accelerationLimitTextField.text, !limitText.isEmpty, let limitValue = Double(limitText) {
416 + if limitValue > mAcceleration {
417 + return "red"
418 + } else {
419 + return "green"
420 + }
421 + }
422 +
423 + return ""
424 + }
425 +
426 + // MARK: Location Permissions
427 + func locationServicesIsEnabled() -> Bool {
428 + return (CLLocationManager.locationServicesEnabled()) ? true : false;
429 + }
430 +
431 + func authorizationStatusNeedRequest(status: CLAuthorizationStatus) -> Bool {
432 + return (status == .notDetermined) ? true : false;
433 + }
434 +
435 + func authorizationStatusIsGranted(status: CLAuthorizationStatus) -> Bool {
436 + return (status == .authorizedAlways || status == .authorizedWhenInUse) ? true : false;
437 + }
438 +
439 + func authorizationStatusIsDenied(status: CLAuthorizationStatus) -> Bool {
440 + return (status == .restricted || status == .denied) ? true : false;
441 + }
442 +
443 + func onLocationServicesIsDisabled() {
444 + locationManager.requestWhenInUseAuthorization();
445 + }
446 +
447 + func onAuthorizationStatusNeedRequest() {
448 + locationManager.requestWhenInUseAuthorization();
449 + }
450 +
451 + func onAuthorizationStatusIsGranted() {
452 + // print("=== onAuthorizationStatusIsGranted === ")
453 + locationManager.startUpdatingLocation();
454 + registerSensor()
455 + }
456 +
457 + func onAuthorizationStatusIsDenied() {
458 +
459 + }
460 +
461 + public func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
462 + // print("=== locationManager didChangeAuthorization: ",status)
463 +
464 + if (authorizationStatusIsDenied(status: status)) {
465 + onAuthorizationStatusIsDenied();
466 + }
467 + else if (authorizationStatusIsGranted(status: status)) {
468 + onAuthorizationStatusIsGranted();
469 + }
470 + }
471 +
472 + public func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
473 + if let location = locations.last {
474 + // print("=== locationManager didUpdateLocations latitude: ",location.coordinate.latitude)
475 + // print("=== locationManager didUpdateLocations longitude: ",location.coordinate.longitude)
476 +
477 + if mLatitude != 0 && mLongitude != 0 {
478 + mSpeed = calculateSpeed(lat1: mLatitude, lon1: mLongitude, lat2: location.coordinate.latitude, lon2: location.coordinate.longitude, timeDifferenceInSeconds: LOCATION_UPDATE_INTERVAL / 1000)
479 + avgVelocityLabel.text = String(format: "%.1f", floor(mSpeed)) + " km/h"
480 + }
481 +
482 + mLatitude = location.coordinate.latitude
483 + mLongitude = location.coordinate.longitude
484 + }
485 + }
486 +
487 + public func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
488 + print("=== locationManager didFailWithError: ", error)
489 + }
490 +}
491 +
492 +extension Double {
493 + func toRadians() -> Double {
494 + return self * .pi / 180.0
495 + }
29 } 496 }
......
...@@ -423,6 +423,14 @@ WL_VERSION_INTERFACE() ...@@ -423,6 +423,14 @@ WL_VERSION_INTERFACE()
423 423
424 - (void)getSingleCampaignWithSuccessBlock:(NSString *)sessionUuid :(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure; 424 - (void)getSingleCampaignWithSuccessBlock:(NSString *)sessionUuid :(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure;
425 425
426 +- (void) sendAccelerationDataWithSuccessBlock:(NSArray*)accelerationTimestamps :(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure;
427 +
428 +- (void) getTelematicsHistoryWithSuccessBlock:(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure;
429 +
430 +- (void) getTripMetricsWithSuccessBlock:(NSNumber*)tripId :(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure;
431 +
432 +- (void) rateTripWithSuccessBlock:(NSNumber*)tripId :(NSNumber*)rating :(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure;
433 +
426 /*! 434 /*!
427 @abstract Get the full page add accordint to the display_type of a campaign. 435 @abstract Get the full page add accordint to the display_type of a campaign.
428 @attributeblock successBlock This block is called when getInbox is sucessful and allOffers is empty or nil and returns an array with the available WLInboxItem items. Otherwise, the allOffers array is filtered. 436 @attributeblock successBlock This block is called when getInbox is sucessful and allOffers is empty or nil and returns an array with the available WLInboxItem items. Otherwise, the allOffers array is filtered.
......
...@@ -7574,6 +7574,271 @@ static void distanceFunc(sqlite3_context *context, int argc, sqlite3_value **arg ...@@ -7574,6 +7574,271 @@ static void distanceFunc(sqlite3_context *context, int argc, sqlite3_value **arg
7574 }]; 7574 }];
7575 } 7575 }
7576 7576
7577 +- (void) sendAccelerationDataWithSuccessBlock:(NSArray*)accelerationTimestamps :(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure
7578 +{
7579 + // NSDictionary *postDictionary = @{@"wallet": @{@"action": @"sharing_response", @"sharing_id": sharingId, @"accept": accept}};
7580 +
7581 + NSString * startTime = @"";
7582 + NSString * stopTime = @"";
7583 + int samples = 0;
7584 +
7585 + if (accelerationTimestamps.count > 0) {
7586 + NSDictionary *firstObject = accelerationTimestamps[0];
7587 +
7588 + if (firstObject) {
7589 + NSArray *allKeys = [firstObject allKeys];
7590 +
7591 + if (allKeys.count > 0) {
7592 + NSString *parent = allKeys[0];
7593 + NSDictionary *jobj = firstObject[parent];
7594 +
7595 + if (jobj) {
7596 + startTime = jobj[@"start_time"];
7597 + stopTime = jobj[@"stop_time"];
7598 + samples = [jobj[@"samples"] intValue];
7599 + }
7600 + }
7601 + }
7602 + }
7603 +
7604 + NSMutableDictionary *postDictionary = [NSMutableDictionary dictionary];
7605 + NSMutableDictionary *jsonParams = [NSMutableDictionary dictionary];
7606 + jsonParams[@"action"] = @"submit_telematics";
7607 +
7608 + NSMutableDictionary *rawDataObj = [NSMutableDictionary dictionary];
7609 + [rawDataObj setValue:@(0.0f) forKey:@"total_km"];
7610 + [rawDataObj setValue:@(0.0f) forKey:@"average_speed"];
7611 + [rawDataObj setValue:@(0.0f) forKey:@"smoothness"];
7612 + [rawDataObj setValue:@(0.0f) forKey:@"focus"];
7613 + [rawDataObj setValue:[NSDateFormatter localizedStringFromDate:[NSDate dateWithTimeIntervalSince1970:[startTime doubleValue]]
7614 + dateStyle:NSDateFormatterShortStyle
7615 + timeStyle:NSDateFormatterShortStyle] forKey:@"trip_start"];
7616 + [rawDataObj setValue:[NSDateFormatter localizedStringFromDate:[NSDate dateWithTimeIntervalSince1970:[stopTime doubleValue]]
7617 + dateStyle:NSDateFormatterShortStyle
7618 + timeStyle:NSDateFormatterShortStyle] forKey:@"trip_stop"];
7619 + [rawDataObj setValue:@(samples) forKey:@"samples"];
7620 + [rawDataObj setValue:@(samples / 1000) forKey:@"sample_rate"];
7621 + [rawDataObj setValue:accelerationTimestamps forKey:@"metadata"];
7622 +
7623 + jsonParams[@"raw_data"] = rawDataObj;
7624 +
7625 + postDictionary[@"telematics"] = jsonParams;
7626 +
7627 + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:postDictionary options:0 error:NULL];
7628 + [self sendContext8:jsonData successBlock:^(NSDictionary *contextResponse) {
7629 + if (success) {
7630 + success(contextResponse);
7631 + }
7632 + NSLog(@"**************** WARPLY Response *****************" );
7633 + NSLog(@"%@", contextResponse );
7634 + } failureBlock:^(NSError *error) {
7635 + if (failure) {
7636 + NSDictionary* dict = [NSDictionary alloc];
7637 + dict = [error userInfo];
7638 + NSString* errorCode = [dict objectForKey:@"NSLocalizedDescription"];
7639 + if ([errorCode isEqual:@"Request failed: unauthorized (401)"]) {
7640 +
7641 +// NSString* errorDomain = [error domain];
7642 +// NSError *errorToken = [NSError errorWithDomain:errorDomain code:401 userInfo:dict];
7643 +//
7644 +// if (failure) {
7645 +// failure(errorToken);
7646 +// }
7647 +
7648 + [self refreshToken:^(NSDictionary *response) {
7649 + [self sendContext8:jsonData successBlock:^(NSDictionary *contextResponse) {
7650 + if (success) {
7651 + success(contextResponse);
7652 + }
7653 + NSLog(@"**************** WARPLY Response *****************" );
7654 + NSLog(@"%@", contextResponse );
7655 + } failureBlock:^(NSError *error) {
7656 + if (failure) {
7657 + failure(error);
7658 + }
7659 + }];
7660 + } failureBlock:^(NSError *error) {
7661 + if (failure) {
7662 + // [_db executeUpdate:@"DROP TABLE requestVariables"];
7663 + failure(error);
7664 + }
7665 + NSLog(@"Error at token %@", error );
7666 + }];
7667 + } else {
7668 + NSLog(@"Error at send Acceleration Data %@", error );
7669 + failure(error);
7670 + }
7671 + }
7672 + }];
7673 +}
7674 +
7675 +- (void) getTelematicsHistoryWithSuccessBlock:(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure
7676 +{
7677 + NSDictionary *postDictionary = @{@"telematics": @{@"action": @"get_all_trip_ids"}};
7678 +
7679 + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:postDictionary options:0 error:NULL];
7680 + [self sendContext8:jsonData successBlock:^(NSDictionary *contextResponse) {
7681 + if (success) {
7682 + success(contextResponse);
7683 + }
7684 + NSLog(@"**************** WARPLY Response *****************" );
7685 + NSLog(@"%@", contextResponse );
7686 + } failureBlock:^(NSError *error) {
7687 + if (failure) {
7688 + NSDictionary* dict = [NSDictionary alloc];
7689 + dict = [error userInfo];
7690 + NSString* errorCode = [dict objectForKey:@"NSLocalizedDescription"];
7691 + if ([errorCode isEqual:@"Request failed: unauthorized (401)"]) {
7692 +
7693 +// NSString* errorDomain = [error domain];
7694 +// NSError *errorToken = [NSError errorWithDomain:errorDomain code:401 userInfo:dict];
7695 +//
7696 +// if (failure) {
7697 +// failure(errorToken);
7698 +// }
7699 +
7700 + [self refreshToken:^(NSDictionary *response) {
7701 + [self sendContext8:jsonData successBlock:^(NSDictionary *contextResponse) {
7702 + if (success) {
7703 + success(contextResponse);
7704 + }
7705 + NSLog(@"**************** WARPLY Response *****************" );
7706 + NSLog(@"%@", contextResponse );
7707 + } failureBlock:^(NSError *error) {
7708 + if (failure) {
7709 + failure(error);
7710 + }
7711 + }];
7712 + } failureBlock:^(NSError *error) {
7713 + if (failure) {
7714 + // [_db executeUpdate:@"DROP TABLE requestVariables"];
7715 + failure(error);
7716 + }
7717 + NSLog(@"Error at token %@", error );
7718 + }];
7719 + } else {
7720 + NSLog(@"Error at get Telematics History %@", error );
7721 + failure(error);
7722 + }
7723 + }
7724 + }];
7725 +}
7726 +
7727 +- (void) getTripMetricsWithSuccessBlock:(NSNumber*)tripId :(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure
7728 +{
7729 + NSMutableDictionary* data = [[NSMutableDictionary alloc] init];
7730 + [data setValue:@"get_scoring" forKey:@"action"];
7731 + [data setValue:tripId forKey:@"trip_id"];
7732 +
7733 + NSMutableDictionary* postDictionary = [[NSMutableDictionary alloc] init];
7734 + [postDictionary setValue:data forKey:@"telematics"];
7735 +
7736 + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:postDictionary options:0 error:NULL];
7737 + [self sendContext8:jsonData successBlock:^(NSDictionary *contextResponse) {
7738 + if (success) {
7739 + success(contextResponse);
7740 + }
7741 + NSLog(@"**************** WARPLY Response *****************" );
7742 + NSLog(@"%@", contextResponse );
7743 + } failureBlock:^(NSError *error) {
7744 + if (failure) {
7745 + NSDictionary* dict = [NSDictionary alloc];
7746 + dict = [error userInfo];
7747 + NSString* errorCode = [dict objectForKey:@"NSLocalizedDescription"];
7748 + if ([errorCode isEqual:@"Request failed: unauthorized (401)"]) {
7749 +
7750 +// NSString* errorDomain = [error domain];
7751 +// NSError *errorToken = [NSError errorWithDomain:errorDomain code:401 userInfo:dict];
7752 +//
7753 +// if (failure) {
7754 +// failure(errorToken);
7755 +// }
7756 +
7757 + [self refreshToken:^(NSDictionary *response) {
7758 + [self sendContext8:jsonData successBlock:^(NSDictionary *contextResponse) {
7759 + if (success) {
7760 + success(contextResponse);
7761 + }
7762 + NSLog(@"**************** WARPLY Response *****************" );
7763 + NSLog(@"%@", contextResponse );
7764 + } failureBlock:^(NSError *error) {
7765 + if (failure) {
7766 + failure(error);
7767 + }
7768 + }];
7769 + } failureBlock:^(NSError *error) {
7770 + if (failure) {
7771 + // [_db executeUpdate:@"DROP TABLE requestVariables"];
7772 + failure(error);
7773 + }
7774 + NSLog(@"Error at token %@", error );
7775 + }];
7776 + } else {
7777 + NSLog(@"Error at get Trip Metrics %@", error );
7778 + failure(error);
7779 + }
7780 + }
7781 + }];
7782 +}
7783 +
7784 +- (void) rateTripWithSuccessBlock:(NSNumber*)tripId :(NSNumber*)rating :(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure
7785 +{
7786 + NSMutableDictionary* data = [[NSMutableDictionary alloc] init];
7787 + [data setValue:@"update_rating" forKey:@"action"];
7788 + [data setValue:tripId forKey:@"trip_id"];
7789 + [data setValue:rating forKey:@"rating"];
7790 +
7791 + NSMutableDictionary* postDictionary = [[NSMutableDictionary alloc] init];
7792 + [postDictionary setValue:data forKey:@"telematics"];
7793 +
7794 + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:postDictionary options:0 error:NULL];
7795 + [self sendContext8:jsonData successBlock:^(NSDictionary *contextResponse) {
7796 + if (success) {
7797 + success(contextResponse);
7798 + }
7799 + NSLog(@"**************** WARPLY Response *****************" );
7800 + NSLog(@"%@", contextResponse );
7801 + } failureBlock:^(NSError *error) {
7802 + if (failure) {
7803 + NSDictionary* dict = [NSDictionary alloc];
7804 + dict = [error userInfo];
7805 + NSString* errorCode = [dict objectForKey:@"NSLocalizedDescription"];
7806 + if ([errorCode isEqual:@"Request failed: unauthorized (401)"]) {
7807 +
7808 +// NSString* errorDomain = [error domain];
7809 +// NSError *errorToken = [NSError errorWithDomain:errorDomain code:401 userInfo:dict];
7810 +//
7811 +// if (failure) {
7812 +// failure(errorToken);
7813 +// }
7814 +
7815 + [self refreshToken:^(NSDictionary *response) {
7816 + [self sendContext8:jsonData successBlock:^(NSDictionary *contextResponse) {
7817 + if (success) {
7818 + success(contextResponse);
7819 + }
7820 + NSLog(@"**************** WARPLY Response *****************" );
7821 + NSLog(@"%@", contextResponse );
7822 + } failureBlock:^(NSError *error) {
7823 + if (failure) {
7824 + failure(error);
7825 + }
7826 + }];
7827 + } failureBlock:^(NSError *error) {
7828 + if (failure) {
7829 + // [_db executeUpdate:@"DROP TABLE requestVariables"];
7830 + failure(error);
7831 + }
7832 + NSLog(@"Error at token %@", error );
7833 + }];
7834 + } else {
7835 + NSLog(@"Error at Rate Trip %@", error );
7836 + failure(error);
7837 + }
7838 + }
7839 + }];
7840 +}
7841 +
7577 /////////////////////////////////////////////////////////////////////////////// 7842 ///////////////////////////////////////////////////////////////////////////////
7578 - (void)networkReachabilityReporting 7843 - (void)networkReachabilityReporting
7579 { 7844 {
......
...@@ -7297,6 +7297,431 @@ public class swiftApi { ...@@ -7297,6 +7297,431 @@ public class swiftApi {
7297 let instanceOfMyApi = MyApi() 7297 let instanceOfMyApi = MyApi()
7298 return instanceOfMyApi.getNetworkStatusM() 7298 return instanceOfMyApi.getNetworkStatusM()
7299 } 7299 }
7300 +
7301 +
7302 + public func sendAccelerationDataAsync(accelerationTimestamps: [[String: Any]], _ sendAccelerationDataCallback: @escaping (_ responseData: GenericResponseModel?) -> Void, failureCallback: @escaping (_ errorCode: Int) -> Void) -> Void {
7303 +
7304 + let instanceOfMyApi = MyApi()
7305 + instanceOfMyApi.sendAccelerationDataAsync(accelerationTimestamps, requestCallback, failureBlock: requestFailureCallback)
7306 +
7307 + func requestCallback(_ responseData: [AnyHashable: Any]?) -> Void {
7308 +
7309 + if let responseDataDictionary = responseData as? [String: AnyObject] {
7310 + if (responseDataDictionary["status"] as? Int == 1) {
7311 +
7312 +// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
7313 +// dynatraceEvent._eventName = "custom_success_send_acceleration_data"
7314 +// dynatraceEvent._parameters = nil
7315 +// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
7316 +
7317 + if let responseDataDictionary = responseData as? [String: Any] {
7318 +
7319 + let tempResponse = GenericResponseModel(dictionary: responseDataDictionary)
7320 + sendAccelerationDataCallback(tempResponse);
7321 +
7322 + } else {
7323 + sendAccelerationDataCallback(nil)
7324 + }
7325 +
7326 + } else {
7327 +// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
7328 +// dynatraceEvent._eventName = "custom_error_send_acceleration_data"
7329 +// dynatraceEvent._parameters = nil
7330 +// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
7331 +
7332 + sendAccelerationDataCallback(nil)
7333 + }
7334 +
7335 + } else {
7336 +// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
7337 +// dynatraceEvent._eventName = "custom_error_send_acceleration_data"
7338 +// dynatraceEvent._parameters = nil
7339 +// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
7340 +
7341 + sendAccelerationDataCallback(nil)
7342 + }
7343 +
7344 + }
7345 +
7346 + func requestFailureCallback(_ error: Error?) -> Void {
7347 + print("sendAccelerationData error: ")
7348 + print(error)
7349 + print("====================")
7300 7350
7351 +// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
7352 +// dynatraceEvent._eventName = "custom_error_send_acceleration_data"
7353 +// dynatraceEvent._parameters = nil
7354 +// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
7355 +
7356 + if let error = error as? NSError {
7357 +// if (error.code == 401) {
7358 +// let sessionEvent = swiftApi.LoyaltySDKSessionExpiredEventModel()
7359 +// sessionEvent._sessionExpired = true
7360 +// SwiftEventBus.post("sdk_session_expired", sender: sessionEvent)
7361 +// }
7362 +
7363 + failureCallback(error.code)
7364 + } else {
7365 + failureCallback(-1)
7366 + }
7367 + }
7368 + }
7369 +
7370 +
7371 + public class TelematicsHistory {
7372 + private var trip_id: Int
7373 + private var created: String
7374 +
7375 + init() {
7376 + self.trip_id = -1
7377 + self.created = ""
7378 + }
7379 +
7380 + init(dictionary: [String: Any]) {
7381 + self.trip_id = dictionary["trip_id"] as? Int ?? -1
7382 + self.created = dictionary["created"] as? String ?? ""
7383 + }
7384 +
7385 + public var _trip_id: Int {
7386 + get { // getter
7387 + return self.trip_id
7388 + }
7389 + set(newValue) { //setter
7390 + self.trip_id = newValue
7391 + }
7392 + }
7393 +
7394 + public var _created: String {
7395 + get { // getter
7396 + return self.created
7397 + }
7398 + set(newValue) { //setter
7399 + self.created = newValue
7400 + }
7401 + }
7402 + }
7403 +
7404 +
7405 + public func getTelematicsHistoryAsync(_ getTelematicsHistoryCallback: @escaping (_ responseData: Array<TelematicsHistory>?) -> Void, failureCallback: @escaping (_ errorCode: Int) -> Void) -> Void {
7406 +
7407 + let instanceOfMyApi = MyApi()
7408 + instanceOfMyApi.getTelematicsHistoryAsync(requestCallback, failureBlock: requestFailureCallback)
7409 +
7410 + func requestCallback(_ responseData: [AnyHashable: Any]?) -> Void {
7411 + var telematicsHistoryArray:Array<TelematicsHistory> = []
7412 +
7413 + if let responseDataDictionary = responseData as? [String: AnyObject] {
7414 + if (responseDataDictionary["status"] as? Int == 1) {
7415 +
7416 +// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
7417 +// dynatraceEvent._eventName = "custom_success_telematics_history"
7418 +// dynatraceEvent._parameters = nil
7419 +// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
7420 +
7421 + if let responseDataDictionary = responseData as? [String: Any] {
7422 +
7423 + if let responseDataResult = responseDataDictionary["result"] as? [[String: Any]] {
7424 +
7425 + for item in responseDataResult {
7426 + let tempHistoryItem = TelematicsHistory(dictionary: item)
7427 + telematicsHistoryArray.append(tempHistoryItem)
7428 + }
7429 + getTelematicsHistoryCallback(telematicsHistoryArray)
7430 +
7431 + } else {
7432 + getTelematicsHistoryCallback(nil)
7433 + }
7434 +
7435 + } else {
7436 + getTelematicsHistoryCallback(nil)
7437 + }
7438 +
7439 + } else {
7440 +// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
7441 +// dynatraceEvent._eventName = "custom_error_telematics_history"
7442 +// dynatraceEvent._parameters = nil
7443 +// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
7444 +
7445 + getTelematicsHistoryCallback(nil)
7446 + }
7447 +
7448 + } else {
7449 +// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
7450 +// dynatraceEvent._eventName = "custom_error_telematics_history"
7451 +// dynatraceEvent._parameters = nil
7452 +// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
7453 +
7454 + getTelematicsHistoryCallback(nil)
7455 + }
7456 +
7457 + }
7458 +
7459 + func requestFailureCallback(_ error: Error?) -> Void {
7460 + print("getTelematicsHistory error: ")
7461 + print(error)
7462 + print("====================")
7463 +
7464 +// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
7465 +// dynatraceEvent._eventName = "custom_error_telematics_history"
7466 +// dynatraceEvent._parameters = nil
7467 +// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
7468 +
7469 + if let error = error as? NSError {
7470 +// if (error.code == 401) {
7471 +// let sessionEvent = swiftApi.LoyaltySDKSessionExpiredEventModel()
7472 +// sessionEvent._sessionExpired = true
7473 +// SwiftEventBus.post("sdk_session_expired", sender: sessionEvent)
7474 +// }
7475 +
7476 + failureCallback(error.code)
7477 + } else {
7478 + failureCallback(-1)
7479 + }
7480 + }
7481 + }
7482 +
7483 +
7484 + public class TripMetrics {
7485 + private var average_speed: Double
7486 + private var num_of_trips: Int
7487 + private var overall_acceleration_score: Double
7488 + private var overall_focus_score: Double
7489 + private var readiness_score: Double
7490 + private var smoothness_score: Double
7491 + private var total_km: Double
7492 +
7493 + init() {
7494 + self.average_speed = 0.0
7495 + self.num_of_trips = 0
7496 + self.overall_acceleration_score = 0.0
7497 + self.overall_focus_score = 0.0
7498 + self.readiness_score = 0.0
7499 + self.smoothness_score = 0.0
7500 + self.total_km = 0.0
7501 + }
7502 +
7503 + init(dictionary: [String: Any]) {
7504 + self.average_speed = dictionary["average_speed"] as? Double ?? 0.0
7505 + self.num_of_trips = dictionary["num_of_trips"] as? Int ?? 0
7506 + self.overall_acceleration_score = dictionary["overall_acceleration_score"] as? Double ?? 0.0
7507 + self.overall_focus_score = dictionary["overall_focus_score"] as? Double ?? 0.0
7508 + self.readiness_score = dictionary["readiness_score"] as? Double ?? 0.0
7509 + self.smoothness_score = dictionary["smoothness_score"] as? Double ?? 0.0
7510 + self.total_km = dictionary["total_km"] as? Double ?? 0.0
7511 + }
7512 +
7513 + public var _average_speed: Double {
7514 + get { // getter
7515 + return self.average_speed
7516 + }
7517 + set(newValue) { //setter
7518 + self.average_speed = newValue
7519 + }
7520 + }
7521 +
7522 + public var _num_of_trips: Int {
7523 + get { // getter
7524 + return self.num_of_trips
7525 + }
7526 + set(newValue) { //setter
7527 + self.num_of_trips = newValue
7528 + }
7529 + }
7530 +
7531 + public var _overall_acceleration_score: Double {
7532 + get { // getter
7533 + return self.overall_acceleration_score
7534 + }
7535 + set(newValue) { //setter
7536 + self.overall_acceleration_score = newValue
7537 + }
7538 + }
7539 +
7540 + public var _overall_focus_score: Double {
7541 + get { // getter
7542 + return self.overall_focus_score
7543 + }
7544 + set(newValue) { //setter
7545 + self.overall_focus_score = newValue
7546 + }
7547 + }
7548 +
7549 + public var _readiness_score: Double {
7550 + get { // getter
7551 + return self.readiness_score
7552 + }
7553 + set(newValue) { //setter
7554 + self.readiness_score = newValue
7555 + }
7556 + }
7557 +
7558 + public var _smoothness_score: Double {
7559 + get { // getter
7560 + return self.smoothness_score
7561 + }
7562 + set(newValue) { //setter
7563 + self.smoothness_score = newValue
7564 + }
7565 + }
7566 +
7567 + public var _total_km: Double {
7568 + get { // getter
7569 + return self.total_km
7570 + }
7571 + set(newValue) { //setter
7572 + self.total_km = newValue
7573 + }
7574 + }
7575 + }
7576 +
7577 +
7578 + public func getTripMetricsAsync(tripId: Int, _ getTripMetricsCallback: @escaping (_ responseData: TripMetrics?) -> Void, failureCallback: @escaping (_ errorCode: Int) -> Void) -> Void {
7579 +
7580 + let instanceOfMyApi = MyApi()
7581 + instanceOfMyApi.getTripMetricsAsync(tripId as NSNumber, requestCallback, failureBlock: requestFailureCallback)
7582 +
7583 + func requestCallback(_ responseData: [AnyHashable: Any]?) -> Void {
7584 +
7585 + if let responseDataDictionary = responseData as? [String: AnyObject] {
7586 + if (responseDataDictionary["status"] as? Int == 1) {
7587 +
7588 +// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
7589 +// dynatraceEvent._eventName = "custom_success_trip_metrics"
7590 +// dynatraceEvent._parameters = nil
7591 +// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
7592 +
7593 + if let responseDataDictionary = responseData as? [String: Any] {
7594 +
7595 + if let responseDataResult = responseDataDictionary["result"] as? [String: Any] {
7596 +
7597 + if let parent = responseDataResult.keys.first, let jobj = responseDataResult[parent] as? [String: Any] {
7598 +
7599 + let tempTripMetrics = TripMetrics(dictionary: jobj)
7600 + getTripMetricsCallback(tempTripMetrics)
7601 + } else {
7602 + getTripMetricsCallback(nil)
7603 + }
7604 +
7605 + } else {
7606 + getTripMetricsCallback(nil)
7607 + }
7608 +
7609 + } else {
7610 + getTripMetricsCallback(nil)
7611 + }
7612 +
7613 + } else {
7614 +// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
7615 +// dynatraceEvent._eventName = "custom_error_trip_metrics"
7616 +// dynatraceEvent._parameters = nil
7617 +// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
7618 +
7619 + getTripMetricsCallback(nil)
7620 + }
7621 +
7622 + } else {
7623 +// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
7624 +// dynatraceEvent._eventName = "custom_error_trip_metrics"
7625 +// dynatraceEvent._parameters = nil
7626 +// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
7627 +
7628 + getTripMetricsCallback(nil)
7629 + }
7630 +
7631 + }
7632 +
7633 + func requestFailureCallback(_ error: Error?) -> Void {
7634 + print("getTripMetrics error: ")
7635 + print(error)
7636 + print("====================")
7637 +
7638 +// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
7639 +// dynatraceEvent._eventName = "custom_error_trip_metrics"
7640 +// dynatraceEvent._parameters = nil
7641 +// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
7642 +
7643 + if let error = error as? NSError {
7644 +// if (error.code == 401) {
7645 +// let sessionEvent = swiftApi.LoyaltySDKSessionExpiredEventModel()
7646 +// sessionEvent._sessionExpired = true
7647 +// SwiftEventBus.post("sdk_session_expired", sender: sessionEvent)
7648 +// }
7649 +
7650 + failureCallback(error.code)
7651 + } else {
7652 + failureCallback(-1)
7653 + }
7654 + }
7655 + }
7656 +
7657 +
7658 + public func rateTripAsync(tripId: Int, rating: Bool, _ rateTripCallback: @escaping (_ responseData: GenericResponseModel?) -> Void, failureCallback: @escaping (_ errorCode: Int) -> Void) -> Void {
7659 +
7660 + let instanceOfMyApi = MyApi()
7661 + instanceOfMyApi.rateTripAsync(tripId as NSNumber, (rating ? 1 : 0) as NSNumber, requestCallback, failureBlock: requestFailureCallback)
7662 +
7663 + func requestCallback(_ responseData: [AnyHashable: Any]?) -> Void {
7664 +
7665 + if let responseDataDictionary = responseData as? [String: AnyObject] {
7666 + if (responseDataDictionary["status"] as? Int == 1) {
7667 +
7668 +// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
7669 +// dynatraceEvent._eventName = "custom_success_rate_trip"
7670 +// dynatraceEvent._parameters = nil
7671 +// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
7672 +
7673 + if let responseDataDictionary = responseData as? [String: Any] {
7674 +
7675 + let tempResponse = GenericResponseModel(dictionary: responseDataDictionary)
7676 + rateTripCallback(tempResponse);
7677 +
7678 + } else {
7679 + rateTripCallback(nil)
7680 + }
7681 +
7682 + } else {
7683 +// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
7684 +// dynatraceEvent._eventName = "custom_error_rate_trip"
7685 +// dynatraceEvent._parameters = nil
7686 +// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
7687 +
7688 + rateTripCallback(nil)
7689 + }
7690 +
7691 + } else {
7692 +// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
7693 +// dynatraceEvent._eventName = "custom_error_rate_trip"
7694 +// dynatraceEvent._parameters = nil
7695 +// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
7696 +
7697 + rateTripCallback(nil)
7698 + }
7699 +
7700 + }
7701 +
7702 + func requestFailureCallback(_ error: Error?) -> Void {
7703 + print("rateTrip error: ")
7704 + print(error)
7705 + print("====================")
7706 +
7707 +// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
7708 +// dynatraceEvent._eventName = "custom_error_rate_trip"
7709 +// dynatraceEvent._parameters = nil
7710 +// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
7711 +
7712 + if let error = error as? NSError {
7713 +// if (error.code == 401) {
7714 +// let sessionEvent = swiftApi.LoyaltySDKSessionExpiredEventModel()
7715 +// sessionEvent._sessionExpired = true
7716 +// SwiftEventBus.post("sdk_session_expired", sender: sessionEvent)
7717 +// }
7718 +
7719 + failureCallback(error.code)
7720 + } else {
7721 + failureCallback(-1)
7722 + }
7723 + }
7724 + }
7725 +
7301 7726
7302 } 7727 }
......