From 446683b03a252b216228ede62ecb770b0f0acab9 Mon Sep 17 00:00:00 2001 From: Pratik Gandhi Date: Thu, 13 Apr 2017 00:14:58 +0530 Subject: [PATCH 1/2] Added Swift 3 Support. --- MegaController.xcodeproj/project.pbxproj | 6 +++ MegaController/AddCompletionSegue.swift | 8 +-- MegaController/AddPresentationSegue.swift | 26 +++++----- MegaController/AddViewController.swift | 10 ++-- MegaController/AppDelegate.swift | 4 +- MegaController/Base.lproj/Main.storyboard | 46 +++++++--------- MegaController/CoreDataStore.swift | 20 +++---- MegaController/ImminentDueDatePredicate.swift | 4 +- MegaController/NavigationController.swift | 4 +- MegaController/NavigationTheme.swift | 34 ++++++------ .../RelativeTimeDateFormatter.swift | 32 +++++++----- MegaController/Task.swift | 8 +-- MegaController/TaskTableViewCell.swift | 8 +-- MegaController/UINavigationBar+Theme.swift | 2 +- MegaController/UpcomingTaskDataManager.swift | 52 +++++++++---------- ...omingTaskDataManagerTableViewAdapter.swift | 36 ++++++------- MegaController/UpcomingTaskResultsCache.swift | 26 +++++----- MegaController/UpcomingTaskSection.swift | 24 ++++----- MegaController/ViewController.swift | 10 ++-- .../ImminentDueDateTests.swift | 10 ++-- .../NavigationThemeTests.swift | 6 +-- .../RelativeTimeDateFormatterTests.swift | 10 ++-- .../UpcomingTaskResultsCacheTests.swift | 20 +++---- .../UpcomiungTaskSectionTests.swift | 20 +++---- 24 files changed, 216 insertions(+), 210 deletions(-) diff --git a/MegaController.xcodeproj/project.pbxproj b/MegaController.xcodeproj/project.pbxproj index 36cce5e..464f7e3 100644 --- a/MegaController.xcodeproj/project.pbxproj +++ b/MegaController.xcodeproj/project.pbxproj @@ -208,9 +208,11 @@ TargetAttributes = { 614991B91B9E3D9A005278F8 = { CreatedOnToolsVersion = 7.0; + LastSwiftMigration = 0820; }; 614991D01B9E3D9A005278F8 = { CreatedOnToolsVersion = 7.0; + LastSwiftMigration = 0820; TestTargetID = 614991B91B9E3D9A005278F8; }; }; @@ -413,6 +415,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = org.andymatuschak.MegaController; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -424,6 +427,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = org.andymatuschak.MegaController; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Release; }; @@ -438,6 +442,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "MegaControllerTests/MegaControllerTests-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MegaController.app/MegaController"; }; name = Debug; @@ -452,6 +457,7 @@ PRODUCT_BUNDLE_IDENTIFIER = org.andymatuschak.MegaControllerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "MegaControllerTests/MegaControllerTests-Bridging-Header.h"; + SWIFT_VERSION = 3.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MegaController.app/MegaController"; }; name = Release; diff --git a/MegaController/AddCompletionSegue.swift b/MegaController/AddCompletionSegue.swift index 360158c..b036efa 100644 --- a/MegaController/AddCompletionSegue.swift +++ b/MegaController/AddCompletionSegue.swift @@ -13,11 +13,11 @@ class AddCompletionSegue: UIStoryboardSegue { return addViewController.taskTitle } - var taskDueDate: NSDate { - return addViewController.taskDueDate + var taskDueDate: Date { + return addViewController.taskDueDate as Date } - private var addViewController: AddViewController { - return sourceViewController as! AddViewController + fileprivate var addViewController: AddViewController { + return source as! AddViewController } } diff --git a/MegaController/AddPresentationSegue.swift b/MegaController/AddPresentationSegue.swift index 3825808..12d61aa 100644 --- a/MegaController/AddPresentationSegue.swift +++ b/MegaController/AddPresentationSegue.swift @@ -11,32 +11,32 @@ import UIKit class AddPresentationSegue: UIStoryboardSegue, UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning { override func perform() { - destinationViewController.modalPresentationStyle = .OverFullScreen - destinationViewController.transitioningDelegate = self + destination.modalPresentationStyle = .overFullScreen + destination.transitioningDelegate = self super.perform() } - func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? { + func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { return self } - func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { + func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { return self } - func animateTransition(transitionContext: UIViewControllerContextTransitioning) { - if transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey) is AddViewController { - let addView = transitionContext.viewForKey(UITransitionContextToViewKey) + func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { + if transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) is AddViewController { + let addView = transitionContext.view(forKey: UITransitionContextViewKey.to) addView!.alpha = 0 - transitionContext.containerView()!.addSubview(addView!) - UIView.animateWithDuration(0.4, animations: { + transitionContext.containerView.addSubview(addView!) + UIView.animate(withDuration: 0.4, animations: { addView!.alpha = 1.0 }, completion: { didComplete in transitionContext.completeTransition(didComplete) }) - } else if transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey) is AddViewController { - let addView = transitionContext.viewForKey(UITransitionContextFromViewKey) - UIView.animateWithDuration(0.4, animations: { + } else if transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from) is AddViewController { + let addView = transitionContext.view(forKey: UITransitionContextViewKey.from) + UIView.animate(withDuration: 0.4, animations: { addView!.alpha = 0.0 }, completion: { didComplete in transitionContext.completeTransition(didComplete) @@ -44,7 +44,7 @@ class AddPresentationSegue: UIStoryboardSegue, UIViewControllerTransitioningDele } } - func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval { + func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { return 0.4 } } diff --git a/MegaController/AddViewController.swift b/MegaController/AddViewController.swift index 8469449..c2fd990 100644 --- a/MegaController/AddViewController.swift +++ b/MegaController/AddViewController.swift @@ -14,15 +14,15 @@ class AddViewController: UIViewController { return textField.text! } - var taskDueDate: NSDate { + var taskDueDate: Date { return datePicker.date } - @IBOutlet private weak var textField: UITextField! - @IBOutlet private weak var datePicker: UIDatePicker! + @IBOutlet fileprivate weak var textField: UITextField! + @IBOutlet fileprivate weak var datePicker: UIDatePicker! - override func viewWillAppear(animated: Bool) { + override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) textField.becomeFirstResponder() } -} \ No newline at end of file +} diff --git a/MegaController/AppDelegate.swift b/MegaController/AppDelegate.swift index ffe61f5..7add653 100644 --- a/MegaController/AppDelegate.swift +++ b/MegaController/AppDelegate.swift @@ -18,10 +18,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } lazy var primaryViewController: ViewController = { - return UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("Primary") as! ViewController + return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "Primary") as! ViewController }() - func applicationDidFinishLaunching(application: UIApplication) { + func applicationDidFinishLaunching(_ application: UIApplication) { primaryViewController.navigationThemeDidChangeHandler = { [weak self] theme in if let navigationController = self?.navigationController { navigationController.navigationBar.applyTheme(theme) diff --git a/MegaController/Base.lproj/Main.storyboard b/MegaController/Base.lproj/Main.storyboard index 97882c9..666af05 100644 --- a/MegaController/Base.lproj/Main.storyboard +++ b/MegaController/Base.lproj/Main.storyboard @@ -1,47 +1,46 @@ - + + + + - + + - - + + - - + - + - + - - @@ -70,15 +69,14 @@ - + - + - @@ -91,13 +89,11 @@ - - @@ -107,15 +103,13 @@ - - + - - + @@ -134,8 +128,7 @@ - - + @@ -158,7 +151,6 @@ - diff --git a/MegaController/CoreDataStore.swift b/MegaController/CoreDataStore.swift index 3fbd023..9f05c7e 100644 --- a/MegaController/CoreDataStore.swift +++ b/MegaController/CoreDataStore.swift @@ -10,21 +10,21 @@ import CoreData import Foundation class CoreDataStore { - private lazy var applicationDocumentsDirectory: NSURL = { - let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask) + fileprivate lazy var applicationDocumentsDirectory: URL = { + let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) return urls[urls.count-1] }() - private lazy var managedObjectModel: NSManagedObjectModel = { - let modelURL = NSBundle.mainBundle().URLForResource("MegaController", withExtension: "momd")! - return NSManagedObjectModel(contentsOfURL: modelURL)! + fileprivate lazy var managedObjectModel: NSManagedObjectModel = { + let modelURL = Bundle.main.url(forResource: "MegaController", withExtension: "momd")! + return NSManagedObjectModel(contentsOf: modelURL)! }() - private lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = { + fileprivate lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = { let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel) - let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite") + let url = self.applicationDocumentsDirectory.appendingPathComponent("SingleViewCoreData.sqlite") do { - try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil) + try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: nil) } catch { fatalError("Couldn't load database: \(error)") } @@ -34,8 +34,8 @@ class CoreDataStore { lazy var managedObjectContext: NSManagedObjectContext = { let coordinator = self.persistentStoreCoordinator - var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType) + var managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType) managedObjectContext.persistentStoreCoordinator = coordinator return managedObjectContext }() -} \ No newline at end of file +} diff --git a/MegaController/ImminentDueDatePredicate.swift b/MegaController/ImminentDueDatePredicate.swift index 2b13801..9e0b107 100644 --- a/MegaController/ImminentDueDatePredicate.swift +++ b/MegaController/ImminentDueDatePredicate.swift @@ -9,7 +9,7 @@ import Foundation extension NSPredicate { - convenience init(forTasksWithinNumberOfDays numberOfDays: Int, ofDate date: NSDate, calendar: NSCalendar = NSCalendar.currentCalendar()) { - self.init(format: "dueDate <= %@", argumentArray: [calendar.dateByAddingUnit(.Day, value: numberOfDays, toDate: date, options: NSCalendarOptions())!]) + convenience init(forTasksWithinNumberOfDays numberOfDays: Int, ofDate date: Date, calendar: Calendar = Calendar.current) { + self.init(format: "dueDate <= %@", argumentArray: [(calendar as NSCalendar).date(byAdding: .day, value: numberOfDays, to: date, options: NSCalendar.Options())!]) } } diff --git a/MegaController/NavigationController.swift b/MegaController/NavigationController.swift index f417f1b..816437a 100644 --- a/MegaController/NavigationController.swift +++ b/MegaController/NavigationController.swift @@ -9,11 +9,11 @@ import UIKit class NavigationController: UINavigationController { - var statusBarStyle: UIStatusBarStyle = .Default { + var statusBarStyle: UIStatusBarStyle = .default { didSet { setNeedsStatusBarAppearanceUpdate() } } - override func preferredStatusBarStyle() -> UIStatusBarStyle { + override var preferredStatusBarStyle : UIStatusBarStyle { return statusBarStyle } } diff --git a/MegaController/NavigationTheme.swift b/MegaController/NavigationTheme.swift index 7b46ed7..92ce7fd 100644 --- a/MegaController/NavigationTheme.swift +++ b/MegaController/NavigationTheme.swift @@ -9,43 +9,43 @@ import UIKit enum NavigationTheme { - case Normal - case Warning - case Doomed + case normal + case warning + case doomed var statusBarStyle: UIStatusBarStyle { switch self { - case .Normal: return .Default - case .Warning, .Doomed: return .LightContent + case .normal: return .default + case .warning, .doomed: return .lightContent } } var barTintColor: UIColor? { switch self { - case .Normal: + case .normal: return nil - case .Warning: + case .warning: return UIColor(red: 235/255, green: 156/255, blue: 77/255, alpha: 1.0) - case .Doomed: + case .doomed: return UIColor(red: 248/255, green: 73/255, blue: 68/255, alpha: 1.0) } } var titleTextAttributes: [String: NSObject]? { switch self { - case .Normal: + case .normal: return nil - case .Warning, .Doomed: - return [NSForegroundColorAttributeName: UIColor.whiteColor()] + case .warning, .doomed: + return [NSForegroundColorAttributeName: UIColor.white] } } var tintColor: UIColor? { switch self { - case .Normal: + case .normal: return nil - case .Warning, .Doomed: - return UIColor.whiteColor() + case .warning, .doomed: + return UIColor.white } } } @@ -54,11 +54,11 @@ extension NavigationTheme { init(numberOfImminentTasks: Int) { switch numberOfImminentTasks { case -Int.max ... 3: - self = .Normal + self = .normal case 4...9: - self = .Warning + self = .warning default: - self = .Doomed + self = .doomed } } } diff --git a/MegaController/RelativeTimeDateFormatter.swift b/MegaController/RelativeTimeDateFormatter.swift index c0c4408..b819b00 100644 --- a/MegaController/RelativeTimeDateFormatter.swift +++ b/MegaController/RelativeTimeDateFormatter.swift @@ -8,20 +8,27 @@ import Foundation + +extension Date { + func numberOfDaysUntilDateTime(toDateTime: Date, calendar: Calendar) -> Int { + let fromDate = calendar.startOfDay(for: self) + let toDate = calendar.startOfDay(for: toDateTime) + let difference = calendar.dateComponents([.day], from: fromDate, to: toDate) + return difference.day! + } +} + struct RelativeTimeDateFormatter { - let calendar: NSCalendar - - init(calendar: NSCalendar = NSCalendar.autoupdatingCurrentCalendar()) { + let calendar: Calendar + + + init(calendar: Calendar = Calendar.autoupdatingCurrent) { self.calendar = calendar } - func stringForDate(date: NSDate, relativeToDate baseDate: NSDate) -> String { - var beginningOfDate: NSDate? = nil - var beginningOfBaseDate: NSDate? = nil - - calendar.rangeOfUnit(.Day, startDate: &beginningOfDate, interval: nil, forDate: date) - calendar.rangeOfUnit(.Day, startDate: &beginningOfBaseDate, interval: nil, forDate: baseDate) - let numberOfCalendarDaysBetweenDates = calendar.components(NSCalendarUnit.Day, fromDate: beginningOfBaseDate!, toDate: beginningOfDate!, options: NSCalendarOptions()).day + func stringForDate(date: Date, relativeToDate baseDate: Date) -> String { + + let numberOfCalendarDaysBetweenDates = baseDate.numberOfDaysUntilDateTime(toDateTime: date, calendar: calendar) switch numberOfCalendarDaysBetweenDates { case -Int.max ... -2: @@ -34,6 +41,7 @@ struct RelativeTimeDateFormatter { return "Tomorrow" default: return "In \(numberOfCalendarDaysBetweenDates) days" - } + } + } -} \ No newline at end of file +} diff --git a/MegaController/Task.swift b/MegaController/Task.swift index 60d2572..c99c15d 100644 --- a/MegaController/Task.swift +++ b/MegaController/Task.swift @@ -12,7 +12,7 @@ import Foundation struct Task: Equatable { var id: String var title: String - var dueDate: NSDate + var dueDate: Date } func ==(lhs: Task, rhs: Task) -> Bool { @@ -21,8 +21,8 @@ func ==(lhs: Task, rhs: Task) -> Bool { extension Task { init(managedTask: NSManagedObject) { - self.id = managedTask.valueForKey("id") as! String - self.title = managedTask.valueForKey("title") as! String - self.dueDate = managedTask.valueForKey("dueDate") as! NSDate + self.id = managedTask.value(forKey: "id") as! String + self.title = managedTask.value(forKey: "title") as! String + self.dueDate = managedTask.value(forKey: "dueDate") as! Date } } diff --git a/MegaController/TaskTableViewCell.swift b/MegaController/TaskTableViewCell.swift index 938e1c8..42d2ff5 100644 --- a/MegaController/TaskTableViewCell.swift +++ b/MegaController/TaskTableViewCell.swift @@ -17,15 +17,15 @@ class TaskTableViewCell: UITableViewCell { var viewData: ViewData? { didSet { textLabel!.text = viewData?.title - detailTextLabel!.text = viewData?.timingDescription.lowercaseString + detailTextLabel!.text = viewData?.timingDescription.lowercased() } } } extension TaskTableViewCell.ViewData { - init(task: Task, relativeToDate baseDate: NSDate) { + init(task: Task, relativeToDate baseDate: Date) { self.title = task.title - self.timingDescription = RelativeTimeDateFormatter().stringForDate(task.dueDate, relativeToDate: baseDate) + self.timingDescription = RelativeTimeDateFormatter().stringForDate(date: task.dueDate, relativeToDate: baseDate ) } -} \ No newline at end of file +} diff --git a/MegaController/UINavigationBar+Theme.swift b/MegaController/UINavigationBar+Theme.swift index ab3c482..51e4b7b 100644 --- a/MegaController/UINavigationBar+Theme.swift +++ b/MegaController/UINavigationBar+Theme.swift @@ -9,7 +9,7 @@ import UIKit extension UINavigationBar { - func applyTheme(navigationTheme: NavigationTheme) { + func applyTheme(_ navigationTheme: NavigationTheme) { barTintColor = navigationTheme.barTintColor tintColor = navigationTheme.tintColor titleTextAttributes = navigationTheme.titleTextAttributes diff --git a/MegaController/UpcomingTaskDataManager.swift b/MegaController/UpcomingTaskDataManager.swift index 3773762..ec30c44 100644 --- a/MegaController/UpcomingTaskDataManager.swift +++ b/MegaController/UpcomingTaskDataManager.swift @@ -10,7 +10,7 @@ import CoreData class UpcomingTaskDataManager: NSObject, NSFetchedResultsControllerDelegate { var taskSections: [Section] { - return resultsCache.sections.enumerate().map { index, tasks in + return resultsCache.sections.enumerated().map { index, tasks in return Section( title: UpcomingTaskSection(rawValue: index)!.title, items: tasks @@ -19,72 +19,72 @@ class UpcomingTaskDataManager: NSObject, NSFetchedResultsControllerDelegate { } var totalNumberOfTasks: Int { - return taskSections.map { $0.items.count }.reduce(0, combine: +) + return taskSections.map { $0.items.count }.reduce(0, +) } var delegate: UpcomingTaskDataManagerDelegate? - private let coreDataStore = CoreDataStore() - private var fetchedResultsController: NSFetchedResultsController - private var resultsCache: UpcomingTaskResultsCache + fileprivate let coreDataStore = CoreDataStore() + fileprivate var fetchedResultsController: NSFetchedResultsController + fileprivate var resultsCache: UpcomingTaskResultsCache override init() { - let fetchRequest = NSFetchRequest(entityName: "Task") + let fetchRequest = NSFetchRequest(entityName: "Task") fetchRequest.sortDescriptors = [NSSortDescriptor(key: "dueDate", ascending: true)] - fetchRequest.predicate = NSPredicate(forTasksWithinNumberOfDays: 10, ofDate: NSDate()) + fetchRequest.predicate = NSPredicate(forTasksWithinNumberOfDays: 10, ofDate: Date()) fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: coreDataStore.managedObjectContext, sectionNameKeyPath: nil, cacheName: nil) try! fetchedResultsController.performFetch() let managedTasks = fetchedResultsController.fetchedObjects! as! [NSManagedObject] - resultsCache = UpcomingTaskResultsCache(initialTasksSortedAscendingByDate: managedTasks.map { Task(managedTask: $0) }, baseDate: NSDate()) + resultsCache = UpcomingTaskResultsCache(initialTasksSortedAscendingByDate: managedTasks.map { Task(managedTask: $0) }, baseDate: Date()) super.init() fetchedResultsController.delegate = self } - func deleteTask(task: Task) { - coreDataStore.managedObjectContext.deleteObject(managedTaskForTask(task)) + func deleteTask(_ task: Task) { + coreDataStore.managedObjectContext.delete(managedTaskForTask(task)) try! coreDataStore.managedObjectContext.save() } - func createTaskWithTitle(title: String, dueDate: NSDate) { - let newTask = NSManagedObject(entity: coreDataStore.managedObjectContext.persistentStoreCoordinator!.managedObjectModel.entitiesByName["Task"]!, insertIntoManagedObjectContext: coreDataStore.managedObjectContext) - newTask.setValue(NSUUID().UUIDString, forKey: "id") + func createTaskWithTitle(_ title: String, dueDate: Date) { + let newTask = NSManagedObject(entity: coreDataStore.managedObjectContext.persistentStoreCoordinator!.managedObjectModel.entitiesByName["Task"]!, insertInto: coreDataStore.managedObjectContext) + newTask.setValue(UUID().uuidString, forKey: "id") newTask.setValue(title, forKey: "title") newTask.setValue(dueDate, forKey: "dueDate") try! coreDataStore.managedObjectContext.save() } - func controllerWillChangeContent(controller: NSFetchedResultsController) { + func controllerWillChangeContent(_ controller: NSFetchedResultsController) { delegate?.dataManagerWillChangeContent(self) } - func controllerDidChangeContent(controller: NSFetchedResultsController) { + func controllerDidChangeContent(_ controller: NSFetchedResultsController) { delegate?.dataManagerDidChangeContent(self) } - func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) { + func controller(_ controller: NSFetchedResultsController, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) { let task = Task(managedTask: anObject as! NSManagedObject) switch type { - case .Insert: + case .insert: let insertedIndexPath = resultsCache.insertTask(task) delegate?.dataManager(self, didInsertRowAtIndexPath: insertedIndexPath) - case .Delete: + case .delete: let deletedIndexPath = resultsCache.deleteTask(task) delegate?.dataManager(self, didDeleteRowAtIndexPath: deletedIndexPath) - case .Move, .Update: + case .move, .update: fatalError("Unsupported") } } - private func managedTaskForTask(task: Task) -> NSManagedObject { - let fetchRequest = NSFetchRequest(entityName: "Task") + fileprivate func managedTaskForTask(_ task: Task) -> NSManagedObject { + let fetchRequest = NSFetchRequest(entityName: "Task") fetchRequest.predicate = NSPredicate(format: "id == %@", argumentArray: [task.id]) fetchRequest.fetchLimit = 1 - let results = try! coreDataStore.managedObjectContext.executeFetchRequest(fetchRequest) as! [NSManagedObject] + let results = try! coreDataStore.managedObjectContext.fetch(fetchRequest) as! [NSManagedObject] return results.first! } } @@ -95,8 +95,8 @@ struct Section { } protocol UpcomingTaskDataManagerDelegate { - func dataManagerWillChangeContent(dataManager: UpcomingTaskDataManager) - func dataManagerDidChangeContent(dataManager: UpcomingTaskDataManager) - func dataManager(dataManager: UpcomingTaskDataManager, didInsertRowAtIndexPath indexPath: NSIndexPath) - func dataManager(dataManager: UpcomingTaskDataManager, didDeleteRowAtIndexPath indexPath: NSIndexPath) + func dataManagerWillChangeContent(_ dataManager: UpcomingTaskDataManager) + func dataManagerDidChangeContent(_ dataManager: UpcomingTaskDataManager) + func dataManager(_ dataManager: UpcomingTaskDataManager, didInsertRowAtIndexPath indexPath: IndexPath) + func dataManager(_ dataManager: UpcomingTaskDataManager, didDeleteRowAtIndexPath indexPath: IndexPath) } diff --git a/MegaController/UpcomingTaskDataManagerTableViewAdapter.swift b/MegaController/UpcomingTaskDataManagerTableViewAdapter.swift index 84d8243..61aa7c7 100644 --- a/MegaController/UpcomingTaskDataManagerTableViewAdapter.swift +++ b/MegaController/UpcomingTaskDataManagerTableViewAdapter.swift @@ -9,13 +9,13 @@ import UIKit class UpcomingTaskDataManagerTableViewAdapter: NSObject, UITableViewDataSource, UpcomingTaskDataManagerDelegate { - private let tableView: UITableView - private let upcomingTaskDataManager: UpcomingTaskDataManager - private let cellReuseIdentifier: String - private let cellConfigurationHandler: (CellType, Task) -> () - private let didChangeHandler: () -> Void + fileprivate let tableView: UITableView + fileprivate let upcomingTaskDataManager: UpcomingTaskDataManager + fileprivate let cellReuseIdentifier: String + fileprivate let cellConfigurationHandler: (CellType, Task) -> () + fileprivate let didChangeHandler: () -> Void - init(tableView: UITableView, upcomingTaskDataManager: UpcomingTaskDataManager, cellReuseIdentifier: String, cellConfigurationHandler: (CellType, Task) -> (), didChangeHandler: () -> Void) { + init(tableView: UITableView, upcomingTaskDataManager: UpcomingTaskDataManager, cellReuseIdentifier: String, cellConfigurationHandler: @escaping (CellType, Task) -> (), didChangeHandler: @escaping () -> Void) { self.tableView = tableView self.upcomingTaskDataManager = upcomingTaskDataManager self.cellReuseIdentifier = cellReuseIdentifier @@ -25,43 +25,43 @@ class UpcomingTaskDataManagerTableViewAdapter: NSObje super.init() } - func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { + func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { upcomingTaskDataManager.deleteTask(upcomingTaskDataManager.taskSections[indexPath.section].items[indexPath.row]) } - func numberOfSectionsInTableView(tableView: UITableView) -> Int { + func numberOfSections(in tableView: UITableView) -> Int { return upcomingTaskDataManager.taskSections.count } - func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? { + func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { return upcomingTaskDataManager.taskSections[section].title } - func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return upcomingTaskDataManager.taskSections[section].items.count } - func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let task = upcomingTaskDataManager.taskSections[indexPath.section].items[indexPath.row] - let cell = tableView.dequeueReusableCellWithIdentifier(cellReuseIdentifier, forIndexPath: indexPath) as! CellType + let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier, for: indexPath) as! CellType cellConfigurationHandler(cell, task) return cell } - func dataManagerWillChangeContent(dataManager: UpcomingTaskDataManager) { + func dataManagerWillChangeContent(_ dataManager: UpcomingTaskDataManager) { tableView.beginUpdates() } - func dataManagerDidChangeContent(dataManager: UpcomingTaskDataManager) { + func dataManagerDidChangeContent(_ dataManager: UpcomingTaskDataManager) { tableView.endUpdates() didChangeHandler() } - func dataManager(dataManager: UpcomingTaskDataManager, didInsertRowAtIndexPath indexPath: NSIndexPath) { - tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic) + func dataManager(_ dataManager: UpcomingTaskDataManager, didInsertRowAtIndexPath indexPath: IndexPath) { + tableView.insertRows(at: [indexPath], with: .automatic) } - func dataManager(dataManager: UpcomingTaskDataManager, didDeleteRowAtIndexPath indexPath: NSIndexPath) { - tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic) + func dataManager(_ dataManager: UpcomingTaskDataManager, didDeleteRowAtIndexPath indexPath: IndexPath) { + tableView.deleteRows(at: [indexPath], with: .automatic) } } diff --git a/MegaController/UpcomingTaskResultsCache.swift b/MegaController/UpcomingTaskResultsCache.swift index d29f2c3..1da136e 100644 --- a/MegaController/UpcomingTaskResultsCache.swift +++ b/MegaController/UpcomingTaskResultsCache.swift @@ -9,37 +9,37 @@ import Foundation struct UpcomingTaskResultsCache { - var sections: [[Task]] = Array(count: UpcomingTaskSection.numberOfSections, repeatedValue: []) - let baseDate: NSDate + var sections: [[Task]] = Array(repeating: [], count: UpcomingTaskSection.numberOfSections) + let baseDate: Date - init(initialTasksSortedAscendingByDate: [Task], baseDate: NSDate) { + init(initialTasksSortedAscendingByDate: [Task], baseDate: Date) { self.baseDate = baseDate for task in initialTasksSortedAscendingByDate { sections[sectionIndexForTask(task)].append(task) } } - mutating func insertTask(task: Task) -> NSIndexPath { + mutating func insertTask(_ task: Task) -> IndexPath { let insertedTaskDate = task.dueDate let sectionIndex = sectionIndexForTask(task) - let insertionIndex = sections[sectionIndex].indexOf { task in + let insertionIndex = sections[sectionIndex].index { task in let otherTaskDate = task.dueDate - return insertedTaskDate.compare(otherTaskDate) == .OrderedAscending + return insertedTaskDate.compare(otherTaskDate as Date) == .orderedAscending } ?? sections[sectionIndex].count - sections[sectionIndex].insert(task, atIndex: insertionIndex) + sections[sectionIndex].insert(task, at: insertionIndex) - return NSIndexPath(forRow: insertionIndex, inSection: sectionIndex) + return IndexPath(row: insertionIndex, section: sectionIndex) } - mutating func deleteTask(task: Task) -> NSIndexPath { + mutating func deleteTask(_ task: Task) -> IndexPath { let sectionIndex = sectionIndexForTask(task) - let deletedTaskIndex = sections[sectionIndex].indexOf(task)! - sections[sectionIndex].removeAtIndex(deletedTaskIndex) + let deletedTaskIndex = sections[sectionIndex].index(of: task)! + sections[sectionIndex].remove(at: deletedTaskIndex) - return NSIndexPath(forRow: deletedTaskIndex, inSection: sectionIndex) + return IndexPath(row: deletedTaskIndex, section: sectionIndex) } - private func sectionIndexForTask(task: Task) -> Int { + fileprivate func sectionIndexForTask(_ task: Task) -> Int { let dueDate = task.dueDate return UpcomingTaskSection(forTaskDueDate: dueDate, baseDate: baseDate).rawValue } diff --git a/MegaController/UpcomingTaskSection.swift b/MegaController/UpcomingTaskSection.swift index 46d80ae..13f961b 100644 --- a/MegaController/UpcomingTaskSection.swift +++ b/MegaController/UpcomingTaskSection.swift @@ -9,31 +9,31 @@ import Foundation enum UpcomingTaskSection: Int { - case Now - case Soon - case Upcoming + case now + case soon + case upcoming - init(forTaskDueDate date: NSDate, baseDate: NSDate, calendar: NSCalendar = NSCalendar.currentCalendar()) { - let numberOfDaysUntilTaskDueDate = calendar.components(NSCalendarUnit.Day, fromDate: baseDate, toDate: date, options: NSCalendarOptions()).day + init(forTaskDueDate date: Date, baseDate: Date, calendar: Calendar = Calendar.current) { + let numberOfDaysUntilTaskDueDate = (calendar as NSCalendar).components(NSCalendar.Unit.day, from: baseDate, to: date, options: NSCalendar.Options()).day! switch numberOfDaysUntilTaskDueDate { case -Int.max ... 2: - self = .Now + self = .now case 3...5: - self = .Soon + self = .soon default: - self = .Upcoming + self = .upcoming } } var title: String { switch self { - case .Now: return "Now" - case .Soon: return "Soon" - case .Upcoming: return "Upcoming" + case .now: return "Now" + case .soon: return "Soon" + case .upcoming: return "Upcoming" } } static var numberOfSections: Int { return 3 } -} \ No newline at end of file +} diff --git a/MegaController/ViewController.swift b/MegaController/ViewController.swift index 7431fd6..27e42b9 100644 --- a/MegaController/ViewController.swift +++ b/MegaController/ViewController.swift @@ -14,8 +14,8 @@ class ViewController: UITableViewController { return NavigationTheme(numberOfImminentTasks: upcomingTaskDataManager.totalNumberOfTasks) } - private let upcomingTaskDataManager = UpcomingTaskDataManager() - private var upcomingTaskDataManagerTableViewAdapter: UpcomingTaskDataManagerTableViewAdapter! + fileprivate let upcomingTaskDataManager = UpcomingTaskDataManager() + fileprivate var upcomingTaskDataManagerTableViewAdapter: UpcomingTaskDataManagerTableViewAdapter! override func viewDidLoad() { super.viewDidLoad() @@ -25,7 +25,7 @@ class ViewController: UITableViewController { upcomingTaskDataManager: upcomingTaskDataManager, cellReuseIdentifier: "Cell", cellConfigurationHandler: { cell, task in - cell.viewData = TaskTableViewCell.ViewData(task: task, relativeToDate: NSDate()) + cell.viewData = TaskTableViewCell.ViewData(task: task, relativeToDate: Date()) }, didChangeHandler: { [weak self] in self?.updateNavigationBar() } ) @@ -35,7 +35,7 @@ class ViewController: UITableViewController { updateNavigationBar() } - override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool { + override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { return true } @@ -43,7 +43,7 @@ class ViewController: UITableViewController { navigationThemeDidChangeHandler?(navigationTheme) } - @IBAction func unwindFromAddController(segue: AddCompletionSegue) { + @IBAction func unwindFromAddController(_ segue: AddCompletionSegue) { upcomingTaskDataManager.createTaskWithTitle(segue.taskTitle, dueDate: segue.taskDueDate) } } diff --git a/MegaControllerTests/ImminentDueDateTests.swift b/MegaControllerTests/ImminentDueDateTests.swift index 25823de..b9a84c3 100644 --- a/MegaControllerTests/ImminentDueDateTests.swift +++ b/MegaControllerTests/ImminentDueDateTests.swift @@ -10,16 +10,16 @@ import XCTest class ImminentDueDateTests: XCTestCase { - static let calendar = NSCalendar.currentCalendar() - static let referenceDate = NSDate(timeIntervalSinceReferenceDate: 0) + static let calendar = Calendar.current + static let referenceDate = Date(timeIntervalSinceReferenceDate: 0) static let oneDayPredicate = NSPredicate(forTasksWithinNumberOfDays: 1, ofDate: referenceDate, calendar: calendar) func testPredicateMatchesDatesWithinBounds() { - XCTAssertTrue(ImminentDueDateTests.oneDayPredicate.evaluateWithObject(["dueDate": NSDate(timeIntervalSinceReferenceDate: 1000)])) + XCTAssertTrue(ImminentDueDateTests.oneDayPredicate.evaluate(with: ["dueDate": Date(timeIntervalSinceReferenceDate: 1000)])) } func testPredicateDoesNotMatchFurtherDates() { - let twoDays = ImminentDueDateTests.calendar.dateByAddingUnit(.Day, value: 2, toDate: ImminentDueDateTests.referenceDate, options: NSCalendarOptions())! - XCTAssertFalse(ImminentDueDateTests.oneDayPredicate.evaluateWithObject(["dueDate": twoDays])) + let twoDays = (ImminentDueDateTests.calendar as NSCalendar).date(byAdding: .day, value: 2, to: ImminentDueDateTests.referenceDate, options: NSCalendar.Options())! + XCTAssertFalse(ImminentDueDateTests.oneDayPredicate.evaluate(with: ["dueDate": twoDays])) } } diff --git a/MegaControllerTests/NavigationThemeTests.swift b/MegaControllerTests/NavigationThemeTests.swift index 38dd516..820f4bc 100644 --- a/MegaControllerTests/NavigationThemeTests.swift +++ b/MegaControllerTests/NavigationThemeTests.swift @@ -11,14 +11,14 @@ import XCTest class NavigationThemeTests: XCTestCase { func testThemeForZeroTasks() { - XCTAssertEqual(NavigationTheme(numberOfImminentTasks: 0), NavigationTheme.Normal) + XCTAssertEqual(NavigationTheme(numberOfImminentTasks: 0), NavigationTheme.normal) } func testThemeForAFewTasks() { - XCTAssertEqual(NavigationTheme(numberOfImminentTasks: 4), NavigationTheme.Warning) + XCTAssertEqual(NavigationTheme(numberOfImminentTasks: 4), NavigationTheme.warning) } func testThemeForManyTasks() { - XCTAssertEqual(NavigationTheme(numberOfImminentTasks: 20), NavigationTheme.Doomed) + XCTAssertEqual(NavigationTheme(numberOfImminentTasks: 20), NavigationTheme.doomed) } } diff --git a/MegaControllerTests/RelativeTimeDateFormatterTests.swift b/MegaControllerTests/RelativeTimeDateFormatterTests.swift index ca4562d..3ba2a93 100644 --- a/MegaControllerTests/RelativeTimeDateFormatterTests.swift +++ b/MegaControllerTests/RelativeTimeDateFormatterTests.swift @@ -10,8 +10,8 @@ import XCTest class RelativeTimeDateFormatterTests: XCTestCase { - let calendar = NSCalendar.currentCalendar() - let baseDate = NSDate(timeIntervalSinceReferenceDate: 0) + let calendar = Calendar.current + let baseDate = Date(timeIntervalSinceReferenceDate: 0) var dateFormatter: RelativeTimeDateFormatter! override func setUp() { @@ -19,17 +19,17 @@ class RelativeTimeDateFormatterTests: XCTestCase { } func testTodayDate() { - let testDate = calendar.dateByAddingUnit(.Hour, value: 1, toDate: baseDate, options: NSCalendarOptions())! + let testDate = (calendar as NSCalendar).date(byAdding: .hour, value: 1, to: baseDate, options: NSCalendar.Options())! XCTAssertEqual(dateFormatter.stringForDate(testDate, relativeToDate: baseDate), "Today") } func testTomorrowDate() { - let testDate = calendar.dateByAddingUnit(.Day, value: 1, toDate: baseDate, options: NSCalendarOptions())! + let testDate = (calendar as NSCalendar).date(byAdding: .day, value: 1, to: baseDate, options: NSCalendar.Options())! XCTAssertEqual(dateFormatter.stringForDate(testDate, relativeToDate: baseDate), "Tomorrow") } func testLaterDate() { - let testDate = calendar.dateByAddingUnit(.Day, value: 4, toDate: baseDate, options: NSCalendarOptions())! + let testDate = (calendar as NSCalendar).date(byAdding: .day, value: 4, to: baseDate, options: NSCalendar.Options())! XCTAssertEqual(dateFormatter.stringForDate(testDate, relativeToDate: baseDate), "In 4 days") } } diff --git a/MegaControllerTests/UpcomingTaskResultsCacheTests.swift b/MegaControllerTests/UpcomingTaskResultsCacheTests.swift index b466c70..08a3dff 100644 --- a/MegaControllerTests/UpcomingTaskResultsCacheTests.swift +++ b/MegaControllerTests/UpcomingTaskResultsCacheTests.swift @@ -12,8 +12,8 @@ import XCTest class UpcomingTaskResultsCacheTests: XCTestCase { func testAddingAndDeletingTaskChangesNothing() { - let originalCache = UpcomingTaskResultsCache(initialTasksSortedAscendingByDate: [], baseDate: NSDate()) - let task = Task(id: "a", title: "task", dueDate: NSDate()) + let originalCache = UpcomingTaskResultsCache(initialTasksSortedAscendingByDate: [], baseDate: Date()) + let task = Task(id: "a", title: "task", dueDate: Date()) var testCache = originalCache testCache.insertTask(task) @@ -24,26 +24,26 @@ class UpcomingTaskResultsCacheTests: XCTestCase { } func testAddingTaskToEmptySection() { - var cache = UpcomingTaskResultsCache(initialTasksSortedAscendingByDate: [], baseDate: NSDate()) - let task = Task(id: "a", title: "task", dueDate: NSDate()) + var cache = UpcomingTaskResultsCache(initialTasksSortedAscendingByDate: [], baseDate: Date()) + let task = Task(id: "a", title: "task", dueDate: Date()) cache.insertTask(task) XCTAssertEqual(cache.sections[0][0], task) } func testAddingEarlierTaskToSection() { - let earlierTask = Task(id: "a", title: "earlier task", dueDate: NSDate(timeIntervalSinceReferenceDate: 0)) - let laterTask = Task(id: "b", title: "later task", dueDate: NSDate(timeIntervalSinceReferenceDate: 100)) + let earlierTask = Task(id: "a", title: "earlier task", dueDate: Date(timeIntervalSinceReferenceDate: 0)) + let laterTask = Task(id: "b", title: "later task", dueDate: Date(timeIntervalSinceReferenceDate: 100)) - var cache = UpcomingTaskResultsCache(initialTasksSortedAscendingByDate: [laterTask], baseDate: NSDate(timeIntervalSinceReferenceDate: 0)) + var cache = UpcomingTaskResultsCache(initialTasksSortedAscendingByDate: [laterTask], baseDate: Date(timeIntervalSinceReferenceDate: 0)) cache.insertTask(earlierTask) XCTAssertEqual(cache.sections[0], [earlierTask, laterTask]) } func testAddingLaterTaskToSection() { - let earlierTask = Task(id: "a", title: "earlier task", dueDate: NSDate(timeIntervalSinceReferenceDate: 0)) - let laterTask = Task(id: "b", title: "later task", dueDate: NSDate(timeIntervalSinceReferenceDate: 100)) + let earlierTask = Task(id: "a", title: "earlier task", dueDate: Date(timeIntervalSinceReferenceDate: 0)) + let laterTask = Task(id: "b", title: "later task", dueDate: Date(timeIntervalSinceReferenceDate: 100)) - var cache = UpcomingTaskResultsCache(initialTasksSortedAscendingByDate: [earlierTask], baseDate: NSDate(timeIntervalSinceReferenceDate: 0)) + var cache = UpcomingTaskResultsCache(initialTasksSortedAscendingByDate: [earlierTask], baseDate: Date(timeIntervalSinceReferenceDate: 0)) cache.insertTask(laterTask) XCTAssertEqual(cache.sections[0], [earlierTask, laterTask]) } diff --git a/MegaControllerTests/UpcomiungTaskSectionTests.swift b/MegaControllerTests/UpcomiungTaskSectionTests.swift index 617ddc8..4e02c0f 100644 --- a/MegaControllerTests/UpcomiungTaskSectionTests.swift +++ b/MegaControllerTests/UpcomiungTaskSectionTests.swift @@ -12,21 +12,21 @@ import XCTest class UpcomiungTaskSectionTests: XCTestCase { func testTaskAtBaseDateIsInNowSection() { - let testDate = NSDate() - XCTAssertEqual(UpcomingTaskSection(forTaskDueDate: testDate, baseDate: testDate), UpcomingTaskSection.Now) + let testDate = Date() + XCTAssertEqual(UpcomingTaskSection(forTaskDueDate: testDate, baseDate: testDate), UpcomingTaskSection.now) } func testTaskInSeveralDaysIsInSoonSection() { - let baseDate = NSDate() - let calendar = NSCalendar.currentCalendar() - let soonDate = calendar.dateByAddingUnit(.Day, value: 3, toDate: baseDate, options: NSCalendarOptions())! - XCTAssertEqual(UpcomingTaskSection(forTaskDueDate: soonDate, baseDate: baseDate, calendar: calendar), UpcomingTaskSection.Soon) + let baseDate = Date() + let calendar = Calendar.current + let soonDate = (calendar as NSCalendar).date(byAdding: .day, value: 3, to: baseDate, options: NSCalendar.Options())! + XCTAssertEqual(UpcomingTaskSection(forTaskDueDate: soonDate, baseDate: baseDate, calendar: calendar), UpcomingTaskSection.soon) } func testTaskInManyDaysIsInUpcomingSection() { - let baseDate = NSDate() - let calendar = NSCalendar.currentCalendar() - let upcomingDate = calendar.dateByAddingUnit(.Day, value: 10, toDate: baseDate, options: NSCalendarOptions())! - XCTAssertEqual(UpcomingTaskSection(forTaskDueDate: upcomingDate, baseDate: baseDate, calendar: calendar), UpcomingTaskSection.Upcoming) + let baseDate = Date() + let calendar = Calendar.current + let upcomingDate = (calendar as NSCalendar).date(byAdding: .day, value: 10, to: baseDate, options: NSCalendar.Options())! + XCTAssertEqual(UpcomingTaskSection(forTaskDueDate: upcomingDate, baseDate: baseDate, calendar: calendar), UpcomingTaskSection.upcoming) } } From 5bcff345f6d19f1d545069e8eb9ffdacde5326a5 Mon Sep 17 00:00:00 2001 From: Pratik Gandhi Date: Thu, 13 Apr 2017 12:21:12 +0530 Subject: [PATCH 2/2] Added swift 3 support for test targets. --- MegaControllerTests/RelativeTimeDateFormatterTests.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MegaControllerTests/RelativeTimeDateFormatterTests.swift b/MegaControllerTests/RelativeTimeDateFormatterTests.swift index 3ba2a93..e861938 100644 --- a/MegaControllerTests/RelativeTimeDateFormatterTests.swift +++ b/MegaControllerTests/RelativeTimeDateFormatterTests.swift @@ -20,16 +20,16 @@ class RelativeTimeDateFormatterTests: XCTestCase { func testTodayDate() { let testDate = (calendar as NSCalendar).date(byAdding: .hour, value: 1, to: baseDate, options: NSCalendar.Options())! - XCTAssertEqual(dateFormatter.stringForDate(testDate, relativeToDate: baseDate), "Today") + XCTAssertEqual(dateFormatter.stringForDate(date: testDate, relativeToDate: baseDate), "Today") } func testTomorrowDate() { let testDate = (calendar as NSCalendar).date(byAdding: .day, value: 1, to: baseDate, options: NSCalendar.Options())! - XCTAssertEqual(dateFormatter.stringForDate(testDate, relativeToDate: baseDate), "Tomorrow") + XCTAssertEqual(dateFormatter.stringForDate(date: testDate, relativeToDate: baseDate), "Tomorrow") } func testLaterDate() { let testDate = (calendar as NSCalendar).date(byAdding: .day, value: 4, to: baseDate, options: NSCalendar.Options())! - XCTAssertEqual(dateFormatter.stringForDate(testDate, relativeToDate: baseDate), "In 4 days") + XCTAssertEqual(dateFormatter.stringForDate(date: testDate, relativeToDate: baseDate), "In 4 days") } }