mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-20 20:55:31 +00:00
Added dependency injection for better code reuse
This commit is contained in:
@@ -23,7 +23,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
if let gpsFixes = checkIn.gpsFixes {
|
||||
if gpsFixes.count > 0 {
|
||||
noData = false
|
||||
let gpsFixController = GPSFixController(checkIn: checkIn)
|
||||
let gpsFixController = GPSFixController(checkIn: checkIn, coreDataManager: RegattaCoreDataManager.shared)
|
||||
gpsFixController.sendAll(completion: { (withSuccess) in
|
||||
allSuccess = allSuccess && withSuccess
|
||||
})
|
||||
|
||||
@@ -12,11 +12,6 @@ import CoreData
|
||||
@objc(CheckIn)
|
||||
class CheckIn: NSManagedObject {
|
||||
|
||||
func initialize() {
|
||||
event = RegattaCoreDataManager.shared.newEvent(checkIn: self)
|
||||
leaderboard = RegattaCoreDataManager.shared.newLeaderboard(checkIn: self)
|
||||
}
|
||||
|
||||
func updateWithCheckInData(checkInData: CheckInData) {
|
||||
serverURL = checkInData.serverURL
|
||||
event.updateWithEventData(eventData: checkInData.eventData)
|
||||
|
||||
@@ -18,10 +18,16 @@ import AVFoundation
|
||||
|
||||
class CheckInController : NSObject {
|
||||
|
||||
weak var coreDataManager: CoreDataManager!
|
||||
weak var delegate: CheckInControllerDelegate?
|
||||
|
||||
fileprivate var requestManager = RequestManager()
|
||||
|
||||
init(coreDataManager: CoreDataManager) {
|
||||
self.coreDataManager = coreDataManager
|
||||
super.init()
|
||||
}
|
||||
|
||||
// MARK: - CheckIn
|
||||
|
||||
func checkIn(checkInData: CheckInData, completion: @escaping (_ withSuccess: Bool) -> Void) {
|
||||
@@ -92,23 +98,23 @@ class CheckInController : NSObject {
|
||||
fileprivate func postCheckInSuccess(checkInData: CheckInData, completion: (_ withSuccess: Bool) -> Void) {
|
||||
switch checkInData.type {
|
||||
case .competitor:
|
||||
let competitorCheckIn = RegattaCoreDataManager.shared.fetchCompetitorCheckIn(
|
||||
let competitorCheckIn = coreDataManager.fetchCompetitorCheckIn(
|
||||
eventID: checkInData.eventID,
|
||||
leaderboardName: checkInData.leaderboardName,
|
||||
competitorID: checkInData.competitorID!
|
||||
) ?? RegattaCoreDataManager.shared.newCompetitorCheckIn()
|
||||
) ?? coreDataManager.newCompetitorCheckIn()
|
||||
competitorCheckIn.updateWithCheckInData(checkInData: checkInData)
|
||||
RegattaCoreDataManager.shared.saveContext()
|
||||
coreDataManager.saveContext()
|
||||
checkInDidFinish(withSuccess: true, completion: completion)
|
||||
break
|
||||
case .mark:
|
||||
let markCheckIn = RegattaCoreDataManager.shared.fetchMarkCheckIn(
|
||||
let markCheckIn = coreDataManager.fetchMarkCheckIn(
|
||||
eventID: checkInData.eventID,
|
||||
leaderboardName: checkInData.leaderboardName,
|
||||
markID: checkInData.markID!
|
||||
) ?? RegattaCoreDataManager.shared.newMarkCheckIn()
|
||||
) ?? coreDataManager.newMarkCheckIn()
|
||||
markCheckIn.updateWithCheckInData(checkInData: checkInData)
|
||||
RegattaCoreDataManager.shared.saveContext()
|
||||
coreDataManager.saveContext()
|
||||
checkInDidFinish(withSuccess: true, completion: completion)
|
||||
break
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ class CompetitorViewController : SessionViewController, UINavigationControllerDe
|
||||
@IBOutlet weak var announcementLabel: UILabel!
|
||||
|
||||
weak var competitorCheckIn: CompetitorCheckIn!
|
||||
weak var coreDataManager: CoreDataManager!
|
||||
|
||||
weak var countdownTimer: Timer?
|
||||
|
||||
@@ -173,7 +174,7 @@ class CompetitorViewController : SessionViewController, UINavigationControllerDe
|
||||
teamImageView.image = image
|
||||
competitorCheckIn.teamImageRetry = false
|
||||
competitorCheckIn.teamImageData = UIImageJPEGRepresentation(image, 0.8)
|
||||
RegattaCoreDataManager.shared.saveContext()
|
||||
coreDataManager.saveContext()
|
||||
success()
|
||||
}
|
||||
|
||||
@@ -300,7 +301,7 @@ class CompetitorViewController : SessionViewController, UINavigationControllerDe
|
||||
// MARK: - Properties
|
||||
|
||||
fileprivate lazy var competitorSessionController: CompetitorSessionController = {
|
||||
return CompetitorSessionController(checkIn: self.competitorCheckIn)
|
||||
return CompetitorSessionController(checkIn: self.competitorCheckIn, coreDataManager: self.coreDataManager)
|
||||
}()
|
||||
|
||||
}
|
||||
@@ -329,7 +330,7 @@ extension CompetitorViewController: UIImagePickerControllerDelegate {
|
||||
fileprivate func pickedImage(image: UIImage) {
|
||||
teamImageView.image = image
|
||||
competitorCheckIn.teamImageData = UIImageJPEGRepresentation(image, 0.8)
|
||||
RegattaCoreDataManager.shared.saveContext()
|
||||
coreDataManager.saveContext()
|
||||
if let data = competitorCheckIn.teamImageData {
|
||||
uploadTeamImageData(imageData: data)
|
||||
}
|
||||
@@ -354,13 +355,13 @@ extension CompetitorViewController: UIImagePickerControllerDelegate {
|
||||
fileprivate func uploadTeamImageDataSuccess(teamImageURL: String) {
|
||||
competitorCheckIn.teamImageRetry = false
|
||||
competitorCheckIn.teamImageURL = teamImageURL
|
||||
RegattaCoreDataManager.shared.saveContext()
|
||||
coreDataManager.saveContext()
|
||||
refreshTeamImage()
|
||||
}
|
||||
|
||||
fileprivate func uploadTeamImageDataFailure(error: Error) {
|
||||
competitorCheckIn.teamImageRetry = true
|
||||
RegattaCoreDataManager.shared.saveContext()
|
||||
coreDataManager.saveContext()
|
||||
showUploadTeamImageFailureAlert(error: error)
|
||||
refreshTeamImage()
|
||||
}
|
||||
@@ -391,8 +392,8 @@ extension CompetitorViewController: SessionViewControllerDelegate {
|
||||
}
|
||||
|
||||
fileprivate func performCheckOutCompleted(withSuccess: Bool) {
|
||||
RegattaCoreDataManager.shared.deleteObject(object: competitorCheckIn)
|
||||
RegattaCoreDataManager.shared.saveContext()
|
||||
coreDataManager.deleteObject(object: competitorCheckIn)
|
||||
coreDataManager.saveContext()
|
||||
self.navigationController!.popViewController(animated: true)
|
||||
}
|
||||
|
||||
|
||||
@@ -120,13 +120,15 @@ class CoreDataManager: NSObject {
|
||||
|
||||
func newCompetitorCheckIn() -> CompetitorCheckIn {
|
||||
let checkIn = NSEntityDescription.insertNewObject(forEntityName: Entities.CompetitorCheckIn.rawValue, into: managedObjectContext) as! CompetitorCheckIn
|
||||
checkIn.initialize()
|
||||
checkIn.event = newEvent(checkIn: checkIn)
|
||||
checkIn.leaderboard = newLeaderboard(checkIn: checkIn)
|
||||
return checkIn
|
||||
}
|
||||
|
||||
func newMarkCheckIn() -> MarkCheckIn {
|
||||
let checkIn = NSEntityDescription.insertNewObject(forEntityName: Entities.MarkCheckIn.rawValue, into: managedObjectContext) as! MarkCheckIn
|
||||
checkIn.initialize()
|
||||
checkIn.event = newEvent(checkIn: checkIn)
|
||||
checkIn.leaderboard = newLeaderboard(checkIn: checkIn)
|
||||
return checkIn
|
||||
}
|
||||
|
||||
|
||||
@@ -40,9 +40,11 @@ class GPSFixController: NSObject {
|
||||
}
|
||||
|
||||
weak var checkIn: CheckIn!
|
||||
weak var coreDataManager: CoreDataManager!
|
||||
|
||||
init(checkIn: CheckIn) {
|
||||
init(checkIn: CheckIn, coreDataManager: CoreDataManager) {
|
||||
self.checkIn = checkIn
|
||||
self.coreDataManager = coreDataManager
|
||||
}
|
||||
|
||||
// MARK: - Send All
|
||||
@@ -127,8 +129,8 @@ class GPSFixController: NSObject {
|
||||
DispatchQueue.main.async(execute: {
|
||||
self.log(info: "Sending \(gpsFixes.count) GPS fixes was successful")
|
||||
self.postModeChangedNotification(mode: BatteryManager.sharedManager.batterySaving ? .BatterySaving : .Online)
|
||||
RegattaCoreDataManager.shared.deleteObjects(objects: gpsFixes)
|
||||
RegattaCoreDataManager.shared.saveContext()
|
||||
self.coreDataManager.deleteObjects(objects: gpsFixes)
|
||||
self.coreDataManager.saveContext()
|
||||
self.log(info: "\(gpsFixes.count) GPS fixes deleted")
|
||||
success(gpsFixesLeft)
|
||||
})
|
||||
|
||||
@@ -198,7 +198,7 @@ class HomeViewController: UIViewController {
|
||||
|
||||
fileprivate func reviewGPSFixes(checkIns: [CheckIn], completion: @escaping () -> Void) {
|
||||
guard checkIns.count > 0 else { completion(); return }
|
||||
let gpsFixController = GPSFixController.init(checkIn: checkIns[0])
|
||||
let gpsFixController = GPSFixController.init(checkIn: checkIns[0], coreDataManager: RegattaCoreDataManager.shared)
|
||||
gpsFixController.sendAll(completion: { (withSuccess) in
|
||||
self.reviewGPSFixes(checkIns: Array(checkIns[1..<checkIns.count]), completion: completion)
|
||||
})
|
||||
@@ -340,22 +340,25 @@ class HomeViewController: UIViewController {
|
||||
guard let competitorVC = segue.destination as? CompetitorViewController else { return }
|
||||
guard let competitorCheckIn = selectedCheckIn as? CompetitorCheckIn else { return }
|
||||
competitorVC.competitorCheckIn = competitorCheckIn
|
||||
competitorVC.coreDataManager = RegattaCoreDataManager.shared
|
||||
selectedCheckIn = nil
|
||||
} else if (segue.identifier == Segue.Mark) {
|
||||
guard let markVC = segue.destination as? MarkViewController else { return }
|
||||
guard let markCheckIn = selectedCheckIn as? MarkCheckIn else { return }
|
||||
markVC.markCheckIn = markCheckIn
|
||||
markVC.coreDataManager = RegattaCoreDataManager.shared
|
||||
selectedCheckIn = nil
|
||||
} else if (segue.identifier == Segue.Scan) {
|
||||
guard let scanVC = segue.destination as? ScanViewController else { return }
|
||||
scanVC.homeViewController = self
|
||||
scanVC.coreDataManager = RegattaCoreDataManager.shared
|
||||
scanVC.delegate = self
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
fileprivate lazy var checkInController: CheckInController = {
|
||||
let checkInController = CheckInController()
|
||||
let checkInController = CheckInController(coreDataManager: RegattaCoreDataManager.shared)
|
||||
checkInController.delegate = self
|
||||
return checkInController
|
||||
}()
|
||||
@@ -368,6 +371,16 @@ class HomeViewController: UIViewController {
|
||||
|
||||
}
|
||||
|
||||
// MARK: - ScanViewControllerDelegate
|
||||
|
||||
extension HomeViewController: ScanViewControllerDelegate {
|
||||
|
||||
func scanViewController(_ controller: ScanViewController, didScanCheckIn checkIn: CheckIn) {
|
||||
selectedCheckIn = checkIn
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - UITableViewDataSource
|
||||
|
||||
extension HomeViewController: UITableViewDataSource {
|
||||
|
||||
@@ -13,6 +13,7 @@ class MarkViewController: SessionViewController {
|
||||
@IBOutlet weak var markNameLabel: UILabel!
|
||||
|
||||
weak var markCheckIn: MarkCheckIn!
|
||||
weak var coreDataManager: CoreDataManager!
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
@@ -105,7 +106,7 @@ class MarkViewController: SessionViewController {
|
||||
// MARK: - Properties
|
||||
|
||||
fileprivate lazy var markSessionController: MarkSessionController = {
|
||||
return MarkSessionController(checkIn: self.markCheckIn)
|
||||
return MarkSessionController(checkIn: self.markCheckIn, coreDataManager: self.coreDataManager)
|
||||
}()
|
||||
|
||||
}
|
||||
@@ -121,8 +122,8 @@ extension MarkViewController: SessionViewControllerDelegate {
|
||||
}
|
||||
|
||||
fileprivate func performCheckOutCompleted(withSuccess: Bool) {
|
||||
RegattaCoreDataManager.shared.deleteObject(object: markCheckIn)
|
||||
RegattaCoreDataManager.shared.saveContext()
|
||||
coreDataManager.deleteObject(object: markCheckIn)
|
||||
coreDataManager.saveContext()
|
||||
self.navigationController!.popViewController(animated: true)
|
||||
}
|
||||
|
||||
|
||||
@@ -9,9 +9,16 @@
|
||||
import UIKit
|
||||
import AVFoundation
|
||||
|
||||
protocol ScanViewControllerDelegate: class {
|
||||
|
||||
func scanViewController(_ controller: ScanViewController, didScanCheckIn checkIn: CheckIn)
|
||||
|
||||
}
|
||||
|
||||
class ScanViewController: UIViewController {
|
||||
|
||||
weak var homeViewController: HomeViewController?
|
||||
weak var coreDataManager: CoreDataManager!
|
||||
weak var delegate: ScanViewControllerDelegate?
|
||||
|
||||
@IBOutlet weak var previewView: UIView!
|
||||
@IBOutlet weak var targetImageView: UIImageView!
|
||||
@@ -137,7 +144,7 @@ class ScanViewController: UIViewController {
|
||||
// MARK: - Properties
|
||||
|
||||
fileprivate lazy var checkInController: CheckInController = {
|
||||
let checkInController = CheckInController()
|
||||
let checkInController = CheckInController(coreDataManager: self.coreDataManager)
|
||||
checkInController.delegate = self
|
||||
return checkInController
|
||||
}()
|
||||
@@ -190,11 +197,16 @@ extension ScanViewController: AVCaptureMetadataOutputObjectsDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: remove completion and use a success and failure block
|
||||
fileprivate func captureOutputSuccess(checkInData: CheckInData) {
|
||||
checkInController.checkIn(checkInData: checkInData, completion: { (withSuccess) in
|
||||
if withSuccess {
|
||||
self.homeViewController?.selectedCheckIn = RegattaCoreDataManager.shared.fetchCheckIn(checkInData: checkInData)
|
||||
_ = self.navigationController?.popViewController(animated: true)
|
||||
if let checkIn = self.coreDataManager.fetchCheckIn(checkInData: checkInData) {
|
||||
self.delegate?.scanViewController(self, didScanCheckIn: checkIn)
|
||||
_ = self.navigationController?.popViewController(animated: true)
|
||||
} else {
|
||||
self.startScanning()
|
||||
}
|
||||
} else {
|
||||
self.startScanning()
|
||||
}
|
||||
|
||||
@@ -11,14 +11,16 @@ import UIKit
|
||||
class SessionController: NSObject {
|
||||
|
||||
weak var checkIn: CheckIn!
|
||||
weak var coreDataManager: CoreDataManager!
|
||||
|
||||
var sendingBackgroundTask: UIBackgroundTaskIdentifier = UIBackgroundTaskInvalid
|
||||
var sendingDate: Date = Date()
|
||||
|
||||
fileprivate (set) var isTracking: Bool = false
|
||||
|
||||
init(checkIn: CheckIn) {
|
||||
init(checkIn: CheckIn, coreDataManager: CoreDataManager) {
|
||||
self.checkIn = checkIn
|
||||
self.coreDataManager = coreDataManager
|
||||
super.init()
|
||||
subscribeForNotifications()
|
||||
}
|
||||
@@ -53,9 +55,9 @@ class SessionController: NSObject {
|
||||
guard self.isTracking else { return }
|
||||
guard let locationData = notification.userInfo?[LocationManager.UserInfo.LocationData] as? LocationData else { return }
|
||||
guard locationData.isValid else { return }
|
||||
let gpsFix = RegattaCoreDataManager.shared.newGPSFix(checkIn: self.checkIn)
|
||||
let gpsFix = self.coreDataManager.newGPSFix(checkIn: self.checkIn)
|
||||
gpsFix.updateWithLocationData(locationData: locationData)
|
||||
RegattaCoreDataManager.shared.saveContext()
|
||||
self.coreDataManager.saveContext()
|
||||
if self.sendingDate.compare(Date()) == .orderedAscending {
|
||||
self.sendingDate = Date().addingTimeInterval(BatteryManager.sharedManager.sendingPeriod)
|
||||
self.beginGPSFixSendingInBackgroundTask()
|
||||
@@ -105,7 +107,7 @@ class SessionController: NSObject {
|
||||
checkIn.event.updateWithEventData(eventData: checkInData.eventData)
|
||||
checkIn.leaderboard.updateWithLeaderboardData(leaderboardData: checkInData.leaderboardData)
|
||||
checkIn.updateWithCheckInData(checkInData: checkInData)
|
||||
RegattaCoreDataManager.shared.saveContext()
|
||||
coreDataManager.saveContext()
|
||||
completion()
|
||||
}
|
||||
|
||||
@@ -139,7 +141,7 @@ class SessionController: NSObject {
|
||||
// MARK: - Properties
|
||||
|
||||
lazy var gpsFixController: GPSFixController = {
|
||||
let gpsFixController = GPSFixController(checkIn: self.checkIn)
|
||||
let gpsFixController = GPSFixController(checkIn: self.checkIn, coreDataManager: self.coreDataManager)
|
||||
return gpsFixController
|
||||
}()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user