This is the Swift code from one of the view controllers in my app that calculates a one rep maximum weight a person can theoretically lift. This particular view controller presents a list in a tableView of all types of lifts a user can choose from to set as a default preference. When the user selects a lift name, the refresh()
method is called which places a checkmark on that selected item. The selected lift name is then set as the new default value and will be included in the lift log if the user chooses to save it (in another view).
I'm a beginner programmer and new to Swift. This code works, but there are a couple of areas that just don't feel right:
- the
refresh()
function: I struggled to figure out a way to set the upper range in the for loop. Below is the only thing I got to work. - I didn't explicitly adopt the
UITableViewDataSource
orUITableViewDelegate
protocols which I have to have specified, yet it still works. I haven't been able to figure out why.
I'd appreciate any critiques and suggestions anybody has for me.
import UIKit
import CoreData
class LiftsTableViewController: UITableViewController, NSFetchedResultsControllerDelegate {
var coreDataStack = CoreDataStack()
var lifts = [Lift]()
var preferredLift: String?
func refresh() {
let allLifts = self.fetchedResultsController
for index in 0 ... (allLifts.fetchedObjects?.count ?? 0 ) {
let indexPath = NSIndexPath(forItem: index, inSection: 0)
if let cell = tableView.cellForRowAtIndexPath(indexPath) {
let currentLift = cell.textLabel?.text
cell.accessoryType = preferredLift == currentLift ? .Checkmark : .None
}
}
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
refresh()
}
override func viewDidLoad() {
super.viewDidLoad()
let userDefaults = NSUserDefaults.standardUserDefaults()
let lift = userDefaults.objectForKey("preferredLift") as! String?
if(lift != nil) {
self.preferredLift = lift
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// MARK: - Table view data source
lazy var fetchedResultsController : NSFetchedResultsController = {
let request = NSFetchRequest()
let entity = NSEntityDescription.entityForName("Lift",
inManagedObjectContext:self.coreDataStack.managedObjectContext)
request.entity = entity
request.fetchBatchSize = 20
let sortDescriptor = NSSortDescriptor(key:"liftName", ascending:true)
request.sortDescriptors = [sortDescriptor]
let afrc = NSFetchedResultsController(fetchRequest:request,
managedObjectContext:self.coreDataStack.managedObjectContext,
sectionNameKeyPath:nil, cacheName:"Lifts")
afrc.delegate = self
do {
try afrc.performFetch()
} catch {
print("Unresolved error \(error)")
fatalError("Aborting with unresolved error")
}
return afrc
}()
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let sectionInfo = self.fetchedResultsController.sections![section]
return sectionInfo.numberOfObjects
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("liftsCell", forIndexPath: indexPath)
let object = self.fetchedResultsController.objectAtIndexPath(indexPath) as! Lift
cell.textLabel?.text = object.liftName
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
guard let object = self.fetchedResultsController.objectAtIndexPath(indexPath) as? Lift else {
return
}
let selectedLift = object.liftName as String
savePreferences(selectedLift)
refresh()
}
func savePreferences(lift: AnyObject) {
let userDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.setObject(lift, forKey: "preferredLift")
preferredLift = lift as? String
}
}