Added dependency injection for better code reuse

This commit is contained in:
Raimund Wege
2017-08-21 15:43:29 +02:00
parent 57a00fba98
commit 5a23bdc7df
10 changed files with 73 additions and 39 deletions
@@ -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
}()