From 9cfe973468b8322342ccd6c84ff39668d320d87d Mon Sep 17 00:00:00 2001 From: Morgan McKenzie Date: Mon, 14 Jun 2021 19:36:57 -0700 Subject: [PATCH 1/3] Add fallbacks when no local calendar --- ios/Classes/SwiftDeviceCalendarPlugin.swift | 38 +++++++++++++++------ 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/ios/Classes/SwiftDeviceCalendarPlugin.swift b/ios/Classes/SwiftDeviceCalendarPlugin.swift index b7398d6d..53e37599 100644 --- a/ios/Classes/SwiftDeviceCalendarPlugin.swift +++ b/ios/Classes/SwiftDeviceCalendarPlugin.swift @@ -159,6 +159,26 @@ public class SwiftDeviceCalendarPlugin: NSObject, FlutterPlugin { result(hasPermissions) } + private func getSource() -> EKSource? { + let localSources = eventStore.sources.filter { $0.sourceType == .local } + + if (!localSources.isEmpty) { + return localSources.first + } + + if let defaultSource = eventStore.defaultCalendarForNewEvents?.source { + return defaultSource + } + + let iCloudSources = eventStore.sources.filter { $0.sourceType == .calDAV && $0.sourceIdentifier == "iCloud" } + + if (!iCloudSources.isEmpty) { + return iCloudSources.first + } + + return nil + } + private func createCalendar(_ call: FlutterMethodCall, _ result: FlutterResult) { let arguments = call.arguments as! Dictionary let calendar = EKCalendar.init(for: EKEntityType.event, eventStore: eventStore) @@ -173,17 +193,15 @@ public class SwiftDeviceCalendarPlugin: NSObject, FlutterPlugin { calendar.cgColor = UIColor(red: 255, green: 0, blue: 0, alpha: 0).cgColor // Red colour as a default } - let localSources = eventStore.sources.filter { $0.sourceType == .local } - - if (!localSources.isEmpty) { - calendar.source = localSources.first - - try eventStore.saveCalendar(calendar, commit: true) - result(calendar.calendarIdentifier) - } - else { - result(FlutterError(code: self.genericError, message: "Local calendar was not found.", details: nil)) + guard let source = getSource() else { + result(FlutterError(code: self.genericError, message: "Local calendar was not found.", details: nil)) + return } + + calendar.source = source + + try eventStore.saveCalendar(calendar, commit: true) + result(calendar.calendarIdentifier) } catch { eventStore.reset() From 17cc79cea593f10e5ce327e2745e9db20069b6e7 Mon Sep 17 00:00:00 2001 From: Morgan McKenzie Date: Mon, 14 Jun 2021 19:37:07 -0700 Subject: [PATCH 2/3] re-add url parameter to constructor --- lib/src/models/event.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/models/event.dart b/lib/src/models/event.dart index 355a0d65..bdfc728c 100644 --- a/lib/src/models/event.dart +++ b/lib/src/models/event.dart @@ -56,6 +56,7 @@ class Event { this.attendees, this.recurrenceRule, this.reminders, + this.url, required this.availability, this.allDay = false}); From 8f20bd6292dfab51a9276ca21d9002fe65468920 Mon Sep 17 00:00:00 2001 From: Morgan McKenzie Date: Sat, 19 Jun 2021 04:15:27 -0700 Subject: [PATCH 3/3] Don't crash if calendar or eventids are null --- ios/Classes/SwiftDeviceCalendarPlugin.swift | 26 +++++++++++---------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/ios/Classes/SwiftDeviceCalendarPlugin.swift b/ios/Classes/SwiftDeviceCalendarPlugin.swift index 53e37599..d1a33410 100644 --- a/ios/Classes/SwiftDeviceCalendarPlugin.swift +++ b/ios/Classes/SwiftDeviceCalendarPlugin.swift @@ -281,36 +281,38 @@ public class SwiftDeviceCalendarPlugin: NSObject, FlutterPlugin { let calendarId = arguments[calendarIdArgument] as! String let startDateMillisecondsSinceEpoch = arguments[startDateArgument] as? NSNumber let endDateDateMillisecondsSinceEpoch = arguments[endDateArgument] as? NSNumber - let eventIds = arguments[eventIdsArgument] as? [String] + let eventIdArgs = arguments[eventIdsArgument] as? [String] var events = [Event]() let specifiedStartEndDates = startDateMillisecondsSinceEpoch != nil && endDateDateMillisecondsSinceEpoch != nil if specifiedStartEndDates { let startDate = Date (timeIntervalSince1970: startDateMillisecondsSinceEpoch!.doubleValue / 1000.0) let endDate = Date (timeIntervalSince1970: endDateDateMillisecondsSinceEpoch!.doubleValue / 1000.0) - let ekCalendar = self.eventStore.calendar(withIdentifier: calendarId) - let predicate = self.eventStore.predicateForEvents(withStart: startDate, end: endDate, calendars: [ekCalendar!]) - let ekEvents = self.eventStore.events(matching: predicate) - for ekEvent in ekEvents { - let event = createEventFromEkEvent(calendarId: calendarId, ekEvent: ekEvent) - events.append(event) + + if let ekCalendar = self.eventStore.calendar(withIdentifier: calendarId) { + let predicate = self.eventStore.predicateForEvents(withStart: startDate, end: endDate, calendars: [ekCalendar]) + let ekEvents = self.eventStore.events(matching: predicate) + for ekEvent in ekEvents { + let event = createEventFromEkEvent(calendarId: calendarId, ekEvent: ekEvent) + events.append(event) + } } } - if eventIds == nil { - self.encodeJsonAndFinish(codable: events, result: result) - return + guard let eventIds = eventIdArgs else { + self.encodeJsonAndFinish(codable: events, result: result) + return } if specifiedStartEndDates { events = events.filter({ (e) -> Bool in - e.calendarId == calendarId && eventIds!.contains(e.eventId) + e.calendarId == calendarId && eventIds.contains(e.eventId) }) self.encodeJsonAndFinish(codable: events, result: result) return } - for eventId in eventIds! { + for eventId in eventIds { let ekEvent = self.eventStore.event(withIdentifier: eventId) if ekEvent == nil { continue