0

I now develop an iOS App that shows a list of iCloud EKCalendars. My swift codes can get a set of iCloud EKCalendars, but the order is always different. Could anyone give me advice to get the set in order?

let eventStore = EKEventStore()
let sources = eventStore.sources
for source in sources {
    if (source.title == "iCloud") {
        let calendars = source.calendars(for: .event)
        for calendar in calendars {
            print("calendar title = " + calendar.title)
        }
    }
}

Example of the result of the codes:

calendar title = title1
calendar title = title6
calendar title = title5
calendar title = title3
calendar title = title4
calendar title = title2
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62

2 Answers2

2

So let calendars = source.calendars(for: .event) is of type Set<EKCalendar>, by definition a Set is data type that is not ordered so whenever you iterate through a set it could always be in different order, the only thing that Set enforces is that there is only one instance of the object it the set.

If you want to have calendars ordered you will have to order it by yourself, one is to order them by title or calendarIdentifier.

Ladislav
  • 7,223
  • 5
  • 27
  • 31
  • Thank you for your explanation. I didn't understand about the feature of **Set**. – shuvroche Jul 12 '18 at 14:19
  • I now understand why it is random. Thank you. But I still have one problem. Can it be ordered on iOS App just like on macOS Calendar? For example, if the order of titles of calendar on macOS Calendar App is "title1", "titleA2", "title3", "title4", "title5", "title6" (not alphabetically), iOS App can show the same order or not. iCal on iPhone seems to work well (It succeeds in showing calendars in order of "title1", "titleA2", "title3", "title4", title5", title6"). – shuvroche Jul 12 '18 at 14:39
  • Print out all of `calendarIdentifier` and let me know what they are, maybe `Apple` does not use the `title` for ordering but `calendarIdentifier` – Ladislav Jul 12 '18 at 14:41
  • I thought the same idea at first when I faced this problem. But calendarIdentifier seems to be created at random... – shuvroche Jul 13 '18 at 02:18
  • Name and calendarIdentifier(first 4 characters) are, (title1, FC01), (titleA2, 31E5), (title3, BABA), (title4, 9276), (title5, EF7F), (title6, 3DF1). – shuvroche Jul 13 '18 at 02:19
1

Just sort the Set, the result is an ordered array:

let eventStore = EKEventStore()
let sources = eventStore.sources.filter{ $0.title == "iCloud" }
for source in sources {
    let calendars = source.calendars(for: .event).sorted{ $0.title < $1.title }
    calendars.forEach { print("calendar title = ", $0.title) }
}
vadian
  • 274,689
  • 30
  • 353
  • 361
  • Thank you for your advice and I tried your codes and confirm it work fine. Thank you. But I still have one problem. Can it be ordered on iOS App just like on macOS Calendar? For example, if the order of titles of calendar on macOS Calendar App is "title1", "titleA2", "title3", "title4", "title5", "title6" (not alphabetically), iOS App can show the same order or not. iCal on iPhone seems to work well (It succeeds in showing calendars in order of "title1", "titleA2", "title3", "title4", title5", title6"). – shuvroche Jul 12 '18 at 14:41
  • The order of titles on macOS calendar is arbitrary, you can change it with drag&drop. There is no sort mode which sorts in your given order. `localizedStandardCompare` sorts like in Finder but `titleA2` comes always after `title6`. – vadian Jul 12 '18 at 15:58
  • Yes. It can do drag&drop on macOS. And iCal app on iPhone synchronizes with the order just like the result of the drag&drop. I want to make codes that do the same thing on my app, synchronizing with the result on macOS. – shuvroche Jul 13 '18 at 02:38
  • Did you checked it in iOS12? eventstore does not returning any Exchange events like outlook events. – GvSharma Oct 01 '18 at 06:43