Ok, so Swift is the new kid on the block. I love the new enums, and the fact that methods now can return tuplets (multiple return values). A cool example is a pull down meny with four buttons for sorting a table with contacts. Say you want to be able to sort them by first name, last name and ascending or descending respectively. A neat set of combinations there, right? With an enum you can easily setup a way to store the alternatives, and even better, since enums, structs et al. now can have methods associated with them (and methods can return tuplets), you can store all the logic related to translating a button press of the sorting alternatives, to a Core Data Predicate Search term (like “firstName”, “lastName”) combined with a boolean for the sort order. Sweet! So here is an example of a enum class for sorting contacts:
1 2 |
enum PickedSorting: Int { case FirstNameAscending, FirstNameDescending, LastNameAscending, LastNameDescending |
An Int enum in swift specifies a couple of cases. If not specifically set these cases start from 0 and increment just like the enums we know from ObjC. So how to use this enum? Have a look at this list:
This particular list has simple UIButtons in it with their Interface Builder “tag” set from 0 to 3, thereby corresponding to the enum we declared above. All buttons connected to the same sortButtonPress: – method:
1 2 3 4 5 6 7 8 9 10 11 |
@IBAction func sortButtonPress(sender: AnyObject) { var tag: Int = sender.tag! if let pickedSorting: PickedSorting = PickedSorting.fromRaw(tag) { self.currentSorting = pickedSorting self.fixButtonTitles() if let returnBlock = self.sortReturnBlock { returnBlock(pickedSorting: self.currentSorting) } } } |
The highlighted line comprise a few nefty Swift features. First the conditional assignment if let which assigns the value to pickedSorting, should the value exist. Every enum has a .fromRaw(value) method to convert, in this case, an integer to an enum value. So with this method we have a way to store the selection of the sorting in an enum. What’s new in Swift is the ability to associate methods to enums (and structs et al.). In this way you can easily convert your enum to something more useful, like in this case a tuplet to match the requirements needed to create a sort predicate to Core Data. Let’s have a look at the full enum:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
enum PickedSorting: Int { case FirstNameAscending, FirstNameDescending, LastNameAscending, LastNameDescending func toCoreDataKey() -> (String, Bool) { switch self { case .FirstNameAscending: return ("firstName", true) case .FirstNameDescending: return ("firstName", false) case .LastNameAscending: return ("lastName", true) case .LastNameDescending: return ("lastName", false) } } } |
What this toCoreDataKey-method returns is a predicate key “firstName” or “lastName” combined with a boolean value to represent whether or not the sorting should be ascending or descending. Why is this useful? Well, by making an enum implement relevant methods the code stays in one place. Here is how the predicate is created:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
func updateSorting() { let (sortKey, sortOrder) = self.pickedSorting.toCoreDataKey() let sortDescriptor = NSSortDescriptor(key: sortKey, ascending: sortOrder) let sortDescriptors = [sortDescriptor] self.fetchedResultsController.fetchRequest.sortDescriptors = sortDescriptors var fetchError: NSError? = nil self.fetchedResultsController.performFetch(&fetchError) if let error = fetchError { println("Error sorting array") } self.tableView.reloadData() } |
So, instead of littering your code with switch-statements to handle ascending and descending cases where ever you need sorting, a simple method call to the enum returns a tuplet containing both the boolean for the sort order, together with the sortKey for the listing. A really sweet usage of both enum methods and tuplets. Me like!
A simple example maybe, but I think it shows the possibilities of these awesome new features of Swift in a great way…
Please leave a comment if this is useful…