Manos Chorianopoulos

Telematics functionality with temporary ui

......@@ -7,7 +7,7 @@
<key>Pods-SwiftWarplyFramework.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
<integer>1</integer>
</dict>
</dict>
</dict>
......
......@@ -7,7 +7,7 @@
<key>SwiftWarplyFramework.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>1</integer>
<integer>0</integer>
</dict>
</dict>
</dict>
......
......@@ -207,9 +207,188 @@
<view key="view" contentMode="scaleToFill" id="VXV-92-AN4">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="sqF-9o-yrt" userLabel="Main View">
<rect key="frame" x="0.0" y="48" width="414" height="848"/>
<subviews>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" ambiguous="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qS7-w4-Ndd">
<rect key="frame" x="0.0" y="0.0" width="414" height="848"/>
<subviews>
<view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="kWM-gy-2YQ">
<rect key="frame" x="0.0" y="0.0" width="414" height="848"/>
<subviews>
<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">
<rect key="frame" x="20" y="30" width="374" height="20"/>
<fontDescription key="fontDescription" name="PeridotPE-Regular" family="Peridot PE" pointSize="16"/>
<color key="textColor" red="0.12941176469999999" green="0.12941176469999999" blue="0.12941176469999999" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<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">
<rect key="frame" x="20" y="65" width="374" height="21"/>
<fontDescription key="fontDescription" name="PeridotPE-Bold" family="Peridot PE" pointSize="17"/>
<color key="textColor" red="0.12941176469999999" green="0.12941176469999999" blue="0.12941176469999999" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<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">
<rect key="frame" x="20" y="116" width="374" height="20"/>
<fontDescription key="fontDescription" name="PeridotPE-Regular" family="Peridot PE" pointSize="16"/>
<color key="textColor" red="0.12941176469999999" green="0.12941176469999999" blue="0.12941176469999999" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<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">
<rect key="frame" x="20" y="151" width="374" height="21"/>
<fontDescription key="fontDescription" name="PeridotPE-Bold" family="Peridot PE" pointSize="17"/>
<color key="textColor" red="0.12941176469999999" green="0.12941176469999999" blue="0.12941176469999999" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<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">
<rect key="frame" x="20" y="202" width="187" height="20"/>
<fontDescription key="fontDescription" name="PeridotPE-Regular" family="Peridot PE" pointSize="16"/>
<color key="textColor" red="0.12941176469999999" green="0.12941176469999999" blue="0.12941176469999999" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<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">
<rect key="frame" x="207" y="202" width="187" height="20"/>
<fontDescription key="fontDescription" name="PeridotPE-Regular" family="Peridot PE" pointSize="16"/>
<color key="textColor" red="0.12941176469999999" green="0.12941176469999999" blue="0.12941176469999999" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<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">
<rect key="frame" x="20" y="237" width="187" height="0.0"/>
<fontDescription key="fontDescription" name="PeridotPE-Bold" family="Peridot PE" pointSize="17"/>
<color key="textColor" red="0.12941176469999999" green="0.12941176469999999" blue="0.12941176469999999" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<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">
<rect key="frame" x="207" y="237" width="187" height="0.0"/>
<fontDescription key="fontDescription" name="PeridotPE-Bold" family="Peridot PE" pointSize="17"/>
<color key="textColor" red="0.12941176469999999" green="0.12941176469999999" blue="0.12941176469999999" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<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">
<rect key="frame" x="20" y="267" width="374" height="20"/>
<fontDescription key="fontDescription" name="PeridotPE-Regular" family="Peridot PE" pointSize="16"/>
<color key="textColor" red="0.12941176469999999" green="0.12941176469999999" blue="0.12941176469999999" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<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">
<rect key="frame" x="20" y="302" width="374" height="0.0"/>
<fontDescription key="fontDescription" name="PeridotPE-Bold" family="Peridot PE" pointSize="17"/>
<color key="textColor" red="0.12941176469999999" green="0.12941176469999999" blue="0.12941176469999999" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<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">
<rect key="frame" x="20" y="332" width="139" height="34"/>
<color key="textColor" red="0.12941176470588234" green="0.12941176470588234" blue="0.12941176470588234" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" name="PeridotPE-Bold" family="Peridot PE" pointSize="16"/>
<textInputTraits key="textInputTraits"/>
</textField>
<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">
<rect key="frame" x="201.5" y="332" width="192.5" height="34"/>
<color key="textColor" red="0.12941176469999999" green="0.12941176469999999" blue="0.12941176469999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" name="PeridotPE-Bold" family="Peridot PE" pointSize="16"/>
<textInputTraits key="textInputTraits"/>
</textField>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="MvU-5a-Atz">
<rect key="frame" x="170.5" y="416" width="73" height="50"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="R5R-YR-Huo"/>
</constraints>
<fontDescription key="fontDescription" name="PeridotPE-SBold" family="Peridot PE" pointSize="16"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="Start Trip">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</state>
<connections>
<action selector="redeemButtomAction:" destination="CDt-eI-msA" eventType="touchUpInside" id="ZgM-FV-cPH"/>
<action selector="tripButtonTapped:" destination="CkE-e6-QAc" eventType="touchUpInside" id="hmd-Ue-s8Z"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="y6m-dK-ijX" firstAttribute="leading" secondItem="nIl-Tk-yrn" secondAttribute="trailing" id="0qh-ML-W1Q"/>
<constraint firstItem="tgP-fo-JIb" firstAttribute="leading" secondItem="kWM-gy-2YQ" secondAttribute="leading" constant="20" id="1Kg-CH-xU2"/>
<constraint firstAttribute="trailing" secondItem="OyC-mT-xus" secondAttribute="trailing" constant="20" id="4x6-9C-8Tv"/>
<constraint firstAttribute="trailing" secondItem="CdA-Ls-g0v" secondAttribute="trailing" constant="20" id="7dL-tX-p68"/>
<constraint firstItem="CdA-Ls-g0v" firstAttribute="leading" secondItem="kWM-gy-2YQ" secondAttribute="leading" constant="20" id="8NU-Oj-tNl"/>
<constraint firstAttribute="trailing" secondItem="9Hn-O1-emD" secondAttribute="trailing" constant="20" id="8Ra-o7-DYO"/>
<constraint firstAttribute="trailing" secondItem="584-5E-eSX" secondAttribute="trailing" constant="20" id="8xe-26-AVj"/>
<constraint firstItem="584-5E-eSX" firstAttribute="width" secondItem="IP1-S1-DNr" secondAttribute="width" multiplier="1.38489" id="A6e-PC-oAg"/>
<constraint firstAttribute="trailing" secondItem="tgP-fo-JIb" secondAttribute="trailing" constant="20" id="DLP-ku-HX6"/>
<constraint firstItem="y6m-dK-ijX" firstAttribute="centerY" secondItem="nIl-Tk-yrn" secondAttribute="centerY" id="EZZ-E7-a22"/>
<constraint firstAttribute="trailing" secondItem="y6m-dK-ijX" secondAttribute="trailing" constant="20" id="Eym-3p-grC"/>
<constraint firstItem="vix-aW-Fo4" firstAttribute="leading" secondItem="kWM-gy-2YQ" secondAttribute="leading" constant="20" id="GY2-FB-IdB"/>
<constraint firstItem="nIl-Tk-yrn" firstAttribute="top" secondItem="vix-aW-Fo4" secondAttribute="bottom" constant="30" id="HuK-OB-d7y"/>
<constraint firstItem="IP1-S1-DNr" firstAttribute="top" secondItem="9Hn-O1-emD" secondAttribute="bottom" constant="30" id="IRY-R0-wUm"/>
<constraint firstAttribute="trailing" secondItem="z8p-ZO-TCw" secondAttribute="trailing" constant="20" id="Jj5-iy-AYQ"/>
<constraint firstItem="584-5E-eSX" firstAttribute="centerY" secondItem="IP1-S1-DNr" secondAttribute="centerY" id="KvU-dj-vbw"/>
<constraint firstItem="vix-aW-Fo4" firstAttribute="top" secondItem="c66-2s-8OX" secondAttribute="bottom" constant="15" id="MQX-aY-rrW"/>
<constraint firstItem="9Hn-O1-emD" firstAttribute="top" secondItem="CdA-Ls-g0v" secondAttribute="bottom" constant="15" id="Og6-4L-n1G"/>
<constraint firstAttribute="trailing" secondItem="c66-2s-8OX" secondAttribute="trailing" constant="20" id="QNQ-LI-4NC"/>
<constraint firstItem="CdA-Ls-g0v" firstAttribute="top" secondItem="z8p-ZO-TCw" secondAttribute="bottom" constant="30" id="QpO-H6-GAq"/>
<constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="MvU-5a-Atz" secondAttribute="bottom" constant="50" id="R9d-KG-W0F"/>
<constraint firstItem="MvU-5a-Atz" firstAttribute="centerX" secondItem="kWM-gy-2YQ" secondAttribute="centerX" id="R9y-Fy-xHC"/>
<constraint firstItem="584-5E-eSX" firstAttribute="leading" secondItem="IP1-S1-DNr" secondAttribute="trailing" constant="42.5" id="SeS-ip-IOR"/>
<constraint firstItem="9Hn-O1-emD" firstAttribute="leading" secondItem="kWM-gy-2YQ" secondAttribute="leading" constant="20" id="TMl-1P-t8N"/>
<constraint firstItem="OyC-mT-xus" firstAttribute="leading" secondItem="kWM-gy-2YQ" secondAttribute="leading" constant="20" id="XsG-GD-bis"/>
<constraint firstItem="VGj-qa-qFN" firstAttribute="leading" secondItem="kWM-gy-2YQ" secondAttribute="leading" constant="20" id="ZYK-kd-tnY"/>
<constraint firstItem="c66-2s-8OX" firstAttribute="top" secondItem="tgP-fo-JIb" secondAttribute="bottom" constant="30" id="cY4-ke-q8J"/>
<constraint firstItem="z8p-ZO-TCw" firstAttribute="centerY" secondItem="VGj-qa-qFN" secondAttribute="centerY" id="cgo-Xi-lD8"/>
<constraint firstItem="y6m-dK-ijX" firstAttribute="width" secondItem="nIl-Tk-yrn" secondAttribute="width" id="fuR-gd-NWJ"/>
<constraint firstItem="z8p-ZO-TCw" firstAttribute="width" secondItem="VGj-qa-qFN" secondAttribute="width" id="gBO-X4-9I8"/>
<constraint firstItem="c66-2s-8OX" firstAttribute="leading" secondItem="kWM-gy-2YQ" secondAttribute="leading" constant="20" id="gu8-Gm-HFa"/>
<constraint firstItem="tgP-fo-JIb" firstAttribute="top" secondItem="OyC-mT-xus" secondAttribute="bottom" constant="15" id="jK2-hs-0sc"/>
<constraint firstItem="nIl-Tk-yrn" firstAttribute="leading" secondItem="kWM-gy-2YQ" secondAttribute="leading" constant="20" id="koC-NW-nTa"/>
<constraint firstItem="MvU-5a-Atz" firstAttribute="top" secondItem="IP1-S1-DNr" secondAttribute="bottom" constant="50" id="lJ2-FW-mOz"/>
<constraint firstItem="VGj-qa-qFN" firstAttribute="top" secondItem="nIl-Tk-yrn" secondAttribute="bottom" constant="15" id="niZ-yq-QFl"/>
<constraint firstItem="OyC-mT-xus" firstAttribute="top" secondItem="kWM-gy-2YQ" secondAttribute="top" constant="30" id="oQJ-Ua-9Sd"/>
<constraint firstAttribute="trailing" secondItem="vix-aW-Fo4" secondAttribute="trailing" constant="20" id="vKX-e9-9UQ"/>
<constraint firstItem="z8p-ZO-TCw" firstAttribute="leading" secondItem="VGj-qa-qFN" secondAttribute="trailing" id="vOY-Gw-zuk"/>
<constraint firstItem="IP1-S1-DNr" firstAttribute="leading" secondItem="kWM-gy-2YQ" secondAttribute="leading" constant="20" id="ySe-j9-Nnb"/>
</constraints>
</view>
</subviews>
<constraints>
<constraint firstItem="kWM-gy-2YQ" firstAttribute="top" secondItem="Tp2-D9-hLR" secondAttribute="top" id="7aC-oz-4Ws"/>
<constraint firstItem="kWM-gy-2YQ" firstAttribute="leading" secondItem="Tp2-D9-hLR" secondAttribute="leading" id="83P-IW-XKr"/>
<constraint firstItem="kWM-gy-2YQ" firstAttribute="width" secondItem="wyK-Dv-Soq" secondAttribute="width" id="B4e-3T-X0X"/>
<constraint firstItem="kWM-gy-2YQ" firstAttribute="trailing" secondItem="Tp2-D9-hLR" secondAttribute="trailing" id="aho-VS-Wx8"/>
<constraint firstItem="kWM-gy-2YQ" firstAttribute="bottom" secondItem="Tp2-D9-hLR" secondAttribute="bottom" id="jzR-f9-vqQ"/>
</constraints>
<viewLayoutGuide key="contentLayoutGuide" id="Tp2-D9-hLR"/>
<viewLayoutGuide key="frameLayoutGuide" id="wyK-Dv-Soq"/>
</scrollView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="kWM-gy-2YQ" firstAttribute="height" relation="greaterThanOrEqual" secondItem="sqF-9o-yrt" secondAttribute="height" id="8Qb-iP-Kp1"/>
<constraint firstAttribute="trailing" secondItem="qS7-w4-Ndd" secondAttribute="trailing" id="GrT-8n-ffy"/>
<constraint firstItem="qS7-w4-Ndd" firstAttribute="leading" secondItem="sqF-9o-yrt" secondAttribute="leading" id="LT4-VB-Czf"/>
<constraint firstItem="qS7-w4-Ndd" firstAttribute="top" secondItem="sqF-9o-yrt" secondAttribute="top" id="bID-hI-Z8D"/>
<constraint firstAttribute="bottom" secondItem="qS7-w4-Ndd" secondAttribute="bottom" id="pk6-as-PEl"/>
</constraints>
</view>
</subviews>
<viewLayoutGuide key="safeArea" id="rlo-j5-Zjf"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="sqF-9o-yrt" secondAttribute="trailing" id="D0d-SZ-XDb"/>
<constraint firstAttribute="bottom" secondItem="sqF-9o-yrt" secondAttribute="bottom" id="Oo5-RW-LpY"/>
<constraint firstItem="sqF-9o-yrt" firstAttribute="top" secondItem="rlo-j5-Zjf" secondAttribute="top" id="VI6-8R-32f"/>
<constraint firstItem="sqF-9o-yrt" firstAttribute="leading" secondItem="VXV-92-AN4" secondAttribute="leading" id="uM4-ua-sIa"/>
</constraints>
</view>
<connections>
<outlet property="accelerationLabel" destination="tgP-fo-JIb" id="vLl-F1-yH1"/>
<outlet property="accelerationLimitTextField" destination="IP1-S1-DNr" id="b7V-Pu-Hh7"/>
<outlet property="avgVelocityLabel" destination="vix-aW-Fo4" id="auk-dd-MaT"/>
<outlet property="orientationCountLabel" destination="VGj-qa-qFN" id="qMs-AT-mU9"/>
<outlet property="recordsSavedLabel" destination="9Hn-O1-emD" id="itE-j4-3av"/>
<outlet property="sampleTimeTextField" destination="584-5E-eSX" id="Nnd-Le-yEP"/>
<outlet property="touchCountLabel" destination="z8p-ZO-TCw" id="gZt-md-5em"/>
<outlet property="tripButton" destination="MvU-5a-Atz" id="ZCO-gZ-11O"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="MGA-l3-4Jz" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
......@@ -2353,7 +2532,7 @@
<rect key="frame" x="0.0" y="947.5" width="414" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="TeS-tP-Ilh" id="FFV-uA-HHA">
<rect key="frame" x="0.0" y="0.0" width="414" height="44"/>
<rect key="frame" x="0.0" y="0.0" width="600" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="AV7-t1-eK0">
......@@ -2580,7 +2759,7 @@
<rect key="frame" x="0.0" y="991.5" width="414" height="404"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="fgI-zL-RPZ" id="gNB-PU-R1J">
<rect key="frame" x="0.0" y="0.0" width="414" height="404"/>
<rect key="frame" x="0.0" y="0.0" width="600" height="404"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="IZz-Fy-5Iv">
......
......@@ -118,6 +118,10 @@
- (void)updateRefreshTokenMA:(NSString*)access_token :(NSString*)refresh_token;
- (NSString*)getAccessTokenM;
- (long)getNetworkStatusM;
- (void)sendAccelerationDataAsync:(NSArray*)accelerationTimestamps :(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure;
- (void)getTelematicsHistoryAsync:(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure;
- (void)getTripMetricsAsync:(NSNumber*)tripId :(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure;
- (void)rateTripAsync:(NSNumber*)tripId :(NSNumber*)rating :(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure;
@end
#endif /* MyApi_h */
......
......@@ -1820,6 +1820,58 @@ NSString *VERIFY_URL = @"/partners/cosmote/verify";
}];
}
- (void)sendAccelerationDataAsync:(NSArray*)accelerationTimestamps :(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure
{
[[Warply sharedService] sendAccelerationDataWithSuccessBlock:accelerationTimestamps :^(NSDictionary *response) {
if (success) {
success(response);
}
} failureBlock:^(NSError *error) {
if (failure) {
failure(error);
}
}];
}
- (void)getTelematicsHistoryAsync:(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure
{
[[Warply sharedService] getTelematicsHistoryWithSuccessBlock:^(NSDictionary *response) {
if (success) {
success(response);
}
} failureBlock:^(NSError *error) {
if (failure) {
failure(error);
}
}];
}
- (void)getTripMetricsAsync:(NSNumber*)tripId :(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure
{
[[Warply sharedService] getTripMetricsWithSuccessBlock:tripId :^(NSDictionary *response) {
if (success) {
success(response);
}
} failureBlock:^(NSError *error) {
if (failure) {
failure(error);
}
}];
}
- (void)rateTripAsync:(NSNumber*)tripId :(NSNumber*)rating :(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure
{
[[Warply sharedService] rateTripWithSuccessBlock:tripId :rating :^(NSDictionary *response) {
if (success) {
success(response);
}
} failureBlock:^(NSError *error) {
if (failure) {
failure(error);
}
}];
}
- (void) sendEvent: (NSString *) eventName priority: (BOOL) priority {
NSString *event_Name = eventName;
NSNumber *time_submitted = [NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]];
......
......@@ -6,24 +6,491 @@
//
import UIKit
import CoreLocation
import CoreMotion
class TelematicsViewController: UIViewController {
@objc public class TelematicsViewController: UIViewController, CLLocationManagerDelegate, UITextFieldDelegate {
override func viewDidLoad() {
// MARK: Constants and Properties
private var mIsTripStarted = false
private var mAccelerationTimestamps = [[String: Any]]()
private var locationManager: CLLocationManager!
private var motionManager: CMMotionManager!
private var lastUpdate: TimeInterval = 0
private var lastX: Double = 0.0
private var lastY: Double = 0.0
private var lastZ: Double = 0.0
private var velocity: Double = 0.0
private var mAcceleration: Double = 0.0
private let ALPHA: Double = 0.8 // Filter factor
private let STOP_THRESHOLD: Double = 8.0 // Stop threshold in m/s²
private let RECORDS_INTERVAL: Int = 5000
private var mLatitude: Double = 0.0
private var mLongitude: Double = 0.0
private var mSpeed: Double = 0.0
private let EARTH_RADIUS: Double = 6371000.0
private let LOCATION_UPDATE_INTERVAL: Double = 1000.0
private var mStartTimestamp: String = ""
private var mStopTimestamp: String = ""
private var orientationCount: Int = 0
private var touchCount: Int = 0
var oldOrientationIsLandscape: Bool = true
private var timerTel: DispatchSourceTimer?
private var recordsSaved: Int = 0
// MARK: Outlets
@IBOutlet private weak var tripButton: UIButton!
@IBOutlet private weak var sensorDataLabel: UILabel!
// @IBOutlet private weak var velocityLabel: UILabel!
@IBOutlet private weak var accelerationLabel: UILabel!
@IBOutlet private weak var avgVelocityLabel: UILabel!
@IBOutlet private weak var recordsSavedLabel: UILabel!
@IBOutlet private weak var orientationCountLabel: UILabel!
@IBOutlet private weak var touchCountLabel: UILabel!
@IBOutlet private weak var accelerationLimitTextField: UITextField!
@IBOutlet private weak var sampleTimeTextField: UITextField!
public override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.hidesBottomBarWhenPushed = true
// self.setupToHideKeyboardOnTapOnView()
setBackButton()
setNavigationTitle("Telematics")
locationManager = CLLocationManager()
motionManager = CMMotionManager()
locationManager.delegate = self
accelerationLimitTextField.delegate = self
sampleTimeTextField.delegate = self
orientationCountLabel.text = "0"
touchCountLabel.text = "0"
recordsSavedLabel.text = "0"
tripButton.titleLabel?.font = UIFont(name: "PeridotPE-Bold", size: 17)
tripButton.setTitle("Start Trip", for: .normal)
tripButton.setTitleColor(UIColor(red: 0.05, green: 0.65, blue: 0.00, alpha: 1.00), for: .normal)
tripButton.layer.cornerRadius = 15.0
tripButton.frame = CGRect(x: 0.0, y: 0.0, width: tripButton.intrinsicContentSize.width, height: 50)
tripButton.contentEdgeInsets = UIEdgeInsets(top: 0, left: 25, bottom: 0, right: 25)
tripButton.backgroundColor = .clear
tripButton.layer.borderWidth = 2
tripButton.layer.borderColor = UIColor(red: 0.05, green: 0.65, blue: 0.00, alpha: 1.00).cgColor
setupOrientationChangeDetection()
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.didTapView(sender:)))
// tapGesture.cancelsTouchesInView = false
self.view.addGestureRecognizer(tapGesture)
}
public override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
swiftApi().logTrackersEvent("screen", "TelematicsScreen")
self.navigationController?.hideHairline()
}
public override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if (self.mIsTripStarted == true) {
self.stopTrip()
}
}
deinit {
NotificationCenter.default.removeObserver(self, name: UIDevice.orientationDidChangeNotification, object: nil)
}
// MARK: Actions
@IBAction private func tripButtonTapped(_ sender: UIButton) {
if (mIsTripStarted == true) {
// Stop trip
stopTrip()
} else {
// Start trip
if let limitText = accelerationLimitTextField.text, limitText.isEmpty {
// Handle empty limit field
return
}
// Disable UI elements
accelerationLimitTextField.isEnabled = false
sampleTimeTextField.isEnabled = false
// Start location and sensor updates
requestLocationUpdates()
// registerSensor()
mIsTripStarted = true
orientationCountLabel.text = "0"
touchCountLabel.text = "0"
tripButton.setTitle("Stop Trip", for: .normal)
mStartTimestamp = String(Int(Date().timeIntervalSince1970 * 1000)) // time in milliseconds since January 1, 1970
initializeOrientation()
startTimer()
}
}
private func stopTrip() {
mIsTripStarted = false
stopTimer()
unregisterSensor()
stopLocationUpdates()
tripButton.setTitle("Start Trip", for: .normal)
mStopTimestamp = String(Int(Date().timeIntervalSince1970 * 1000)) // time in milliseconds since January 1, 1970
initViews()
// Disable UI elements
accelerationLimitTextField.isEnabled = true
sampleTimeTextField.isEnabled = true
saveAccelerationDataToFile()
orientationCount = 0
touchCount = 0
}
private func saveAccelerationDataToFile() {
var jsonArray = [[String: Any]]()
for var jsonObject in mAccelerationTimestamps {
if let parent = jsonObject.keys.first, var jobj = jsonObject[parent] as? [String: Any] {
jobj["stop_time"] = mStopTimestamp
jsonObject[parent] = jobj
}
jsonArray.append(jsonObject)
}
mAccelerationTimestamps = jsonArray
/*
// MARK: - Navigation
// print("=== mAccelerationTimestamps: ",mAccelerationTimestamps)
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
sendAccelerationDataToServer(jsonArray)
}
*/
func sendAccelerationDataToServer(_ jsonArray: [[String: Any]]) {
if (mAccelerationTimestamps.isEmpty) {
return
}
swiftApi().sendAccelerationDataAsync(accelerationTimestamps: mAccelerationTimestamps, sendAccelerationDataSuccessCallback, failureCallback: {errorCode in })
}
func sendAccelerationDataSuccessCallback (_ response: swiftApi.GenericResponseModel?) -> Void {
if (response != nil) {
DispatchQueue.main.async {
if (response?.getStatus == 1) {
self.recordsSaved += 1;
self.recordsSavedLabel.text = String(self.recordsSaved)
} else {
print("=== sendAccelerationDataAsync error ===")
}
}
} else {
print("=== sendAccelerationDataAsync error ===")
}
}
private func initializeOrientation() {
if #available(iOS 13.0, *) {
if let newOrientation = UIApplication.shared.windows.first?.windowScene?.interfaceOrientation {
oldOrientationIsLandscape = newOrientation.isLandscape
}
} else {
let newOrientation = UIDevice.current.orientation
oldOrientationIsLandscape = newOrientation.isLandscape
}
}
// MARK: Sensor and Location Handling
private func registerSensor() {
// Register sensor for accelerometer data
if motionManager.isAccelerometerAvailable {
motionManager.accelerometerUpdateInterval = 0.1
motionManager.startAccelerometerUpdates(to: .main) { (data, error) in
if let accelerationData = data {
self.processAccelerometerData(accelerationData)
}
}
}
}
private func unregisterSensor() {
motionManager.stopAccelerometerUpdates()
}
private func processAccelerometerData(_ accelerationData: CMAccelerometerData) {
// print("=== accelerationData: ",accelerationData)
// sensorDataLabel.text = "\(accelerationData.acceleration.x), \(accelerationData.acceleration.y), \(accelerationData.acceleration.z)"
// timeIntervalSince1970 is the number of seconds since January, 1st, 1970, 12:00 am (mid night)
let currentTime = Date().timeIntervalSince1970
let timeDifference = currentTime - lastUpdate
lastUpdate = currentTime
let time = timeDifference
// Apply low-pass filter
let filteredX = ALPHA * lastX + (1 - ALPHA) * accelerationData.acceleration.x
let filteredY = ALPHA * lastY + (1 - ALPHA) * accelerationData.acceleration.y
let filteredZ = ALPHA * lastZ + (1 - ALPHA) * accelerationData.acceleration.z
// Calculate acceleration in m/s² using filtered values
let accelerationX = (filteredX - lastX) / time
let accelerationY = (filteredY - lastY) / time
let accelerationZ = (filteredZ - lastZ) / time
// Calculate total acceleration
let acceleration = sqrt(pow(accelerationX, 2) + pow(accelerationY, 2) + pow(accelerationZ, 2))
// TODO: CHECK mayby this is correct
// accelerationLabel.text = String(format: "%.1f m/s^2", acceleration)
// print("=== acceleration: ",acceleration)
// If acceleration is below the stop threshold, assume we are in a stop
// if acceleration < STOP_THRESHOLD {
// velocity = 0
// } else {
// Update velocity
velocity = acceleration * time
// }
// print("=== velocity: ",velocity)
// Convert velocity to km/h
mAcceleration = velocity // Convert to km/h
// mAcceleration = velocity * 3.6 // Convert to km/h
// velocityLabel.text = String(format: "%.1f m/s^2", velocity)
// avgVelocityLabel.text = String(format: "%.1f km/h", velocity)
accelerationLabel.text = String(format: "%.1f m/s^2", velocity)
// Update last values
lastX = filteredX
lastY = filteredY
lastZ = filteredZ
}
private func requestLocationUpdates() {
if CLLocationManager.locationServicesEnabled() {
locationManager.desiredAccuracy = kCLLocationAccuracyBest
// locationManager.requestLocation()
if (!locationServicesIsEnabled()) {
onLocationServicesIsDisabled();
}
else if (authorizationStatusIsDenied(status: CLLocationManager.authorizationStatus())) {
onAuthorizationStatusIsDenied();
}
else if (authorizationStatusNeedRequest(status: CLLocationManager.authorizationStatus())) {
onAuthorizationStatusNeedRequest();
}
else if (authorizationStatusIsGranted(status: CLLocationManager.authorizationStatus())) {
onAuthorizationStatusIsGranted();
}
}
}
private func stopLocationUpdates() {
locationManager.stopUpdatingLocation()
}
// MARK: Helper Methods
private func initViews() {
// velocityLabel.text = "0.0 m/s^2"
accelerationLabel.text = "0.0 m/s^2"
avgVelocityLabel.text = "0.0 km/h"
}
private func calculateSpeed(lat1: Double, lon1: Double, lat2: Double, lon2: Double, timeDifferenceInSeconds: Double) -> Double {
let distance = calculateDistance(lat1: lat1, lon1: lon1, lat2: lat2, lon2: lon2)
return (distance / timeDifferenceInSeconds) * 3.6 // Convert to km/h
}
private func calculateDistance(lat1: Double, lon1: Double, lat2: Double, lon2: Double) -> Double {
let x = (lon2 - lon1).toRadians() * cos(((lat1 + lat2) / 2).toRadians())
let y = (lat2 - lat1).toRadians()
return sqrt(x * x + y * y) * EARTH_RADIUS
}
// Orientation Observer
func setupOrientationChangeDetection() {
NotificationCenter.default.addObserver(self, selector: #selector(orientationDidChange), name: UIDevice.orientationDidChangeNotification, object: nil)
}
@objc func orientationDidChange() {
if mIsTripStarted {
if #available(iOS 13.0, *) {
if let newOrientation = UIApplication.shared.windows.first?.windowScene?.interfaceOrientation {
if ((newOrientation.isLandscape || newOrientation.isPortrait) && (newOrientation.isLandscape != oldOrientationIsLandscape)) {
orientationCount += 1
orientationCountLabel.text = String(orientationCount)
oldOrientationIsLandscape = !oldOrientationIsLandscape
}
}
} else {
let newOrientation = UIDevice.current.orientation
if ((newOrientation.isLandscape || newOrientation.isPortrait) && (newOrientation.isLandscape != oldOrientationIsLandscape)) {
orientationCount += 1
orientationCountLabel.text = String(orientationCount)
oldOrientationIsLandscape = !oldOrientationIsLandscape
}
}
}
}
// MARK: TapGestureRecognizer callback
@objc func didTapView(sender: UITapGestureRecognizer) {
self.view.endEditing(true);
if (mIsTripStarted == true) {
touchCount += 1;
touchCountLabel.text = String(touchCount);
}
}
// MARK: Timer
func startTimer() {
let timeInterval = Int(sampleTimeTextField.text ?? String(RECORDS_INTERVAL)) ?? RECORDS_INTERVAL
let queue = DispatchQueue(label: Bundle.main.bundleIdentifier! + ".telematics.timer")
timerTel = DispatchSource.makeTimerSource(queue: queue)
timerTel!.schedule(deadline: .now(), repeating: .milliseconds(timeInterval))
timerTel!.setEventHandler { [weak self] in
// do whatever stuff you want on the background queue here here
DispatchQueue.main.async {
// update your model objects and/or UI here
var jsonObject = [String: Any]()
var jsonObjectData = [String: Any]()
let timestamp = String(Int(Date().timeIntervalSince1970 * 1000))
jsonObjectData["acceleration"] = self?.mAcceleration
jsonObjectData["speed"] = self?.mSpeed
jsonObjectData["orientation_count"] = self?.orientationCount
jsonObjectData["touch_count"] = self?.touchCount
jsonObjectData["timestamp"] = timestamp
jsonObjectData["start_time"] = self?.mStartTimestamp
jsonObjectData["stop_time"] = self?.mStopTimestamp
jsonObjectData["latitude"] = self?.mLatitude
jsonObjectData["longitude"] = self?.mLongitude
jsonObjectData["limit"] = self?.getCutOffLimit()
jsonObjectData["samples"] = Int(self?.sampleTimeTextField.text ?? String(self?.RECORDS_INTERVAL ?? 5000)) ?? self?.RECORDS_INTERVAL ?? 5000
jsonObject[timestamp] = jsonObjectData
// let valid = JSONSerialization.isValidJSONObject(jsonObject)
// print("=== valid JSON: ", valid)
self?.mAccelerationTimestamps.append(jsonObject)
// print("=== self?.mAccelerationTimestamps: ", self?.mAccelerationTimestamps)
}
}
timerTel!.resume()
}
func stopTimer() {
timerTel?.cancel()
timerTel = nil
}
func getCutOffLimit() -> String {
if let limitText = accelerationLimitTextField.text, !limitText.isEmpty, let limitValue = Double(limitText) {
if limitValue > mAcceleration {
return "red"
} else {
return "green"
}
}
return ""
}
// MARK: Location Permissions
func locationServicesIsEnabled() -> Bool {
return (CLLocationManager.locationServicesEnabled()) ? true : false;
}
func authorizationStatusNeedRequest(status: CLAuthorizationStatus) -> Bool {
return (status == .notDetermined) ? true : false;
}
func authorizationStatusIsGranted(status: CLAuthorizationStatus) -> Bool {
return (status == .authorizedAlways || status == .authorizedWhenInUse) ? true : false;
}
func authorizationStatusIsDenied(status: CLAuthorizationStatus) -> Bool {
return (status == .restricted || status == .denied) ? true : false;
}
func onLocationServicesIsDisabled() {
locationManager.requestWhenInUseAuthorization();
}
func onAuthorizationStatusNeedRequest() {
locationManager.requestWhenInUseAuthorization();
}
func onAuthorizationStatusIsGranted() {
// print("=== onAuthorizationStatusIsGranted === ")
locationManager.startUpdatingLocation();
registerSensor()
}
func onAuthorizationStatusIsDenied() {
}
public func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
// print("=== locationManager didChangeAuthorization: ",status)
if (authorizationStatusIsDenied(status: status)) {
onAuthorizationStatusIsDenied();
}
else if (authorizationStatusIsGranted(status: status)) {
onAuthorizationStatusIsGranted();
}
}
public func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.last {
// print("=== locationManager didUpdateLocations latitude: ",location.coordinate.latitude)
// print("=== locationManager didUpdateLocations longitude: ",location.coordinate.longitude)
if mLatitude != 0 && mLongitude != 0 {
mSpeed = calculateSpeed(lat1: mLatitude, lon1: mLongitude, lat2: location.coordinate.latitude, lon2: location.coordinate.longitude, timeDifferenceInSeconds: LOCATION_UPDATE_INTERVAL / 1000)
avgVelocityLabel.text = String(format: "%.1f", floor(mSpeed)) + " km/h"
}
mLatitude = location.coordinate.latitude
mLongitude = location.coordinate.longitude
}
}
public func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("=== locationManager didFailWithError: ", error)
}
}
extension Double {
func toRadians() -> Double {
return self * .pi / 180.0
}
}
......
......@@ -423,6 +423,14 @@ WL_VERSION_INTERFACE()
- (void)getSingleCampaignWithSuccessBlock:(NSString *)sessionUuid :(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure;
- (void) sendAccelerationDataWithSuccessBlock:(NSArray*)accelerationTimestamps :(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure;
- (void) getTelematicsHistoryWithSuccessBlock:(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure;
- (void) getTripMetricsWithSuccessBlock:(NSNumber*)tripId :(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure;
- (void) rateTripWithSuccessBlock:(NSNumber*)tripId :(NSNumber*)rating :(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure;
/*!
@abstract Get the full page add accordint to the display_type of a campaign.
@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
}];
}
- (void) sendAccelerationDataWithSuccessBlock:(NSArray*)accelerationTimestamps :(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure
{
// NSDictionary *postDictionary = @{@"wallet": @{@"action": @"sharing_response", @"sharing_id": sharingId, @"accept": accept}};
NSString * startTime = @"";
NSString * stopTime = @"";
int samples = 0;
if (accelerationTimestamps.count > 0) {
NSDictionary *firstObject = accelerationTimestamps[0];
if (firstObject) {
NSArray *allKeys = [firstObject allKeys];
if (allKeys.count > 0) {
NSString *parent = allKeys[0];
NSDictionary *jobj = firstObject[parent];
if (jobj) {
startTime = jobj[@"start_time"];
stopTime = jobj[@"stop_time"];
samples = [jobj[@"samples"] intValue];
}
}
}
}
NSMutableDictionary *postDictionary = [NSMutableDictionary dictionary];
NSMutableDictionary *jsonParams = [NSMutableDictionary dictionary];
jsonParams[@"action"] = @"submit_telematics";
NSMutableDictionary *rawDataObj = [NSMutableDictionary dictionary];
[rawDataObj setValue:@(0.0f) forKey:@"total_km"];
[rawDataObj setValue:@(0.0f) forKey:@"average_speed"];
[rawDataObj setValue:@(0.0f) forKey:@"smoothness"];
[rawDataObj setValue:@(0.0f) forKey:@"focus"];
[rawDataObj setValue:[NSDateFormatter localizedStringFromDate:[NSDate dateWithTimeIntervalSince1970:[startTime doubleValue]]
dateStyle:NSDateFormatterShortStyle
timeStyle:NSDateFormatterShortStyle] forKey:@"trip_start"];
[rawDataObj setValue:[NSDateFormatter localizedStringFromDate:[NSDate dateWithTimeIntervalSince1970:[stopTime doubleValue]]
dateStyle:NSDateFormatterShortStyle
timeStyle:NSDateFormatterShortStyle] forKey:@"trip_stop"];
[rawDataObj setValue:@(samples) forKey:@"samples"];
[rawDataObj setValue:@(samples / 1000) forKey:@"sample_rate"];
[rawDataObj setValue:accelerationTimestamps forKey:@"metadata"];
jsonParams[@"raw_data"] = rawDataObj;
postDictionary[@"telematics"] = jsonParams;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:postDictionary options:0 error:NULL];
[self sendContext8:jsonData successBlock:^(NSDictionary *contextResponse) {
if (success) {
success(contextResponse);
}
NSLog(@"**************** WARPLY Response *****************" );
NSLog(@"%@", contextResponse );
} failureBlock:^(NSError *error) {
if (failure) {
NSDictionary* dict = [NSDictionary alloc];
dict = [error userInfo];
NSString* errorCode = [dict objectForKey:@"NSLocalizedDescription"];
if ([errorCode isEqual:@"Request failed: unauthorized (401)"]) {
// NSString* errorDomain = [error domain];
// NSError *errorToken = [NSError errorWithDomain:errorDomain code:401 userInfo:dict];
//
// if (failure) {
// failure(errorToken);
// }
[self refreshToken:^(NSDictionary *response) {
[self sendContext8:jsonData successBlock:^(NSDictionary *contextResponse) {
if (success) {
success(contextResponse);
}
NSLog(@"**************** WARPLY Response *****************" );
NSLog(@"%@", contextResponse );
} failureBlock:^(NSError *error) {
if (failure) {
failure(error);
}
}];
} failureBlock:^(NSError *error) {
if (failure) {
// [_db executeUpdate:@"DROP TABLE requestVariables"];
failure(error);
}
NSLog(@"Error at token %@", error );
}];
} else {
NSLog(@"Error at send Acceleration Data %@", error );
failure(error);
}
}
}];
}
- (void) getTelematicsHistoryWithSuccessBlock:(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure
{
NSDictionary *postDictionary = @{@"telematics": @{@"action": @"get_all_trip_ids"}};
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:postDictionary options:0 error:NULL];
[self sendContext8:jsonData successBlock:^(NSDictionary *contextResponse) {
if (success) {
success(contextResponse);
}
NSLog(@"**************** WARPLY Response *****************" );
NSLog(@"%@", contextResponse );
} failureBlock:^(NSError *error) {
if (failure) {
NSDictionary* dict = [NSDictionary alloc];
dict = [error userInfo];
NSString* errorCode = [dict objectForKey:@"NSLocalizedDescription"];
if ([errorCode isEqual:@"Request failed: unauthorized (401)"]) {
// NSString* errorDomain = [error domain];
// NSError *errorToken = [NSError errorWithDomain:errorDomain code:401 userInfo:dict];
//
// if (failure) {
// failure(errorToken);
// }
[self refreshToken:^(NSDictionary *response) {
[self sendContext8:jsonData successBlock:^(NSDictionary *contextResponse) {
if (success) {
success(contextResponse);
}
NSLog(@"**************** WARPLY Response *****************" );
NSLog(@"%@", contextResponse );
} failureBlock:^(NSError *error) {
if (failure) {
failure(error);
}
}];
} failureBlock:^(NSError *error) {
if (failure) {
// [_db executeUpdate:@"DROP TABLE requestVariables"];
failure(error);
}
NSLog(@"Error at token %@", error );
}];
} else {
NSLog(@"Error at get Telematics History %@", error );
failure(error);
}
}
}];
}
- (void) getTripMetricsWithSuccessBlock:(NSNumber*)tripId :(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure
{
NSMutableDictionary* data = [[NSMutableDictionary alloc] init];
[data setValue:@"get_scoring" forKey:@"action"];
[data setValue:tripId forKey:@"trip_id"];
NSMutableDictionary* postDictionary = [[NSMutableDictionary alloc] init];
[postDictionary setValue:data forKey:@"telematics"];
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:postDictionary options:0 error:NULL];
[self sendContext8:jsonData successBlock:^(NSDictionary *contextResponse) {
if (success) {
success(contextResponse);
}
NSLog(@"**************** WARPLY Response *****************" );
NSLog(@"%@", contextResponse );
} failureBlock:^(NSError *error) {
if (failure) {
NSDictionary* dict = [NSDictionary alloc];
dict = [error userInfo];
NSString* errorCode = [dict objectForKey:@"NSLocalizedDescription"];
if ([errorCode isEqual:@"Request failed: unauthorized (401)"]) {
// NSString* errorDomain = [error domain];
// NSError *errorToken = [NSError errorWithDomain:errorDomain code:401 userInfo:dict];
//
// if (failure) {
// failure(errorToken);
// }
[self refreshToken:^(NSDictionary *response) {
[self sendContext8:jsonData successBlock:^(NSDictionary *contextResponse) {
if (success) {
success(contextResponse);
}
NSLog(@"**************** WARPLY Response *****************" );
NSLog(@"%@", contextResponse );
} failureBlock:^(NSError *error) {
if (failure) {
failure(error);
}
}];
} failureBlock:^(NSError *error) {
if (failure) {
// [_db executeUpdate:@"DROP TABLE requestVariables"];
failure(error);
}
NSLog(@"Error at token %@", error );
}];
} else {
NSLog(@"Error at get Trip Metrics %@", error );
failure(error);
}
}
}];
}
- (void) rateTripWithSuccessBlock:(NSNumber*)tripId :(NSNumber*)rating :(void(^)(NSDictionary *response))success failureBlock:(void(^)(NSError *error))failure
{
NSMutableDictionary* data = [[NSMutableDictionary alloc] init];
[data setValue:@"update_rating" forKey:@"action"];
[data setValue:tripId forKey:@"trip_id"];
[data setValue:rating forKey:@"rating"];
NSMutableDictionary* postDictionary = [[NSMutableDictionary alloc] init];
[postDictionary setValue:data forKey:@"telematics"];
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:postDictionary options:0 error:NULL];
[self sendContext8:jsonData successBlock:^(NSDictionary *contextResponse) {
if (success) {
success(contextResponse);
}
NSLog(@"**************** WARPLY Response *****************" );
NSLog(@"%@", contextResponse );
} failureBlock:^(NSError *error) {
if (failure) {
NSDictionary* dict = [NSDictionary alloc];
dict = [error userInfo];
NSString* errorCode = [dict objectForKey:@"NSLocalizedDescription"];
if ([errorCode isEqual:@"Request failed: unauthorized (401)"]) {
// NSString* errorDomain = [error domain];
// NSError *errorToken = [NSError errorWithDomain:errorDomain code:401 userInfo:dict];
//
// if (failure) {
// failure(errorToken);
// }
[self refreshToken:^(NSDictionary *response) {
[self sendContext8:jsonData successBlock:^(NSDictionary *contextResponse) {
if (success) {
success(contextResponse);
}
NSLog(@"**************** WARPLY Response *****************" );
NSLog(@"%@", contextResponse );
} failureBlock:^(NSError *error) {
if (failure) {
failure(error);
}
}];
} failureBlock:^(NSError *error) {
if (failure) {
// [_db executeUpdate:@"DROP TABLE requestVariables"];
failure(error);
}
NSLog(@"Error at token %@", error );
}];
} else {
NSLog(@"Error at Rate Trip %@", error );
failure(error);
}
}
}];
}
///////////////////////////////////////////////////////////////////////////////
- (void)networkReachabilityReporting
{
......
......@@ -7299,4 +7299,429 @@ public class swiftApi {
}
public func sendAccelerationDataAsync(accelerationTimestamps: [[String: Any]], _ sendAccelerationDataCallback: @escaping (_ responseData: GenericResponseModel?) -> Void, failureCallback: @escaping (_ errorCode: Int) -> Void) -> Void {
let instanceOfMyApi = MyApi()
instanceOfMyApi.sendAccelerationDataAsync(accelerationTimestamps, requestCallback, failureBlock: requestFailureCallback)
func requestCallback(_ responseData: [AnyHashable: Any]?) -> Void {
if let responseDataDictionary = responseData as? [String: AnyObject] {
if (responseDataDictionary["status"] as? Int == 1) {
// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
// dynatraceEvent._eventName = "custom_success_send_acceleration_data"
// dynatraceEvent._parameters = nil
// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
if let responseDataDictionary = responseData as? [String: Any] {
let tempResponse = GenericResponseModel(dictionary: responseDataDictionary)
sendAccelerationDataCallback(tempResponse);
} else {
sendAccelerationDataCallback(nil)
}
} else {
// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
// dynatraceEvent._eventName = "custom_error_send_acceleration_data"
// dynatraceEvent._parameters = nil
// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
sendAccelerationDataCallback(nil)
}
} else {
// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
// dynatraceEvent._eventName = "custom_error_send_acceleration_data"
// dynatraceEvent._parameters = nil
// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
sendAccelerationDataCallback(nil)
}
}
func requestFailureCallback(_ error: Error?) -> Void {
print("sendAccelerationData error: ")
print(error)
print("====================")
// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
// dynatraceEvent._eventName = "custom_error_send_acceleration_data"
// dynatraceEvent._parameters = nil
// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
if let error = error as? NSError {
// if (error.code == 401) {
// let sessionEvent = swiftApi.LoyaltySDKSessionExpiredEventModel()
// sessionEvent._sessionExpired = true
// SwiftEventBus.post("sdk_session_expired", sender: sessionEvent)
// }
failureCallback(error.code)
} else {
failureCallback(-1)
}
}
}
public class TelematicsHistory {
private var trip_id: Int
private var created: String
init() {
self.trip_id = -1
self.created = ""
}
init(dictionary: [String: Any]) {
self.trip_id = dictionary["trip_id"] as? Int ?? -1
self.created = dictionary["created"] as? String ?? ""
}
public var _trip_id: Int {
get { // getter
return self.trip_id
}
set(newValue) { //setter
self.trip_id = newValue
}
}
public var _created: String {
get { // getter
return self.created
}
set(newValue) { //setter
self.created = newValue
}
}
}
public func getTelematicsHistoryAsync(_ getTelematicsHistoryCallback: @escaping (_ responseData: Array<TelematicsHistory>?) -> Void, failureCallback: @escaping (_ errorCode: Int) -> Void) -> Void {
let instanceOfMyApi = MyApi()
instanceOfMyApi.getTelematicsHistoryAsync(requestCallback, failureBlock: requestFailureCallback)
func requestCallback(_ responseData: [AnyHashable: Any]?) -> Void {
var telematicsHistoryArray:Array<TelematicsHistory> = []
if let responseDataDictionary = responseData as? [String: AnyObject] {
if (responseDataDictionary["status"] as? Int == 1) {
// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
// dynatraceEvent._eventName = "custom_success_telematics_history"
// dynatraceEvent._parameters = nil
// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
if let responseDataDictionary = responseData as? [String: Any] {
if let responseDataResult = responseDataDictionary["result"] as? [[String: Any]] {
for item in responseDataResult {
let tempHistoryItem = TelematicsHistory(dictionary: item)
telematicsHistoryArray.append(tempHistoryItem)
}
getTelematicsHistoryCallback(telematicsHistoryArray)
} else {
getTelematicsHistoryCallback(nil)
}
} else {
getTelematicsHistoryCallback(nil)
}
} else {
// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
// dynatraceEvent._eventName = "custom_error_telematics_history"
// dynatraceEvent._parameters = nil
// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
getTelematicsHistoryCallback(nil)
}
} else {
// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
// dynatraceEvent._eventName = "custom_error_telematics_history"
// dynatraceEvent._parameters = nil
// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
getTelematicsHistoryCallback(nil)
}
}
func requestFailureCallback(_ error: Error?) -> Void {
print("getTelematicsHistory error: ")
print(error)
print("====================")
// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
// dynatraceEvent._eventName = "custom_error_telematics_history"
// dynatraceEvent._parameters = nil
// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
if let error = error as? NSError {
// if (error.code == 401) {
// let sessionEvent = swiftApi.LoyaltySDKSessionExpiredEventModel()
// sessionEvent._sessionExpired = true
// SwiftEventBus.post("sdk_session_expired", sender: sessionEvent)
// }
failureCallback(error.code)
} else {
failureCallback(-1)
}
}
}
public class TripMetrics {
private var average_speed: Double
private var num_of_trips: Int
private var overall_acceleration_score: Double
private var overall_focus_score: Double
private var readiness_score: Double
private var smoothness_score: Double
private var total_km: Double
init() {
self.average_speed = 0.0
self.num_of_trips = 0
self.overall_acceleration_score = 0.0
self.overall_focus_score = 0.0
self.readiness_score = 0.0
self.smoothness_score = 0.0
self.total_km = 0.0
}
init(dictionary: [String: Any]) {
self.average_speed = dictionary["average_speed"] as? Double ?? 0.0
self.num_of_trips = dictionary["num_of_trips"] as? Int ?? 0
self.overall_acceleration_score = dictionary["overall_acceleration_score"] as? Double ?? 0.0
self.overall_focus_score = dictionary["overall_focus_score"] as? Double ?? 0.0
self.readiness_score = dictionary["readiness_score"] as? Double ?? 0.0
self.smoothness_score = dictionary["smoothness_score"] as? Double ?? 0.0
self.total_km = dictionary["total_km"] as? Double ?? 0.0
}
public var _average_speed: Double {
get { // getter
return self.average_speed
}
set(newValue) { //setter
self.average_speed = newValue
}
}
public var _num_of_trips: Int {
get { // getter
return self.num_of_trips
}
set(newValue) { //setter
self.num_of_trips = newValue
}
}
public var _overall_acceleration_score: Double {
get { // getter
return self.overall_acceleration_score
}
set(newValue) { //setter
self.overall_acceleration_score = newValue
}
}
public var _overall_focus_score: Double {
get { // getter
return self.overall_focus_score
}
set(newValue) { //setter
self.overall_focus_score = newValue
}
}
public var _readiness_score: Double {
get { // getter
return self.readiness_score
}
set(newValue) { //setter
self.readiness_score = newValue
}
}
public var _smoothness_score: Double {
get { // getter
return self.smoothness_score
}
set(newValue) { //setter
self.smoothness_score = newValue
}
}
public var _total_km: Double {
get { // getter
return self.total_km
}
set(newValue) { //setter
self.total_km = newValue
}
}
}
public func getTripMetricsAsync(tripId: Int, _ getTripMetricsCallback: @escaping (_ responseData: TripMetrics?) -> Void, failureCallback: @escaping (_ errorCode: Int) -> Void) -> Void {
let instanceOfMyApi = MyApi()
instanceOfMyApi.getTripMetricsAsync(tripId as NSNumber, requestCallback, failureBlock: requestFailureCallback)
func requestCallback(_ responseData: [AnyHashable: Any]?) -> Void {
if let responseDataDictionary = responseData as? [String: AnyObject] {
if (responseDataDictionary["status"] as? Int == 1) {
// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
// dynatraceEvent._eventName = "custom_success_trip_metrics"
// dynatraceEvent._parameters = nil
// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
if let responseDataDictionary = responseData as? [String: Any] {
if let responseDataResult = responseDataDictionary["result"] as? [String: Any] {
if let parent = responseDataResult.keys.first, let jobj = responseDataResult[parent] as? [String: Any] {
let tempTripMetrics = TripMetrics(dictionary: jobj)
getTripMetricsCallback(tempTripMetrics)
} else {
getTripMetricsCallback(nil)
}
} else {
getTripMetricsCallback(nil)
}
} else {
getTripMetricsCallback(nil)
}
} else {
// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
// dynatraceEvent._eventName = "custom_error_trip_metrics"
// dynatraceEvent._parameters = nil
// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
getTripMetricsCallback(nil)
}
} else {
// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
// dynatraceEvent._eventName = "custom_error_trip_metrics"
// dynatraceEvent._parameters = nil
// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
getTripMetricsCallback(nil)
}
}
func requestFailureCallback(_ error: Error?) -> Void {
print("getTripMetrics error: ")
print(error)
print("====================")
// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
// dynatraceEvent._eventName = "custom_error_trip_metrics"
// dynatraceEvent._parameters = nil
// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
if let error = error as? NSError {
// if (error.code == 401) {
// let sessionEvent = swiftApi.LoyaltySDKSessionExpiredEventModel()
// sessionEvent._sessionExpired = true
// SwiftEventBus.post("sdk_session_expired", sender: sessionEvent)
// }
failureCallback(error.code)
} else {
failureCallback(-1)
}
}
}
public func rateTripAsync(tripId: Int, rating: Bool, _ rateTripCallback: @escaping (_ responseData: GenericResponseModel?) -> Void, failureCallback: @escaping (_ errorCode: Int) -> Void) -> Void {
let instanceOfMyApi = MyApi()
instanceOfMyApi.rateTripAsync(tripId as NSNumber, (rating ? 1 : 0) as NSNumber, requestCallback, failureBlock: requestFailureCallback)
func requestCallback(_ responseData: [AnyHashable: Any]?) -> Void {
if let responseDataDictionary = responseData as? [String: AnyObject] {
if (responseDataDictionary["status"] as? Int == 1) {
// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
// dynatraceEvent._eventName = "custom_success_rate_trip"
// dynatraceEvent._parameters = nil
// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
if let responseDataDictionary = responseData as? [String: Any] {
let tempResponse = GenericResponseModel(dictionary: responseDataDictionary)
rateTripCallback(tempResponse);
} else {
rateTripCallback(nil)
}
} else {
// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
// dynatraceEvent._eventName = "custom_error_rate_trip"
// dynatraceEvent._parameters = nil
// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
rateTripCallback(nil)
}
} else {
// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
// dynatraceEvent._eventName = "custom_error_rate_trip"
// dynatraceEvent._parameters = nil
// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
rateTripCallback(nil)
}
}
func requestFailureCallback(_ error: Error?) -> Void {
print("rateTrip error: ")
print(error)
print("====================")
// let dynatraceEvent = swiftApi.LoyaltySDKDynatraceEventModel()
// dynatraceEvent._eventName = "custom_error_rate_trip"
// dynatraceEvent._parameters = nil
// SwiftEventBus.post("dynatrace", sender: dynatraceEvent)
if let error = error as? NSError {
// if (error.code == 401) {
// let sessionEvent = swiftApi.LoyaltySDKSessionExpiredEventModel()
// sessionEvent._sessionExpired = true
// SwiftEventBus.post("sdk_session_expired", sender: sessionEvent)
// }
failureCallback(error.code)
} else {
failureCallback(-1)
}
}
}
}
......