samedi 25 juin 2016

Mapping between array of enums and a dictionary of enums

Here's what I'm trying to do: Provide a tableView that allows the user to select a formula name (an enum) that will be set as their default In this view I'll place a checkmark next to the formula that is the current default Their chosen default formula is what will determine which formula is used to calculate a 1 rep maximum amount (the theoretical amount the user could lift based on actual lifts of lesser weight) After calculating the value, the user will be able to save a record of the lifts they did, the formula used to calculate the maximum, and the calculated maximum weight. That record will be saved in Core Data with one of the entities being Lift which will simply be the formula name I've created a class that I want to handle the work of providing the current default formula to what ever part of the app needs it as well as set the default when a new one is selected. Here is my enum of the formula names: enum CalculationFormula: Int { case Epley case Brzychi case Baechle case Lander case Lombardi case MayhewEtAl case OConnerEtAl } and with help from the SO community, I created this class to handle the management of userDefaults: class UserDefaultsManager: NSUserDefaults { let formulas = [CalculationFormula.Baechle, CalculationFormula.Brzychi, CalculationFormula.Epley, CalculationFormula.Lander, CalculationFormula.Lombardi, CalculationFormula.MayhewEtAl, CalculationFormula.OConnerEtAl] let formulaNameDictionary: [CalculationFormula : String] = [.Epley : "Epley", .Brzychi: "Brzychi", .Baechle: "Baechle", .Lander: "Lander", .Lombardi: "Lombardi", .MayhewEtAl: "Mayhew Et.Al.", .OConnerEtAl: "O'Conner Et.Al"] let userDefaults = NSUserDefaults.standardUserDefaults() func getPreferredFormula() -> CalculationFormula? { guard NSUserDefaults.standardUserDefaults().dictionaryRepresentation().keys.contains("selectedFormula") else { print("No value found") return nil } guard let preferredFormula = CalculationFormula(rawValue: NSUserDefaults.standardUserDefaults().integerForKey("selectedFormula")) else { print("Wrong value found") return nil } return preferredFormula } func setPreferredFormula(formula: CalculationFormula) { NSUserDefaults.standardUserDefaults().setInteger(formula.rawValue, forKey: "selectedFormula") } You can see I have an array of the enums in the order I want them displayed in the tableView and a dictionary of the enums so I can get each enum's string representation to display in each cell of the tableView. Here's how I populate the cell text label which works: override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("formulasCell", forIndexPath: indexPath) let currentFormula = formulas[indexPath.row].formulaName cell.textLabel?.text = currentFormula return cell } and here's where I'm setting the checkmark anytime a cell in the tableView is selected func refresh() { let preferredFormula = defaults.getPreferredFormula() for index in 0 ... formulas.count { let indexPath = NSIndexPath(forItem: index, inSection: 0) if let cell = tableView.cellForRowAtIndexPath(indexPath) { cell.accessoryType = preferredFormula == index ? .Checkmark : .None } } } As I mentioned at the beginning, I need to do many different things with this enum but to keep this question focused on one thing, I'll stay with this checkmark example which now doesn't work after creating my UserDefaultsManager class The problem is obvious - preferredFormula is now an enum and I can't compare that to the index value which is an Int - but the solution is not. I could get the raw value of the enum but the rawValues aren't guaranteed to be in alignment with the cell indexPaths. Some ideas I've had are: I could probably change the order of the enum cases so their raw values match the order I've put them in my formulas array, but that seems silly and unreliable I could use the array index values but that seems equally silly and unreliable If I just use the array, I don't have the string representations of the cases to display in the cells It seems that using the array and dictionary together is a viable but the best I could come up with is maybe creating another dictionary that maps the enums to Ints but that would have the same issues I just listed. Any guidance someone could provide would be greatly appreciated.

Aucun commentaire:

Enregistrer un commentaire