Fixed retain cycles

This commit is contained in:
Raimund Wege
2017-08-18 13:39:03 +02:00
parent fb5c30acf4
commit fe98544ffd
15 changed files with 127 additions and 99 deletions
@@ -10,7 +10,7 @@ import Foundation
import UIKit
import AVFoundation
@objc protocol CheckInControllerDelegate {
@objc protocol CheckInControllerDelegate: class {
func checkInController(_ sender: CheckInController, show alertController: UIAlertController)
@@ -18,7 +18,7 @@ import AVFoundation
class CheckInController : NSObject {
var delegate: CheckInControllerDelegate?
weak var delegate: CheckInControllerDelegate?
fileprivate var requestManager = RequestManager()
@@ -46,11 +46,11 @@ class CheckInController : NSObject {
message: String(format: Translation.CheckInController.WelcomeAlert.Message.String, checkInData.competitorData.sailID),
preferredStyle: .alert
)
let okAction = UIAlertAction(title: Translation.Common.OK.String, style: .default) { (action) in
self.postCheckIn(checkInData: checkInData, completion: completion)
let okAction = UIAlertAction(title: Translation.Common.OK.String, style: .default) { [weak self] action in
self?.postCheckIn(checkInData: checkInData, completion: completion)
}
let cancelAction = UIAlertAction(title: Translation.CheckInController.WelcomeAlert.CancelAction.Title.String, style: .cancel) { (action) in
self.checkInDidFinish(withSuccess: false, completion: completion)
let cancelAction = UIAlertAction(title: Translation.CheckInController.WelcomeAlert.CancelAction.Title.String, style: .cancel) { [weak self] action in
self?.checkInDidFinish(withSuccess: false, completion: completion)
}
alertController.addAction(okAction)
alertController.addAction(cancelAction)
@@ -68,8 +68,8 @@ class CheckInController : NSObject {
message: error.localizedDescription,
preferredStyle: .alert
)
let okAction = UIAlertAction(title: Translation.Common.OK.String, style: .default) { (action) in
self.checkInDidFinish(withSuccess: false, completion: completion)
let okAction = UIAlertAction(title: Translation.Common.OK.String, style: .default) { [weak self] action in
self?.checkInDidFinish(withSuccess: false, completion: completion)
}
alertController.addAction(okAction)
showCheckInAlert(alertController: alertController)
@@ -120,8 +120,8 @@ class CheckInController : NSObject {
message: error.localizedDescription,
preferredStyle: .alert
)
let okAction = UIAlertAction(title: Translation.Common.OK.String, style: .default) { (action) in
self.checkInDidFinish(withSuccess: false, completion: completion)
let okAction = UIAlertAction(title: Translation.Common.OK.String, style: .default) { [weak self] action in
self?.checkInDidFinish(withSuccess: false, completion: completion)
}
alertController.addAction(okAction)
showCheckInAlert(alertController: alertController)
@@ -30,9 +30,9 @@ class CompetitorViewController : SessionViewController, UINavigationControllerDe
@IBOutlet weak var eventButton: UIButton!
@IBOutlet weak var announcementLabel: UILabel!
var competitorCheckIn: CompetitorCheckIn!
weak var competitorCheckIn: CompetitorCheckIn!
var countdownTimer: Timer?
weak var countdownTimer: Timer?
override func viewDidLoad() {
super.viewDidLoad()
@@ -43,14 +43,36 @@ class CompetitorViewController : SessionViewController, UINavigationControllerDe
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
validateTimer()
refresh()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
invalidateTimer()
}
// MARK: - Timer
fileprivate func validateTimer() {
tickTimer()
countdownTimer = Timer.scheduledTimer(
timeInterval: 1,
target: self,
selector: #selector(tickTimer),
userInfo: nil,
repeats: true
)
}
fileprivate func invalidateTimer() {
countdownTimer?.invalidate()
}
// MARK: - Setup
fileprivate func setup() {
setupButtons()
setupCountdownTimer()
setupLocalization()
setupNavigationBar()
}
@@ -61,18 +83,6 @@ class CompetitorViewController : SessionViewController, UINavigationControllerDe
startTrackingButton.setBackgroundImage(Images.GreenHighlighted, for: .highlighted)
}
fileprivate func setupCountdownTimer() {
countdownTimer?.invalidate()
countdownTimer = Timer.scheduledTimer(
timeInterval: 1,
target: self,
selector: #selector(CompetitorViewController.countdownTimerTick),
userInfo: nil,
repeats: true
)
countdownTimerTick()
}
fileprivate func setupLocalization() {
announcementLabel.text = Translation.CompetitorView.AnnouncementLabel.Text.String
countdownDaysTitleLabel.text = Translation.CompetitorView.CountdownDaysTitleLabel.Text.String
@@ -174,7 +184,8 @@ class CompetitorViewController : SessionViewController, UINavigationControllerDe
// MARK: - Timer
@objc fileprivate func countdownTimerTick() {
@objc fileprivate func tickTimer() {
guard competitorCheckIn != nil else { return }
if competitorCheckIn.event.startDate - Date().timeIntervalSince1970 > 0 {
regattaStartLabel.text = Translation.CompetitorView.RegattaStartLabel.Text.BeforeRegattaDidStart.String
let duration = competitorCheckIn.event.startDate - Date().timeIntervalSince1970
@@ -220,20 +231,20 @@ class CompetitorViewController : SessionViewController, UINavigationControllerDe
if let popoverController = alertController.popoverPresentationController {
popoverController.barButtonItem = sender as? UIBarButtonItem
}
let settingsAction = UIAlertAction(title: Translation.SettingsView.Title.String, style: .default) { (action) in
self.performSegue(withIdentifier: Segue.Settings, sender: self)
let settingsAction = UIAlertAction(title: Translation.SettingsView.Title.String, style: .default) { [weak self] action in
self?.performSegue(withIdentifier: Segue.Settings, sender: self)
}
let checkOutAction = UIAlertAction(title: Translation.CompetitorView.OptionSheet.CheckOutAction.Title.String, style: .default) { (action) in
self.checkOut()
let checkOutAction = UIAlertAction(title: Translation.CompetitorView.OptionSheet.CheckOutAction.Title.String, style: .default) { [weak self] action in
self?.checkOut()
}
let replaceImageAction = UIAlertAction(title: Translation.CompetitorView.OptionSheet.ReplaceImageAction.Title.String, style: .default) { (action) in
self.showSelectImageAlert()
let replaceImageAction = UIAlertAction(title: Translation.CompetitorView.OptionSheet.ReplaceImageAction.Title.String, style: .default) { [weak self] action in
self?.showSelectImageAlert()
}
let updateAction = UIAlertAction(title: Translation.CompetitorView.OptionSheet.UpdateAction.Title.String, style: .default) { (action) -> Void in
self.update()
let updateAction = UIAlertAction(title: Translation.CompetitorView.OptionSheet.UpdateAction.Title.String, style: .default) { [weak self] action in
self?.update()
}
let aboutAction = UIAlertAction(title: Translation.Common.Info.String, style: .default) { (action) -> Void in
self.performSegue(withIdentifier: Segue.About, sender: alertController)
let aboutAction = UIAlertAction(title: Translation.Common.Info.String, style: .default) { [weak self] action in
self?.performSegue(withIdentifier: Segue.About, sender: alertController)
}
let cancelAction = UIAlertAction(title: Translation.Common.Cancel.String, style: .cancel, handler: nil)
alertController.addAction(settingsAction)
@@ -253,11 +264,11 @@ class CompetitorViewController : SessionViewController, UINavigationControllerDe
message: Translation.CompetitorView.SelectImageAlert.Message.String,
preferredStyle: .alert
)
let cameraAction = UIAlertAction(title: Translation.CompetitorView.SelectImageAlert.CameraAction.Title.String, style: .default) { (action) in
self.showImagePicker(sourceType: .camera)
let cameraAction = UIAlertAction(title: Translation.CompetitorView.SelectImageAlert.CameraAction.Title.String, style: .default) { [weak self] action in
self?.showImagePicker(sourceType: .camera)
}
let photoLibraryAction = UIAlertAction(title: Translation.CompetitorView.SelectImageAlert.PhotoLibraryAction.Title.String, style: .default) { (action) in
self.showImagePicker(sourceType: .photoLibrary)
let photoLibraryAction = UIAlertAction(title: Translation.CompetitorView.SelectImageAlert.PhotoLibraryAction.Title.String, style: .default) { [weak self] action in
self?.showImagePicker(sourceType: .photoLibrary)
}
let cancelAction = UIAlertAction(title: Translation.Common.Cancel.String, style: .cancel, handler: nil)
alertController.addAction(cameraAction)
@@ -18,7 +18,7 @@ protocol ForgotPasswordViewControllerDelegate {
class ForgotPasswordViewController: FormularViewController {
var signUpController: SignUpController?
weak var signUpController: SignUpController?
@IBOutlet weak var infoLabel: UILabel!
@IBOutlet weak var emailLabel: UILabel!
@@ -39,7 +39,7 @@ class GPSFixController: NSObject {
}
}
let checkIn: CheckIn
weak var checkIn: CheckIn!
init(checkIn: CheckIn) {
self.checkIn = checkIn
@@ -146,9 +146,9 @@ class HomeViewController: UIViewController {
message: Translation.HomeView.TermsAlert.Message.String,
preferredStyle: .alert
)
let showTermsAction = UIAlertAction(title: Translation.HomeView.TermsAlert.ShowTermsAction.Title.String, style: .default) { action in
let showTermsAction = UIAlertAction(title: Translation.HomeView.TermsAlert.ShowTermsAction.Title.String, style: .default) { [weak self] action in
UIApplication.shared.openURL(URLs.Terms)
self.reviewTerms(completion: completion) // Review terms until user accepted terms
self?.reviewTerms(completion: completion) // Review terms until user accepted terms
}
let acceptTermsAction = UIAlertAction(title: Translation.HomeView.TermsAlert.AcceptTermsAction.Title.String, style: .default) { action in
Preferences.termsAccepted = true
@@ -169,9 +169,9 @@ class HomeViewController: UIViewController {
message: "Please try to respect the code convention which is used for this project.",
preferredStyle: .alert
)
let showCodeConventionAction = UIAlertAction(title: "Code Convention", style: .default) { action in
let showCodeConventionAction = UIAlertAction(title: "Code Convention", style: .default) { [weak self] action in
UIApplication.shared.openURL(URLs.CodeConvention)
self.reviewCodeConvention(completion: completion)
self?.reviewCodeConvention(completion: completion)
}
let okAction = UIAlertAction(title: "OK", style: .default) { action in
Preferences.codeConventionRead = true
@@ -266,11 +266,11 @@ class HomeViewController: UIViewController {
if let popoverController = alertController.popoverPresentationController {
popoverController.barButtonItem = sender as? UIBarButtonItem
}
let settingsAction = UIAlertAction(title: Translation.SettingsView.Title.String, style: .default) { (action) -> Void in
self.performSegue(withIdentifier: Segue.Settings, sender: alertController)
let settingsAction = UIAlertAction(title: Translation.SettingsView.Title.String, style: .default) { [weak self] action in
self?.performSegue(withIdentifier: Segue.Settings, sender: alertController)
}
let aboutAction = UIAlertAction(title: Translation.Common.Info.String, style: .default) { (action) -> Void in
self.performSegue(withIdentifier: Segue.About, sender: alertController)
let aboutAction = UIAlertAction(title: Translation.Common.Info.String, style: .default) { [weak self] action in
self?.performSegue(withIdentifier: Segue.About, sender: alertController)
}
let cancelAction = UIAlertAction(title: Translation.Common.Cancel.String, style: .cancel, handler: nil)
alertController.addAction(settingsAction)
@@ -10,7 +10,7 @@ import Foundation
class LeaderboardViewController: UIViewController {
var checkIn: CheckIn!
weak var checkIn: CheckIn!
@IBOutlet weak var webView: UIWebView!
@IBOutlet weak var activityIndicator: UIActivityIndicatorView!
@@ -55,8 +55,8 @@ extension LeaderboardViewController: UIWebViewDelegate {
func webView(_ webView: UIWebView, didFailLoadWithError error: Error) {
activityIndicator.stopAnimating()
let alertController = UIAlertController(title: error.localizedDescription, message: nil, preferredStyle: .alert)
let okAction = UIAlertAction(title: Translation.Common.OK.String, style: .default) { (action) in
self.presentingViewController!.dismiss(animated: true, completion: nil)
let okAction = UIAlertAction(title: Translation.Common.OK.String, style: .default) { [weak self] action in
self?.presentingViewController!.dismiss(animated: true, completion: nil)
}
alertController.addAction(okAction)
present(alertController, animated: true, completion: nil)
@@ -12,7 +12,7 @@ class MarkViewController: SessionViewController {
@IBOutlet weak var markNameLabel: UILabel!
var markCheckIn: MarkCheckIn!
weak var markCheckIn: MarkCheckIn!
override func viewDidLoad() {
super.viewDidLoad()
@@ -70,17 +70,17 @@ class MarkViewController: SessionViewController {
if let popoverController = alertController.popoverPresentationController {
popoverController.barButtonItem = sender as? UIBarButtonItem
}
let settingsAction = UIAlertAction(title: Translation.SettingsView.Title.String, style: .default) { (action) in
self.performSegue(withIdentifier: Segue.Settings, sender: self)
let settingsAction = UIAlertAction(title: Translation.SettingsView.Title.String, style: .default) { [weak self] action in
self?.performSegue(withIdentifier: Segue.Settings, sender: self)
}
let checkOutAction = UIAlertAction(title: Translation.CompetitorView.OptionSheet.CheckOutAction.Title.String, style: .default) { (action) in
self.checkOut()
let checkOutAction = UIAlertAction(title: Translation.CompetitorView.OptionSheet.CheckOutAction.Title.String, style: .default) { [weak self] action in
self?.checkOut()
}
let updateAction = UIAlertAction(title: Translation.CompetitorView.OptionSheet.UpdateAction.Title.String, style: .default) { (action) -> Void in
self.update()
let updateAction = UIAlertAction(title: Translation.CompetitorView.OptionSheet.UpdateAction.Title.String, style: .default) { [weak self] action in
self?.update()
}
let aboutAction = UIAlertAction(title: Translation.Common.Info.String, style: .default) { (action) -> Void in
self.performSegue(withIdentifier: Segue.About, sender: alertController)
let aboutAction = UIAlertAction(title: Translation.Common.Info.String, style: .default) { [weak self] action in
self?.performSegue(withIdentifier: Segue.About, sender: alertController)
}
let cancelAction = UIAlertAction(title: Translation.Common.Cancel.String, style: .cancel, handler: nil)
alertController.addAction(settingsAction)
@@ -105,14 +105,14 @@ class ScanViewController: UIViewController {
message: error.localizedFailureReason,
preferredStyle: .alert
)
let settingsAction = UIAlertAction(title: Translation.Common.Settings.String, style: .default) { (action) in
let settingsAction = UIAlertAction(title: Translation.Common.Settings.String, style: .default) { [weak self] action in
if let settingsURL = URL(string: UIApplicationOpenSettingsURLString) {
UIApplication.shared.openURL(settingsURL)
}
_ = self.navigationController?.popViewController(animated: true)
_ = self?.navigationController?.popViewController(animated: true)
}
let cancelAction = UIAlertAction(title: Translation.Common.Cancel.String, style: .cancel) { (action) in
_ = self.navigationController?.popViewController(animated: true)
let cancelAction = UIAlertAction(title: Translation.Common.Cancel.String, style: .cancel) { [weak self] action in
_ = self?.navigationController?.popViewController(animated: true)
}
alertController.addAction(settingsAction)
alertController.addAction(cancelAction)
@@ -213,8 +213,8 @@ extension ScanViewController: AVCaptureMetadataOutputObjectsDelegate {
message: Translation.ScanView.IncorrectCodeAlert.Message.String,
preferredStyle: .alert
)
let okAction = UIAlertAction(title: Translation.Common.OK.String, style: .default) { (action) in
self.startScanning()
let okAction = UIAlertAction(title: Translation.Common.OK.String, style: .default) { [weak self] action in
self?.startScanning()
}
alertController.addAction(okAction)
present(alertController, animated: true, completion: nil)
@@ -10,7 +10,7 @@ import UIKit
class SessionController: NSObject {
let checkIn: CheckIn
weak var checkIn: CheckIn!
var sendingBackgroundTask: UIBackgroundTaskIdentifier = UIBackgroundTaskInvalid
var sendingDate: Date = Date()
@@ -8,7 +8,7 @@
import UIKit
protocol SessionViewControllerDelegate {
protocol SessionViewControllerDelegate: class {
func performCheckOut()
@@ -27,7 +27,7 @@ class SessionViewController: UIViewController {
@IBOutlet weak var startTrackingButton: UIButton!
var delegate: SessionViewControllerDelegate!
weak var delegate: SessionViewControllerDelegate!
// MARK: - Actions
@@ -67,8 +67,8 @@ class SessionViewController: UIViewController {
message: Translation.CompetitorView.CheckOutAlert.Message.String,
preferredStyle: .alert
)
let yesAction = UIAlertAction(title: Translation.Common.Yes.String, style: .default) { (action) in
self.delegate.performCheckOut()
let yesAction = UIAlertAction(title: Translation.Common.Yes.String, style: .default) { [weak self] action in
self?.delegate.performCheckOut()
}
let noAction = UIAlertAction(title: Translation.Common.No.String, style: .cancel, handler: nil)
alertController.addAction(yesAction)
@@ -82,13 +82,13 @@ class SessionViewController: UIViewController {
message: "WIFI IS ON BUT NOT CONNECTED",
preferredStyle: .alert
)
let settingsAction = UIAlertAction(title: Translation.Common.Settings.String, style: .default) { (action) in
let settingsAction = UIAlertAction(title: Translation.Common.Settings.String, style: .default) { action in
if let settingsURL = URL(string: "prefs:root=WIFI") {
UIApplication.shared.openURL(settingsURL)
}
}
let okAction = UIAlertAction(title: Translation.Common.OK.String, style: .default) { (action) in
self.startTracking()
let okAction = UIAlertAction(title: Translation.Common.OK.String, style: .default) { [weak self] action in
self?.startTracking()
}
let cancelAction = UIAlertAction(title: Translation.Common.Cancel.String, style: .cancel, handler: nil)
alertController.addAction(settingsAction)
@@ -103,7 +103,7 @@ class SessionViewController: UIViewController {
message: message,
preferredStyle: .alert
)
let settingsAction = UIAlertAction(title: Translation.Common.Settings.String, style: .default) { (action) in
let settingsAction = UIAlertAction(title: Translation.Common.Settings.String, style: .default) { action in
if let locationServiceURL = URL(string: "prefs:root=LOCATION_SERVICES") {
UIApplication.shared.openURL(locationServiceURL)
}
@@ -21,7 +21,7 @@ extension SignUpControllerError: LocalizedError {
}
}
@objc protocol SignUpControllerDelegate {
@objc protocol SignUpControllerDelegate: class {
func signUpControllerDidFinish(_ controller: SignUpController)
@@ -31,7 +31,7 @@ extension SignUpControllerError: LocalizedError {
class SignUpController: NSObject {
var delegate: SignUpControllerDelegate?
weak var delegate: SignUpControllerDelegate?
fileprivate let requestManager = SignUpRequestManager(baseURLString: "https://dev.sapsailing.com")
@@ -42,7 +42,7 @@ protocol SignUpViewControllerDelegate {
class SignUpViewController: FormularViewController {
var signUpController: SignUpController?
weak var signUpController: SignUpController?
@IBOutlet weak var infoLabel: UILabel!
@IBOutlet weak var errorLabel: UILabel!
@@ -15,36 +15,53 @@ class TimerViewController: UIViewController {
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var timeLabel: UILabel!
weak var timer: Timer?
override func viewDidLoad() {
super.viewDidLoad()
setup()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
validateTimer()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
invalidateTimer()
}
// MARK: - Timer
fileprivate func validateTimer() {
timer = Timer.scheduledTimer(
timeInterval: 0.1,
target: self,
selector: #selector(tickTimer),
userInfo: nil,
repeats: true
)
tickTimer()
}
fileprivate func invalidateTimer() {
timer?.invalidate()
}
// MARK: - Setup
fileprivate func setup() {
setupLocalization()
setupTimer()
}
fileprivate func setupLocalization() {
titleLabel.text = Translation.TimerView.TitleLabel.Text.String
}
fileprivate func setupTimer() {
let timer = Timer(
timeInterval: 0.1,
target: self,
selector: #selector(tick),
userInfo: nil,
repeats: true
)
RunLoop.current.add(timer, forMode: RunLoopMode.commonModes)
}
// MARK: - Timer
@objc fileprivate func tick(_ timer: Timer) {
@objc fileprivate func tickTimer() {
let currentDate = Date()
let timeInterval = currentDate.timeIntervalSince(startDate)
let timerDate = Date(timeIntervalSince1970: timeInterval)
@@ -10,8 +10,8 @@ import Foundation
class TrackingViewController : UIViewController {
var checkIn: CheckIn!
var sessionController: SessionController!
weak var checkIn: CheckIn!
weak var sessionController: SessionController!
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var tableViewHeight: NSLayoutConstraint!
@@ -56,12 +56,12 @@ class TrackingViewController : UIViewController {
message: Translation.TrackingView.StopTrackingAlert.Message.String,
preferredStyle: .alert
)
let okAction = UIAlertAction(title: Translation.Common.OK.String, style: .default) { action in
let okAction = UIAlertAction(title: Translation.Common.OK.String, style: .default) { [weak self] action in
LocationManager.sharedManager.stopTracking()
SVProgressHUD.show()
self.sessionController.gpsFixController.sendAll(completion: { (withSuccess) in
self?.sessionController.gpsFixController.sendAll(completion: { (withSuccess) in
SVProgressHUD.popActivity()
self.dismiss(animated: true, completion: nil)
self?.dismiss(animated: true, completion: nil)
})
}
let cancelAction = UIAlertAction(title: Translation.Common.Cancel.String, style: .cancel, handler: nil)
@@ -10,7 +10,7 @@ import UIKit
class TrackingViewGPSFixesCell: UITableViewCell {
var checkIn: CheckIn?
weak var checkIn: CheckIn?
@IBOutlet weak var gpsFixesTitleLabel: UILabel!
@IBOutlet weak var gpsFixesLabel: UILabel!