Swift and enums #1

:  ~ 1 min read

This will only work for enums that are Ints, start from 0, and increment by 1 - for example tableView / collectionView sections, but I think it's a nice little trick that I always use:

private enum Section: Int {

  case products
  case shippingDetails
  case paymentDetails
  case totalValue
  case numberOfSections
}

Now you can do the following:

func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
  return Section.numberOfSections.rawValue
}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
  let cell: UICollectionViewCell

  // Since numberOfSections returns Section.numberOfSections,
  // it's safe to force unwrap here; it will never crash.
  switch Section(rawValue: indexPath.section)! {
    case .products: [...]
    case .shippingDetails: [...]
    case .paymentDetails: [...]
    case .totalValue: [...]
    // Now comes the downside: either do a default case,
    // either add the .numberOfSections case, both of which
    // do nothing, but I think it's worth the minor inconvenience.
    case .numberOfSections // default:
    assert(false, "Switches must be exhaustive in Swift.")
  }
}

Then, in the future, if the requirements change, and you need the paymentDetails section to be second, you don't have to remember which index it was and make sure you change it accordingly in didSelectItemAtIndexPath, as well - just move it in front of shippingDetails inside the enum declaration. Or, if you need to add / remove a section, you don't need to remember to update numberOfSections, it will continue work by itself.