Ali Mir Ali Mir - 5 months ago 21
Swift Question

Sort arrays of protocols in Swift?

I have a lot of arrays stored in a ViewController of the following:

protocol AlarmClockType {
var alarmLabel: String { get set }
var sound: AlarmSound { get set }
var snooze: Bool { get set }
var alarmType: AlarmType { get set }
var alarmOn: Bool { get set }
var alarm: NSTimer? { get set }
var attributedTitle: NSMutableAttributedString { get }

static var DocumentsDirectory: NSURL { get }
static var ArchiveURL: NSURL { get }

func timeToAlarm(prayerTimes: [String: String]?) -> NSDate

Each instance has a property alarmTime (which is NSDate). How can I sort the array based on time?

To make it more clear:

It's a TableViewController and the cells display alarm times. Each time the user adds an alarm, the tableView should be sorted by alarm times.


If you want to sort an array by dates, it's probably better if you use a custom data structure that includes an NSDate.

For example, you can create a struct that has properties for your data.

struct Alarm {
    var alarmTime: NSDate = NSDate()
    var description: String = ""

This struct can be used to create an array.

let alarms = [
    Alarm(alarmTime: NSDate().dateByAddingTimeInterval(120),
          description: "alarm 60 s in the future"), 
    Alarm(alarmTime: NSDate().dateByAddingTimeInterval(30),
           description: "alarm 30 s in the future"), 
    Alarm(alarmTime: NSDate().dateByAddingTimeInterval(90),
          description: "alarm 90 s in the future")

The array can be sorted using the sort function and some special syntax for handling NSDates.

let sortedAlarms = alarms.sort(
    { $$1.alarmTime) == NSComparisonResult.OrderedAscending }

Finally, in this example, sortedAlarms contains everything in alarms but it is sorted by the NSDate in alarmTime.

The data in the array can be easily accessed. For example, to get the alarm time from the first alarm in the sorted alarms array, use the following code.

let alarmTime = sortedAlarms[0].alarmTime

After the alarms are sorted, you will want to reload the data in your table view using tableView.reloadData().