Refactoring view controller

This commit is contained in:
Raimund Wege committed 2016-06-27 08:31:12 +02:00
1 parent 3cbdb762a0
commit 5b424e0bef
18 files changed
+1476 -948

No files matched your search

@@ -321,8 +321,12 @@
C852BAA21CF5E1EA0093B0C5 /* CheckInRequestManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C852BAA11CF5E1EA0093B0C5 /* CheckInRequestManager.swift */; };
C852BAAB1CF736680093B0C5 /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = C852BAAA1CF736680093B0C5 /* Preferences.swift */; };
C852BAAD1CF757950093B0C5 /* CheckInViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C852BAAC1CF757950093B0C5 /* CheckInViewController.swift */; };
C8603D4A1C528832002B2F28 /* Acknowledgements.markdown in Sources */ = {isa = PBXBuildFile; fileRef = C8603D491C528832002B2F28 /* Acknowledgements.markdown */; };
C8603D511C52892A002B2F28 /* Acknowledgements.markdown in Resources */ = {isa = PBXBuildFile; fileRef = C8603D491C528832002B2F28 /* Acknowledgements.markdown */; };
C89C5FC51D06A289002AAAD2 /* GradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C89C5FC41D06A289002AAAD2 /* GradientView.swift */; };
C89C5FCA1D06CECD002AAAD2 /* StatusTrackingTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C89C5FC91D06CECD002AAAD2 /* StatusTrackingTableViewCell.swift */; };
C89C5FCC1D06CF0C002AAAD2 /* GPSAccuracyTrackingTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C89C5FCB1D06CF0C002AAAD2 /* GPSAccuracyTrackingTableViewCell.swift */; };
C89C5FCE1D06CF26002AAAD2 /* CachedFixesTrackingTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C89C5FCD1D06CF26002AAAD2 /* CachedFixesTrackingTableViewCell.swift */; };
C89C5FD01D06CF46002AAAD2 /* ModeTrackingTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C89C5FCF1D06CF46002AAAD2 /* ModeTrackingTableViewCell.swift */; };
C8A4400B1C18153600DF70A0 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = C8A4400A1C18153600DF70A0 /* Settings.bundle */; };
C8BBAC791C52649E004CA551 /* LicenseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8BBAC781C52649E004CA551 /* LicenseViewController.swift */; };
EEB2FC8E79793611ABC022B9 /* libPods-SAPTrackerTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CDE153BDE8C83E9A084A24F1 /* libPods-SAPTrackerTests.a */; };
@@ -707,6 +711,11 @@
C852BAAA1CF736680093B0C5 /* Preferences.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = "<group>"; };
C852BAAC1CF757950093B0C5 /* CheckInViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckInViewController.swift; sourceTree = "<group>"; };
C8603D491C528832002B2F28 /* Acknowledgements.markdown */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = Acknowledgements.markdown; sourceTree = "<group>"; };
C89C5FC41D06A289002AAAD2 /* GradientView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GradientView.swift; sourceTree = "<group>"; };
C89C5FC91D06CECD002AAAD2 /* StatusTrackingTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusTrackingTableViewCell.swift; sourceTree = "<group>"; };
C89C5FCB1D06CF0C002AAAD2 /* GPSAccuracyTrackingTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GPSAccuracyTrackingTableViewCell.swift; sourceTree = "<group>"; };
C89C5FCD1D06CF26002AAAD2 /* CachedFixesTrackingTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CachedFixesTrackingTableViewCell.swift; sourceTree = "<group>"; };
C89C5FCF1D06CF46002AAAD2 /* ModeTrackingTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ModeTrackingTableViewCell.swift; sourceTree = "<group>"; };
C8A4400A1C18153600DF70A0 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = "<group>"; };
C8B31F771B68DAD400C8A809 /* Pods.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Pods.xcodeproj; path = Pods/Pods.xcodeproj; sourceTree = "<group>"; };
C8BBAC781C52649E004CA551 /* LicenseViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LicenseViewController.swift; sourceTree = "<group>"; };
@@ -765,21 +774,12 @@
7F06590119F7FE920077FF95 /* ViewController */ = {
isa = PBXGroup;
children = (
7F83F15719F154F000C53328 /* HomeViewController.swift */,
7F0658FC19F7D6700077FF95 /* ScanViewController.swift */,
C8BBAC781C52649E004CA551 /* LicenseViewController.swift */,
7F8CC2071A10D47A00C56D7F /* SettingsViewController.swift */,
7FAFA7941A126B5700D230F1 /* AboutViewController.swift */,
7F99DE3B1A126554009B3619 /* RegattaViewController.swift */,
7F950A901A35E967003C8C5C /* LeaderBoardViewController.swift */,
7F1875B21A10F1B800C25BE0 /* TrackingViewController.swift */,
7F193A901A39E54600D71773 /* GPSAccuracyView.swift */,
7F8B8D3E1A37356C00C34B88 /* TrackingPageViewController.swift */,
7F193A8E1A39ACF500D71773 /* TimerViewController.swift */,
7F8B8D401A373B0200C34B88 /* SpeedViewController.swift */,
7F8B8D421A373D4400C34B88 /* CourseViewController.swift */,
7F72C73F1A2DEA2100F48EE8 /* Resources */,
7F72C7401A2DEA3300F48EE8 /* Helpers */,
C8BBAC781C52649E004CA551 /* LicenseViewController.swift */,
7F83F15719F154F000C53328 /* HomeViewController.swift */,
7F0658FC19F7D6700077FF95 /* ScanViewController.swift */,
C89C60101D0FF036002AAAD2 /* Regatta */,
);
name = ViewController;
sourceTree = "<group>";
@@ -1069,22 +1069,6 @@
path = flags;
sourceTree = "<group>";
};
7F72C73F1A2DEA2100F48EE8 /* Resources */ = {
isa = PBXGroup;
children = (
9ECBDDAD1C9C4F0300F76AEB /* LaunchScreen.storyboard */,
7F83F15919F154F000C53328 /* Main.storyboard */,
7F4D2F531A1C8EE50038E7D1 /* Images.xcassets */,
7F87CA9D1A2CCE8B0076C617 /* OpenSans-Bold.ttf */,
7F87CA9E1A2CCE8B0076C617 /* OpenSans-Light.ttf */,
7F87CA9F1A2CCE8B0076C617 /* OpenSans-Regular.ttf */,
7F87CAA01A2CCE8B0076C617 /* OpenSans-Semibold.ttf */,
7F87DDE21A973C7400704AC4 /* eula-ios.html */,
7F87DDDD1A97339300704AC4 /* Localizable.strings */,
);
name = Resources;
sourceTree = "<group>";
};
7F72C7401A2DEA3300F48EE8 /* Helpers */ = {
isa = PBXGroup;
children = (
@@ -1121,12 +1105,18 @@
7F83F15219F154F000C53328 /* SAPTracker */ = {
isa = PBXGroup;
children = (
9ECBDDAD1C9C4F0300F76AEB /* LaunchScreen.storyboard */,
7F83F15919F154F000C53328 /* Main.storyboard */,
7F87DDDD1A97339300704AC4 /* Localizable.strings */,
7F4D2F531A1C8EE50038E7D1 /* Images.xcassets */,
C89C60131D0FF61E002AAAD2 /* Resources */,
C89C5FC31D06A269002AAAD2 /* Views */,
C852BAA91CF736440093B0C5 /* Preferences */,
7F83F15519F154F000C53328 /* AppDelegate.swift */,
7F72C7401A2DEA3300F48EE8 /* Helpers */,
7F06590119F7FE920077FF95 /* ViewController */,
7F06590219F7FEA40077FF95 /* DataController */,
7F06590019F7FE750077FF95 /* Model */,
7F14A0031A13B9A6001C1ECB /* Flags */,
7F83F15319F154F000C53328 /* Supporting Files */,
);
path = SAPTracker;
@@ -1201,6 +1191,78 @@
name = Preferences;
sourceTree = "<group>";
};
C89C5FC31D06A269002AAAD2 /* Views */ = {
isa = PBXGroup;
children = (
7F193A901A39E54600D71773 /* GPSAccuracyView.swift */,
C89C5FC41D06A289002AAAD2 /* GradientView.swift */,
);
name = Views;
sourceTree = "<group>";
};
C89C5FC61D06CE62002AAAD2 /* Tracking */ = {
isa = PBXGroup;
children = (
C89C5FC81D06CEA0002AAAD2 /* Cells */,
C89C5FC71D06CE87002AAAD2 /* Pages */,
7F1875B21A10F1B800C25BE0 /* TrackingViewController.swift */,
7F8B8D3E1A37356C00C34B88 /* TrackingPageViewController.swift */,
);
name = Tracking;
sourceTree = "<group>";
};
C89C5FC71D06CE87002AAAD2 /* Pages */ = {
isa = PBXGroup;
children = (
7F193A8E1A39ACF500D71773 /* TimerViewController.swift */,
7F8B8D401A373B0200C34B88 /* SpeedViewController.swift */,
7F8B8D421A373D4400C34B88 /* CourseViewController.swift */,
);
name = Pages;
sourceTree = "<group>";
};
C89C5FC81D06CEA0002AAAD2 /* Cells */ = {
isa = PBXGroup;
children = (
C89C5FC91D06CECD002AAAD2 /* StatusTrackingTableViewCell.swift */,
C89C5FCB1D06CF0C002AAAD2 /* GPSAccuracyTrackingTableViewCell.swift */,
C89C5FCD1D06CF26002AAAD2 /* CachedFixesTrackingTableViewCell.swift */,
C89C5FCF1D06CF46002AAAD2 /* ModeTrackingTableViewCell.swift */,
);
name = Cells;
sourceTree = "<group>";
};
C89C60101D0FF036002AAAD2 /* Regatta */ = {
isa = PBXGroup;
children = (
7F99DE3B1A126554009B3619 /* RegattaViewController.swift */,
7F950A901A35E967003C8C5C /* LeaderBoardViewController.swift */,
C89C5FC61D06CE62002AAAD2 /* Tracking */,
);
name = Regatta;
sourceTree = "<group>";
};
C89C60131D0FF61E002AAAD2 /* Resources */ = {
isa = PBXGroup;
children = (
7F87DDE21A973C7400704AC4 /* eula-ios.html */,
7F14A0031A13B9A6001C1ECB /* Flags */,
C89C60141D0FF63C002AAAD2 /* Fonts */,
);
name = Resources;
sourceTree = "<group>";
};
C89C60141D0FF63C002AAAD2 /* Fonts */ = {
isa = PBXGroup;
children = (
7F87CA9D1A2CCE8B0076C617 /* OpenSans-Bold.ttf */,
7F87CA9E1A2CCE8B0076C617 /* OpenSans-Light.ttf */,
7F87CA9F1A2CCE8B0076C617 /* OpenSans-Regular.ttf */,
7F87CAA01A2CCE8B0076C617 /* OpenSans-Semibold.ttf */,
);
name = Fonts;
sourceTree = "<group>";
};
C8B31F781B68DAD400C8A809 /* Products */ = {
isa = PBXGroup;
children = (
@@ -1757,6 +1819,7 @@
7F8B8D431A373D4400C34B88 /* CourseViewController.swift in Sources */,
7FAFA7951A126B5700D230F1 /* AboutViewController.swift in Sources */,
7F44095B19F65B5B0021BF22 /* CoreData.xcdatamodeld in Sources */,
C89C5FD01D06CF46002AAAD2 /* ModeTrackingTableViewCell.swift in Sources */,
7F1B66F91A0CDCF600904A41 /* BatteryManager.swift in Sources */,
C852BA971CF2302D0093B0C5 /* CameraController.swift in Sources */,
7F03FD3E19FA44CD00FA1327 /* APIManager.swift in Sources */,
@@ -1766,6 +1829,8 @@
7F23F0881A1A3DEF00F03F1C /* CheckInController.swift in Sources */,
7F2C605A19F160E400C32D93 /* LocationManager.swift in Sources */,
7FCDB6631A1636610075D7D9 /* Event.swift in Sources */,
C89C5FCC1D06CF0C002AAAD2 /* GPSAccuracyTrackingTableViewCell.swift in Sources */,
C89C5FCA1D06CECD002AAAD2 /* StatusTrackingTableViewCell.swift in Sources */,
7F8B8D3F1A37356C00C34B88 /* TrackingPageViewController.swift in Sources */,
7FCDB6621A1636610075D7D9 /* GPSFix.swift in Sources */,
7F99DE3C1A126554009B3619 /* RegattaViewController.swift in Sources */,
@@ -1775,10 +1840,10 @@
7F3AA7C81A1CD7D700F8861F /* SendGPSFixController.swift in Sources */,
7FCDB6641A1636610075D7D9 /* LeaderBoard.swift in Sources */,
C852BAAD1CF757950093B0C5 /* CheckInViewController.swift in Sources */,
C8603D4A1C528832002B2F28 /* Acknowledgements.markdown in Sources */,
7F8B8D411A373B0200C34B88 /* SpeedViewController.swift in Sources */,
9E95C3D61C723AB30016632B /* Constants.swift in Sources */,
7FD9D3031A1236080058FEAD /* Extensions.swift in Sources */,
C89C5FC51D06A289002AAAD2 /* GradientView.swift in Sources */,
C852BAAB1CF736680093B0C5 /* Preferences.swift in Sources */,
7F0658FD19F7D6700077FF95 /* ScanViewController.swift in Sources */,
7FCDB6651A1636610075D7D9 /* Competitor.swift in Sources */,
@@ -1786,6 +1851,7 @@
7F193A8F1A39ACF500D71773 /* TimerViewController.swift in Sources */,
7F83F15619F154F000C53328 /* AppDelegate.swift in Sources */,
7F950A911A35E967003C8C5C /* LeaderBoardViewController.swift in Sources */,
C89C5FCE1D06CF26002AAAD2 /* CachedFixesTrackingTableViewCell.swift in Sources */,
7F0658FF19F7EE910077FF95 /* CheckInData.swift in Sources */,
7F193A911A39E54600D71773 /* GPSAccuracyView.swift in Sources */,
);
@@ -11,53 +11,36 @@ import CoreData
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
struct NotificationType {
static let openUrl = "openUrl"
}
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// set up connection logging for debug builds
// Set up connection logging for debug builds
#if DEBUG
AFNetworkActivityLogger.sharedLogger().startLogging()
AFNetworkActivityLogger.sharedLogger().level = AFHTTPRequestLoggerLevel.AFLoggerLevelDebug
//AFNetworkActivityLogger.sharedLogger().startLogging()
//AFNetworkActivityLogger.sharedLogger().level = AFHTTPRequestLoggerLevel.AFLoggerLevelDebug
#endif
// initialize core data, migrate database if needed, or delete if migration needed but not possible
// Initialize core data, migrate database if needed, or delete if migration needed but not possible
DataManager.sharedManager
// start timer in case GPS fixes need to be sent
// Start timer in case GPS fixes need to be sent
SendGPSFixController.sharedManager.timer()
// set up styling
UINavigationBar.appearance().setBackgroundImage(UIImage(named: "navbar_bg"), forBarMetrics: UIBarMetrics.Default)
UINavigationBar.appearance().tintColor = UIColor.whiteColor()
UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName: UIColor.whiteColor(), NSFontAttributeName: UIFont(name: "OpenSans-Bold", size: CGFloat(17.0))!]
UIPageControl.appearance().pageIndicatorTintColor = UIColor.lightGrayColor()
UIPageControl.appearance().currentPageIndicatorTintColor = UIColor.blackColor()
UIPageControl.appearance().backgroundColor = UIColor.whiteColor()
// Setup
self.setupNavigationBarApperance()
self.setupPageControlApperance()
// FIXME: - Still need this?
// needed for missing Swift method
Appearance.setAppearance()
//Appearance.setAppearance()
return true
}
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
// Extract url string from deeplink
var urlString = url.absoluteString
let appPrefix : String = "comsapsailingtracker://"
urlString = urlString.hasPrefix(appPrefix) ? urlString.substringFromIndex(appPrefix.endIndex) : urlString
let httpPrefix : String = "http//"
urlString = urlString.hasPrefix(httpPrefix) ? "http://" + urlString.substringFromIndex(httpPrefix.endIndex) : urlString
let httpsPrefix : String = "https//"
urlString = urlString.hasPrefix(httpsPrefix) ? "https://" + urlString.substringFromIndex(httpsPrefix.endIndex) : urlString
// Save this url
Preferences.setLastCheckInURLString(urlString)
// Handled successful
Preferences.setLastCheckInURLString(self.urlStringForDeeplink(url))
return true
}
@@ -85,6 +68,38 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
DataManager.sharedManager.saveContext()
}
// MARK: - Setups
private func setupNavigationBarApperance() {
let tintColor = UIColor(hex: 0x009de0)
UINavigationBar.appearance().tintColor = tintColor
UINavigationBar.appearance().titleTextAttributes =
[NSForegroundColorAttributeName: tintColor,
NSFontAttributeName: UIFont(name: "OpenSans-Bold", size: CGFloat(17.0))!
]
}
private func setupPageControlApperance() {
UIPageControl.appearance().pageIndicatorTintColor = UIColor.lightGrayColor()
UIPageControl.appearance().currentPageIndicatorTintColor = UIColor.blackColor()
}
// MARK: - Helper
private func urlStringForDeeplink(url: NSURL) -> String {
var urlString = url.absoluteString
let appPrefix : String = "comsapsailingtracker://"
// FIXME: - Two prefixes are not allowed
// Deeplink needs another structure (if possible) because of allowed characters in URL
// https:// -> http//
urlString = urlString.hasPrefix(appPrefix) ? urlString.substringFromIndex(appPrefix.endIndex) : urlString
let httpPrefix : String = "http//"
urlString = urlString.hasPrefix(httpPrefix) ? "http://" + urlString.substringFromIndex(httpPrefix.endIndex) : urlString
let httpsPrefix : String = "https//"
urlString = urlString.hasPrefix(httpsPrefix) ? "https://" + urlString.substringFromIndex(httpsPrefix.endIndex) : urlString
return urlString
}
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,50 @@
//
// CachedFixesTrackingTableViewCell.swift
// SAPTracker
//
// Created by Raimund Wege on 07.06.16.
// Copyright © 2016 com.sap.sailing. All rights reserved.
//
import UIKit
class CachedFixesTrackingTableViewCell: UITableViewCell {
@IBOutlet weak var cachedFixesLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
self.setupCachedFixesLabel()
self.subscribeForNotifications()
}
deinit {
self.unsubscribeFromNotifications()
}
// MARK: - Setups
private func setupCachedFixesLabel() {
self.cachedFixesLabel.text = String(format: "%d", DataManager.sharedManager.countCachedFixes())
}
// MARK: - Notifications
private func subscribeForNotifications() {
NSNotificationCenter.defaultCenter().addObserver(self,
selector:#selector(newLocation),
name:LocationManager.NotificationType.newLocation,
object: nil)
}
private func unsubscribeFromNotifications() {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
func newLocation(notification: NSNotification) {
dispatch_async(dispatch_get_main_queue(), {
self.setupCachedFixesLabel()
})
}
}
@@ -10,25 +10,42 @@ import Foundation
class CourseViewController: UIViewController {
@IBOutlet weak var courseLabel: UILabel!
private let defaultCourseText = "- °"
let defaultCourseText = "- °"
@IBOutlet weak var courseLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
courseLabel.text = defaultCourseText
NSNotificationCenter.defaultCenter().addObserver(self, selector:#selector(CourseViewController.newLocation(_:)), name:LocationManager.NotificationType.newLocation, object: nil)
self.setupCourseLabel()
self.subscribeForNotifications()
}
deinit {
self.unsubscribeFromNotifications()
}
// MARK: - Setups
private func setupCourseLabel() {
self.courseLabel.text = defaultCourseText
}
// MARK: - Notifications
private func subscribeForNotifications() {
NSNotificationCenter.defaultCenter().addObserver(self,
selector:#selector(newLocation),
name:LocationManager.NotificationType.newLocation,
object: nil)
}
private func unsubscribeFromNotifications() {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
func newLocation(notification: NSNotification) {
let course = notification.userInfo!["course"] as! Double
courseLabel.text = course < 0 ? defaultCourseText : String(format: "%.0f °", course)
self.courseLabel.text = course < 0 ? defaultCourseText : String(format: "%.0f °", course)
}
}
@@ -23,30 +23,30 @@ extension UIColor {
}
}
/* Needed for setting border color in Interface Builder. */
extension CALayer {
var borderUIColor: UIColor {
get {
return UIColor(CGColor: self.borderColor!)
}
set {
self.borderColor = newValue.CGColor
}
}
}
///* Needed for setting border color in Interface Builder. */
//extension CALayer {
// var borderUIColor: UIColor {
// get {
// return UIColor(CGColor: self.borderColor!)
// }
// set {
// self.borderColor = newValue.CGColor
// }
// }
//}
/* Needed for bottom status labels. */
class PaddedLabel : UILabel {
override func drawTextInRect(rect: CGRect) {
let insets = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
return super.drawTextInRect(UIEdgeInsetsInsetRect(rect, insets))
}
}
///* Needed for bottom status labels. */
//class PaddedLabel : UILabel {
// override func drawTextInRect(rect: CGRect) {
// let insets = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
// return super.drawTextInRect(UIEdgeInsetsInsetRect(rect, insets))
// }
//}
/* Needed for programmatically setting button heights in iOS 7. */
struct ButtonHeight {
static let bigButtonPortrait = CGFloat(75.0)
static let bigButtonLandscape = CGFloat(50.0)
static let smallButtonPortrait = CGFloat(50.0)
static let smallButtonLandscape = CGFloat(50.0)
}
///* Needed for programmatically setting button heights in iOS 7. */
//struct ButtonHeight {
// static let bigButtonPortrait = CGFloat(75.0)
// static let bigButtonLandscape = CGFloat(50.0)
// static let smallButtonPortrait = CGFloat(50.0)
// static let smallButtonLandscape = CGFloat(50.0)
//}
@@ -0,0 +1,66 @@
//
// GPSAccuracyTrackingTableViewCell.swift
// SAPTracker
//
// Created by Raimund Wege on 07.06.16.
// Copyright © 2016 com.sap.sailing. All rights reserved.
//
import UIKit
class GPSAccuracyTrackingTableViewCell: UITableViewCell {
@IBOutlet weak var gpsAccuracyLabel: UILabel!
@IBOutlet weak var gpsAccuracyView: GPSAccuracyView!
override func awakeFromNib() {
super.awakeFromNib()
self.setupGPSAccuracyLabel()
self.subscribeForNotifications()
}
deinit {
self.unsubscribeFromNotifications()
}
// MARK: - Setups
private func setupGPSAccuracyLabel() {
self.gpsAccuracyLabel.text = NSLocalizedString("No GPS", comment: "")
}
private func setupGPSAccuracyLabel(horizontalAccuracy: Double!) {
self.gpsAccuracyLabel.text = "~ " + String(format: "%.0f", horizontalAccuracy) + " m"
}
// MARK: - Notifications
private func subscribeForNotifications() {
NSNotificationCenter.defaultCenter().addObserver(self,
selector:#selector(newLocation),
name:LocationManager.NotificationType.newLocation,
object: nil)
NSNotificationCenter.defaultCenter().addObserver(self,
selector:#selector(locationManagerFailed),
name:LocationManager.NotificationType.locationManagerFailed,
object: nil)
}
private func unsubscribeFromNotifications() {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
func newLocation(notification: NSNotification) {
dispatch_async(dispatch_get_main_queue(), {
let horizontalAccuracy = notification.userInfo!["horizontalAccuracy"] as! Double
self.setupGPSAccuracyLabel(horizontalAccuracy)
})
}
func locationManagerFailed(notification: NSNotification) {
dispatch_async(dispatch_get_main_queue(), {
self.setupGPSAccuracyLabel()
})
}
}
@@ -10,53 +10,62 @@ import UIKit
class GPSAccuracyView : UIView {
struct Color {
static let Green = UIColor(hex: 0x408000)
static let Red = UIColor(hex: 0xFF0000)
static let Orange = UIColor(hex: 0xFF8000)
}
let barView = UIView()
override init(frame: CGRect) {
super.init(frame: frame)
setup()
initialize()
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
setup()
initialize()
}
private func initialize() {
self.setupBarView()
self.setupBackroundColor()
self.subscribeForNotifications()
}
deinit {
self.unsubscribeFromNotifications()
}
// MARK: - Setups
private func setupBarView() {
addSubview(self.barView)
self.barView.frame = self.bounds
}
private func setupBackroundColor() {
self.backgroundColor = UIColor.grayColor()
}
// MARK: - Notifications
private func subscribeForNotifications() {
NSNotificationCenter.defaultCenter().addObserver(self,
selector:#selector(newLocation(_:)),
name:LocationManager.NotificationType.newLocation,
object: nil)
NSNotificationCenter.defaultCenter().addObserver(self,
selector:#selector(locationManagerFailed(_:)),
name:LocationManager.NotificationType.locationManagerFailed,
object: nil)
}
private func unsubscribeFromNotifications() {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
private func setup() {
backgroundColor = UIColor.grayColor()
addSubview(barView)
barView.frame = bounds
// add listeners
NSNotificationCenter.defaultCenter().addObserver(self, selector:#selector(GPSAccuracyView.newLocation(_:)), name:LocationManager.NotificationType.newLocation, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector:#selector(GPSAccuracyView.locationManagerFailed(_:)), name:LocationManager.NotificationType.locationManagerFailed, object: nil)
}
private func drawBar(horizontalAccuracy: Double) {
var height = 1.0
var color = TrackingViewController.Color.Red
if (horizontalAccuracy < 0) {
} else if (horizontalAccuracy > 48) {
height = 0.33
} else if (horizontalAccuracy > 10) {
height = 0.66
color = TrackingViewController.Color.Orange
} else {
height = 1.0
color = TrackingViewController.Color.Green
}
let frame = CGRect(x:0, y:CGFloat(1.0 - height) * bounds.height, width:bounds.width, height:CGFloat(height) * bounds.height)
barView.frame = frame
barView.backgroundColor = color
}
func newLocation(notification: NSNotification) {
let horizontalAccuracy = notification.userInfo!["horizontalAccuracy"] as! Double
drawBar(horizontalAccuracy)
@@ -66,4 +75,28 @@ class GPSAccuracyView : UIView {
drawBar(-1.0)
}
// MARK: - Draw
private func drawBar(horizontalAccuracy: Double) {
var height = 1.0
var color = Color.Red
if (horizontalAccuracy < 0) {
// ...
} else if (horizontalAccuracy > 48) {
height = 0.33
} else if (horizontalAccuracy > 10) {
height = 0.66
color = Color.Orange
} else {
height = 1.0
color = Color.Green
}
let frame = CGRect(x:0,
y:CGFloat(1.0 - height) * bounds.height,
width:bounds.width,
height:CGFloat(height) * bounds.height)
barView.frame = frame
barView.backgroundColor = color
}
}
@@ -0,0 +1,24 @@
//
// GradientView.swift
// SAPTracker
//
// Created by Raimund Wege on 07.06.16.
// Copyright © 2016 com.sap.sailing. All rights reserved.
//
import UIKit
@IBDesignable class GradientView: UIView {
@IBInspectable var firstColor: UIColor = UIColor.whiteColor()
@IBInspectable var secondColor: UIColor = UIColor.blackColor()
override class func layerClass() -> AnyClass {
return CAGradientLayer.self
}
override func layoutSubviews() {
(layer as! CAGradientLayer).colors = [firstColor.CGColor, secondColor.CGColor]
}
}
@@ -15,7 +15,7 @@ class HomeViewController: CheckInViewController, UITableViewDataSource, UITableV
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var scanCodeButton: UIButton!
@IBOutlet weak var noCodeButton: UIButton!
@IBOutlet weak var bottomLabel: PaddedLabel!
@IBOutlet weak var infoCodeLabel: UILabel!
private var fetchedResultsController: NSFetchedResultsController?
@@ -23,7 +23,7 @@ class HomeViewController: CheckInViewController, UITableViewDataSource, UITableV
super.viewDidLoad()
self.setupLanguage()
self.setupNavigationbar()
self.setupNavigationBar()
self.setupTableViewDataSource()
self.subscribeForNotifications()
@@ -59,10 +59,10 @@ class HomeViewController: CheckInViewController, UITableViewDataSource, UITableV
self.titleLabel.text = NSLocalizedString("Your Regattas", comment: "")
self.scanCodeButton.setTitle(NSLocalizedString("Scan Code", comment: ""), forState: .Normal)
self.noCodeButton.setTitle(NSLocalizedString("No Code", comment: ""), forState: .Normal)
self.bottomLabel.text = NSLocalizedString("QR found", comment: "")
self.infoCodeLabel.text = NSLocalizedString("QR found", comment: "")
}
private func setupNavigationbar() {
private func setupNavigationBar() {
let imageView = UIImageView(image: UIImage(named: "sap_logo"))
let barButtonItem = UIBarButtonItem(customView: imageView)
self.navigationItem.leftBarButtonItem = barButtonItem
@@ -71,10 +71,11 @@ class HomeViewController: CheckInViewController, UITableViewDataSource, UITableV
// MARK: - Notifications
private func subscribeForNotifications() {
NSNotificationCenter.defaultCenter().addObserver(self,
selector: #selector(openUrl(_:)),
name: AppDelegate.NotificationType.openUrl,
object: nil)
// FIXME: - How to react?
// NSNotificationCenter.defaultCenter().addObserver(self,
// selector: #selector(openUrl(_:)),
// name: AppDelegate.NotificationType.openUrl,
// object: nil)
NSNotificationCenter.defaultCenter().addObserver(self,
selector: #selector(HomeViewController.checkEULA(_:)),
name: UIApplicationWillEnterForegroundNotification,
@@ -169,6 +170,10 @@ class HomeViewController: CheckInViewController, UITableViewDataSource, UITableV
// MARK: - UITableViewDelegate
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 74
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
DataManager.sharedManager.selectedCheckIn = (fetchedResultsController!.objectAtIndexPath(indexPath) as! CheckIn)
tableView.deselectRowAtIndexPath(indexPath, animated: true)
@@ -63,7 +63,7 @@
<key>UIRequiresFullScreen</key>
<true/>
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>
<string>UIStatusBarStyleDefault</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9532" systemVersion="15E65" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10116" systemVersion="15E65" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9530"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
</dependencies>
<scenes>
@@ -0,0 +1,60 @@
//
// ModeTrackingTableViewCell.swift
// SAPTracker
//
// Created by Raimund Wege on 07.06.16.
// Copyright © 2016 com.sap.sailing. All rights reserved.
//
import UIKit
class ModeTrackingTableViewCell: UITableViewCell {
@IBOutlet weak var modeLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
self.setupModeLabel()
self.subscribeForNotifications()
}
deinit {
self.unsubscribeFromNotifications()
}
// MARK: - Setups
private func setupModeLabel() {
if (APIManager.sharedManager.networkAvailable) {
if !BatteryManager.sharedManager.batterySaving {
modeLabel.text = NSLocalizedString("Online", comment: "")
} else {
modeLabel.text = NSLocalizedString("Battery Saving", comment: "")
}
} else {
modeLabel.text = NSLocalizedString("Offline", comment: "")
}
// FIXME: - Show "API Error" in red in case of response errors
}
// MARK: - Notifications
private func subscribeForNotifications() {
NSNotificationCenter.defaultCenter().addObserver(self,
selector:#selector(networkAvailabilityChanged),
name:APIManager.NotificationType.networkAvailabilityChanged,
object: nil)
}
private func unsubscribeFromNotifications() {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
func networkAvailabilityChanged(notification: NSNotification) {
dispatch_async(dispatch_get_main_queue(), {
self.setupModeLabel()
})
}
}
@@ -15,6 +15,7 @@ class RegattaViewController : UIViewController, UIActionSheetDelegate, UINavigat
enum ActionSheet: Int {
case Menu
}
enum AlertView: Int {
case CheckOut, Image, UploadFailed
}
@@ -26,40 +27,27 @@ class RegattaViewController : UIViewController, UIActionSheetDelegate, UINavigat
var sourceTypes = [UIImagePickerControllerSourceType]()
var sourceTypeNames = [String]()
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var yourTeamPhotoButton: UIButton!
@IBOutlet weak var editTeamPhotoButton: UIButton!
@IBOutlet weak var retryUploadTeamPhotoButton: UIButton!
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var flagImageView: UIImageView!
@IBOutlet weak var sailLabel: UILabel!
@IBOutlet weak var teamImageView: UIImageView!
@IBOutlet weak var teamImageAddButton: UIButton!
@IBOutlet weak var teamImageEditButton: UIButton!
@IBOutlet weak var teamImageRetryButton: UIButton!
@IBOutlet weak var competitorNameLabel: UILabel!
@IBOutlet weak var competitorFlagImageView: UIImageView!
@IBOutlet weak var competitorSailLabel: UILabel!
@IBOutlet weak var regattaStartLabel: UILabel!
@IBOutlet weak var daysHeight: NSLayoutConstraint!
@IBOutlet weak var daysLabel: UILabel!
@IBOutlet weak var hoursHeight: NSLayoutConstraint!
@IBOutlet weak var hoursLabel: UILabel!
@IBOutlet weak var minutesHeight: NSLayoutConstraint!
@IBOutlet weak var minutesLabel: UILabel!
@IBOutlet weak var lastSyncLabel: UILabel!
@IBOutlet weak var leaderBoardButton: UIButton!
@IBOutlet weak var openEventButton: UIButton!
@IBOutlet weak var countdownView: UIView!
@IBOutlet weak var countdownViewHeight: NSLayoutConstraint!
@IBOutlet weak var countdownDaysLabel: UILabel!
@IBOutlet weak var countdownHoursLabel: UILabel!
@IBOutlet weak var countdownMinutesLabel: UILabel!
@IBOutlet weak var leaderboardButton: UIButton!
@IBOutlet weak var eventButton: UIButton!
@IBOutlet weak var startTrackingButton: UIButton!
@IBOutlet weak var leaderBoardButtonHeight: NSLayoutConstraint!
@IBOutlet weak var announcementsLabel: PaddedLabel!
@IBOutlet weak var announcementsLabel: UILabel!
var dateFormatter: NSDateFormatter
var isFinished: Bool = false
let secondsInDay: Double = 60 * 60 * 24
let secondsInHour: Double = 60 * 60
var loop: NSTimer?
/* Setup date formatter for last sync. */
required init(coder aDecoder: NSCoder) {
dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MMM d, yyyy, h:mm a" // As per request - see mail 19.02.2016
super.init(coder: aDecoder)!
}
var timer: NSTimer?
var uploadKey: String {
return RegattaViewUserDefaults.UploadDidFail + "_" + DataManager.sharedManager.selectedCheckIn!.competitorId
@@ -70,37 +58,37 @@ class RegattaViewController : UIViewController, UIActionSheetDelegate, UINavigat
// set values
navigationItem.title = DataManager.sharedManager.selectedCheckIn!.leaderBoardName
openEventButton.setTitle(NSLocalizedString("Show Event", comment: ""), forState: UIControlState.Normal)
self.eventButton.setTitle(NSLocalizedString("Show Event", comment: ""), forState: UIControlState.Normal)
retryUploadTeamPhotoButton.hidden = !NSUserDefaults.standardUserDefaults().boolForKey(uploadKey)
self.teamImageRetryButton.hidden = !NSUserDefaults.standardUserDefaults().boolForKey(uploadKey)
// set regatta image, either load it from server or load from core data
// Set regatta image, either load it from server or load from core data
if DataManager.sharedManager.selectedCheckIn?.userImage != nil {
imageView.image = UIImage(data: DataManager.sharedManager.selectedCheckIn!.userImage!)
self.yourTeamPhotoButton.hidden = true
self.teamImageView.image = UIImage(data: DataManager.sharedManager.selectedCheckIn!.userImage!)
self.teamImageAddButton.hidden = true
} else if DataManager.sharedManager.selectedCheckIn?.imageUrl != nil {
let imageUrl = NSURL(string: DataManager.sharedManager.selectedCheckIn!.imageUrl!)
let urlRequest = NSURLRequest(URL: imageUrl!)
imageView.setImageWithURLRequest(urlRequest,
self.teamImageView.setImageWithURLRequest(urlRequest,
placeholderImage: nil,
success: { (request:NSURLRequest!,response:NSHTTPURLResponse!, image:UIImage!) -> Void in
self.imageView.image = image
self.yourTeamPhotoButton.hidden = true
self.teamImageView.image = image
self.teamImageAddButton.hidden = true
},
failure: { (request:NSURLRequest!,response:NSHTTPURLResponse!, error:NSError!) -> Void in
self.editTeamPhotoButton.hidden = true
self.yourTeamPhotoButton.hidden = !self.retryUploadTeamPhotoButton.hidden
self.teamImageEditButton.hidden = true
self.teamImageAddButton.hidden = !self.teamImageRetryButton.hidden
}
)
} else {
self.editTeamPhotoButton.hidden = true
self.yourTeamPhotoButton.hidden = !self.retryUploadTeamPhotoButton.hidden
self.teamImageEditButton.hidden = true
self.teamImageAddButton.hidden = !self.teamImageRetryButton.hidden
}
if (DataManager.sharedManager.selectedCheckIn?.competitor != nil) {
let competitor = DataManager.sharedManager.selectedCheckIn!.competitor!
nameLabel.text = competitor.name
flagImageView.image = UIImage(named: competitor.countryCode)
sailLabel.text = competitor.sailId
self.competitorNameLabel.text = competitor.name
self.competitorFlagImageView.image = UIImage(named: competitor.countryCode)
self.competitorSailLabel.text = competitor.sailId
}
checkRegattaStatus()
@@ -126,7 +114,7 @@ class RegattaViewController : UIViewController, UIActionSheetDelegate, UINavigat
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
loop?.invalidate()
timer?.invalidate()
}
override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {
@@ -141,59 +129,39 @@ class RegattaViewController : UIViewController, UIActionSheetDelegate, UINavigat
let now = NSDate()
isFinished = false
// reset views
lastSyncLabel.hidden = true
if DataManager.sharedManager.selectedCheckIn!.lastSyncDate != nil {
lastSyncLabel.text = NSLocalizedString("Last sync", comment: "") + " " + dateFormatter.stringFromDate(DataManager.sharedManager.selectedCheckIn!.lastSyncDate!)
} else {
lastSyncLabel.text = nil
}
startTrackingButton.setTitle(NSLocalizedString("Start Tracking", comment: ""), forState: UIControlState.Normal)
announcementsLabel.text = NSLocalizedString("Please listen for announcements", comment: "")
if DataManager.sharedManager.selectedCheckIn?.event != nil {
let event = DataManager.sharedManager.selectedCheckIn!.event!
// // finished
// if now.timeIntervalSinceDate(event.endDate) > 0 {
// isFinished = true
// regattaStartLabel.text = NSLocalizedString("Thank you for participating!", comment: "")
// leaderBoardButtonHeight.constant = ButtonHeight.smallButtonPortrait
// daysHeight.constant = 0
// hoursHeight.constant = 0
// minutesHeight.constant = 0
// startTrackingButton.setTitle(NSLocalizedString("Check-Out", comment: ""), forState: UIControlState.Normal)
// startTrackingButton.backgroundColor = UIColor(hex: 0xEFAD00)
// announcementsLabel.text = " "
// }
// else
// before race
if now.timeIntervalSinceDate(event.startDate) < 0 {
regattaStartLabel.text = NSLocalizedString("Regatta will start in", comment: "")
lastSyncLabel.hidden = false
leaderBoardButtonHeight.constant = 0
self.regattaStartLabel.text = NSLocalizedString("Regatta will start in", comment: "")
let delta = floor(now.timeIntervalSinceDate(event.startDate)) * -1
let days = floor(delta / secondsInDay)
let hours = floor((delta - days * secondsInDay) / secondsInHour)
let minutes = floor((delta - days * secondsInDay - hours * secondsInHour) / 60.0)
daysLabel.text = String(format: "%.0f", arguments: [days])
hoursLabel.text = String(format: "%.0f", arguments: [hours])
minutesLabel.text = String(format: "%.0f", arguments: [minutes])
loop?.invalidate()
loop = NSTimer(timeInterval: 60, target: self, selector: #selector(RegattaViewController.checkRegattaStatus), userInfo: nil, repeats: false)
NSRunLoop.currentRunLoop().addTimer(loop!, forMode:NSRunLoopCommonModes)
self.countdownDaysLabel.text = String(format: "%.0f", arguments: [days])
self.countdownHoursLabel.text = String(format: "%.0f", arguments: [hours])
self.countdownMinutesLabel.text = String(format: "%.0f", arguments: [minutes])
self.countdownView.hidden = false
self.countdownViewHeight.constant = 60
timer?.invalidate()
timer = NSTimer(timeInterval: 60,
target: self,
selector: #selector(RegattaViewController.checkRegattaStatus),
userInfo: nil,
repeats: false)
NSRunLoop.currentRunLoop().addTimer(timer!, forMode:NSRunLoopCommonModes)
}
// during race
else {
regattaStartLabel.text = NSLocalizedString("Regatta in progress", comment: "")
daysHeight.constant = 0
hoursHeight.constant = 0
minutesHeight.constant = 0
leaderBoardButtonHeight.constant = ButtonHeight.smallButtonPortrait
lastSyncLabel.hidden = false
self.regattaStartLabel.text = NSLocalizedString("Regatta in progress", comment: "")
self.countdownView.hidden = true
self.countdownViewHeight.constant = 0
}
}
}
@@ -280,10 +248,10 @@ class RegattaViewController : UIViewController, UIActionSheetDelegate, UINavigat
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!) {
dismissViewControllerAnimated(true, completion: nil)
imageView.image = image
yourTeamPhotoButton.hidden = true
editTeamPhotoButton.hidden = false
retryUploadTeamPhotoButton.hidden = true
self.teamImageView.image = image
self.teamImageAddButton.hidden = true
self.teamImageEditButton.hidden = false
self.teamImageRetryButton.hidden = true
let jpegData = UIImageJPEGRepresentation(image, 0.8)
DataManager.sharedManager.selectedCheckIn!.userImage = jpegData
APIManager.sharedManager.postTeamImage(DataManager.sharedManager.selectedCheckIn!.competitorId,
@@ -305,7 +273,7 @@ class RegattaViewController : UIViewController, UIActionSheetDelegate, UINavigat
NSUserDefaults.standardUserDefaults().setBool(true, forKey: self.uploadKey)
NSUserDefaults.standardUserDefaults().synchronize()
self.retryUploadTeamPhotoButton.hidden = false
self.teamImageRetryButton.hidden = false
})
}
@@ -353,7 +321,4 @@ class RegattaViewController : UIViewController, UIActionSheetDelegate, UINavigat
}
}
func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent
}
}
@@ -10,28 +10,36 @@ import Foundation
class SpeedViewController: UIViewController {
let knPerMs = 1.94552529182879
private let mpsToKn = 1.94552529182879
@IBOutlet weak var speedLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
self.subscribeForNotifications()
}
// React on new locations
deinit {
self.unsubscribeFromNotifications()
}
// MARK: - Notifications
private func subscribeForNotifications() {
NSNotificationCenter.defaultCenter().addObserver(self,
selector:#selector(SpeedViewController.newLocation(_:)),
selector:#selector(newLocation),
name:LocationManager.NotificationType.newLocation,
object: nil)
}
deinit {
private func unsubscribeFromNotifications() {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
func newLocation(notification: NSNotification) {
let ms = notification.userInfo!["speed"] as! Double
if(ms >= 0) {
let kn = ms * knPerMs
let mps = notification.userInfo!["speed"] as! Double
if mps >= 0 {
let kn = mps * mpsToKn
speedLabel.text = String(format: "%0.1f kn", kn)
} else {
speedLabel.text = "– kn"
@@ -0,0 +1,62 @@
//
// StatusTrackingTableViewCell.swift
// SAPTracker
//
// Created by Raimund Wege on 07.06.16.
// Copyright © 2016 com.sap.sailing. All rights reserved.
//
import UIKit
class StatusTrackingTableViewCell: UITableViewCell {
@IBOutlet weak var statusLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
self.setupStatusLabel(false)
self.subscribeForNotifications()
}
deinit {
self.unsubscribeFromNotifications()
}
// MARK: - Setups
private func setupStatusLabel(isTracking: Bool) {
statusLabel.text = isTracking ?
NSLocalizedString("Tracking", comment: "") :
NSLocalizedString("Not Tracking", comment: "")
}
// MARK: - Notifications
private func subscribeForNotifications() {
NSNotificationCenter.defaultCenter().addObserver(self,
selector:#selector(newLocation),
name:LocationManager.NotificationType.newLocation,
object: nil)
NSNotificationCenter.defaultCenter().addObserver(self,
selector:#selector(locationManagerFailed),
name:LocationManager.NotificationType.locationManagerFailed,
object: nil)
}
private func unsubscribeFromNotifications() {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
func newLocation(notification: NSNotification) {
dispatch_async(dispatch_get_main_queue(), {
self.setupStatusLabel(true)
})
}
func locationManagerFailed(notification: NSNotification) {
dispatch_async(dispatch_get_main_queue(), {
self.setupStatusLabel(false)
})
}
}
@@ -10,25 +10,36 @@ import Foundation
class TimerViewController: UIViewController {
@IBOutlet weak var trackingTimeLabel: UILabel!
private let startDate = NSDate()
private let dateFormatter = NSDateFormatter()
let startDate = NSDate()
let dateFormatter = NSDateFormatter()
@IBOutlet weak var trackingTimeLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
self.setupDateFormatter()
self.setupTimer()
}
// start tracking timer
let timer = NSTimer(timeInterval: 0.1, target: self, selector: #selector(TimerViewController.timer(_:)), userInfo: nil, repeats: true)
NSRunLoop.currentRunLoop().addTimer(timer, forMode:NSRunLoopCommonModes)
// MARK: - Setups
private func setupDateFormatter() {
dateFormatter.dateFormat = "HH:mm:ss"
dateFormatter.timeZone = NSTimeZone(forSecondsFromGMT: 0)
}
private func setupTimer() {
let timer = NSTimer(timeInterval: 0.1,
target: self,
selector: #selector(tick),
userInfo: nil,
repeats: true)
NSRunLoop.currentRunLoop().addTimer(timer, forMode:NSRunLoopCommonModes)
}
// MARK: - Timer
func timer(timer: NSTimer) {
@objc private func tick(timer: NSTimer) {
let currentDate = NSDate()
let timeInterval = currentDate.timeIntervalSinceDate(startDate)
let timerDate = NSDate(timeIntervalSince1970: timeInterval)
@@ -8,88 +8,80 @@
import Foundation
class TrackingViewController : UIViewController {
class TrackingViewController : UIViewController, UITableViewDataSource, UITableViewDelegate {
struct Color {
static let GpsActive = UIColor(hex: 0x8AB54D)
static let GpsInactive = UIColor(hex: 0x445A2F)
static let Green = UIColor(hex: 0x408000)
static let Red = UIColor(hex: 0xFF0000)
static let Orange = UIColor(hex: 0xFF8000)
struct CellIdentifier {
static let StatusCell = "StatusCell"
static let ModeCell = "ModeCell"
static let ChachedFixesCell = "CachedFixesCell"
static let GPSAccuracyCell = "GPSAccuracyCell"
}
@IBOutlet weak var gpsAccuracy: UILabel!
@IBOutlet weak var trackingStatusLabel: UILabel!
@IBOutlet weak var cachedFixesLabel: UILabel!
@IBOutlet weak var onlineModeLabel: UILabel!
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var tableViewHeight: NSLayoutConstraint!
let rows = [
CellIdentifier.StatusCell,
CellIdentifier.ModeCell,
CellIdentifier.ChachedFixesCell,
CellIdentifier.GPSAccuracyCell
]
/* Register for notifications. Set up timer */
override func viewDidLoad() {
super.viewDidLoad()
// set values
navigationItem.title = DataManager.sharedManager.selectedCheckIn!.leaderBoardName
cachedFixesLabel.text = String(format: "%d", DataManager.sharedManager.countCachedFixes())
// set online/buffering label
networkAvailabilityChanged()
// register for notifications
NSNotificationCenter.defaultCenter().addObserver(self, selector:#selector(TrackingViewController.networkAvailabilityChanged), name:APIManager.NotificationType.networkAvailabilityChanged, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector:#selector(TrackingViewController.newLocation(_:)), name:LocationManager.NotificationType.newLocation, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector:#selector(TrackingViewController.locationManagerFailed(_:)), name:LocationManager.NotificationType.locationManagerFailed, object: nil)
self.setupNavigationBarTitle()
}
// MARK:- Buttons
override func updateViewConstraints() {
super.updateViewConstraints()
self.tableViewHeight.constant = tableView.contentSize.height
}
// MARK: - Setups
private func setupNavigationBarTitle() {
navigationItem.title = DataManager.sharedManager.selectedCheckIn!.leaderBoardName
}
// MARK: - Actions
/* Stop tracking, go back to regattas view */
@IBAction func stopTrackingButtonTapped(sender: AnyObject) {
let alertController = UIAlertController(title: NSLocalizedString("Stop tracking?", comment: ""), message: "", preferredStyle: .Alert)
let aCancel = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .Cancel, handler: nil)
alertController.addAction(aCancel)
let aStop = UIAlertAction(title: NSLocalizedString("Stop", comment: ""), style: .Default) { action in
let alertTitle = NSLocalizedString("Stop tracking?", comment: "")
let alertController = UIAlertController(title: alertTitle,
message: "",
preferredStyle: .Alert)
let cancelTitle = NSLocalizedString("Cancel", comment: "")
let cancelAction = UIAlertAction(title: cancelTitle, style: .Cancel, handler: nil)
let stopTitle = NSLocalizedString("Stop", comment: "")
let stopAction = UIAlertAction(title: stopTitle, style: .Default) { action in
LocationManager.sharedManager.stopTracking()
SendGPSFixController.sharedManager.checkIn = nil
self.dismissViewControllerAnimated(true, completion: nil)
}
alertController.addAction(aStop)
alertController.addAction(cancelAction)
alertController.addAction(stopAction)
presentViewController(alertController, animated: true, completion: nil)
}
// MARK:- Notifications
// MARK: - UITableViewDataSourceDelegate
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return rows.count
}
func networkAvailabilityChanged() {
if (APIManager.sharedManager.networkAvailable) {
if !BatteryManager.sharedManager.batterySaving {
onlineModeLabel.text = NSLocalizedString("Online", comment: "")
onlineModeLabel.textColor = Color.Green
} else {
onlineModeLabel.text = NSLocalizedString("Battery Saving", comment: "")
onlineModeLabel.textColor = Color.Orange
}
} else {
onlineModeLabel.text = NSLocalizedString("Offline", comment: "")
onlineModeLabel.textColor = Color.Red
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
return tableView.dequeueReusableCellWithIdentifier(rows[indexPath.row]) ?? UITableViewCell()
}
func newLocation(notification: NSNotification) {
let horizontalAccuracy = notification.userInfo!["horizontalAccuracy"] as! Double
gpsAccuracy.text = "~ " + String(format: "%.0f", horizontalAccuracy) + " m"
trackingStatusLabel.text = NSLocalizedString("Tracking", comment: "")
trackingStatusLabel.textColor = Color.Green
cachedFixesLabel.text = String(format: "%d", DataManager.sharedManager.countCachedFixes())
// MARK: - UITableViewDelegate
func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 52
}
func locationManagerFailed(notification: NSNotification) {
gpsAccuracy.text = NSLocalizedString("No GPS", comment: "")
trackingStatusLabel.text = NSLocalizedString("Not Tracking", comment: "")
trackingStatusLabel.textColor = Color.Red
func tableView(tableView: UITableView, estimatedHeightForFooterInSection section: Int) -> CGFloat {
return 0
}
}