Batch saving EKEvents to Google calendar causing l

2019-07-20 04:18发布

问题:

I have a large set of activities that I want to batch save to the calendar. Which calendar is selected by the user. They have the option to export to iCloud calendar or Google calendar. When exporting to iCloud calendar everything runs smoothly. No problems. However, when exporting to Google calendar I am encountering som weird issues. The number of events to be saved is somewhere around 60-90 events. I use the function provided below to export the calendar events in the background. The operation runs fine and during logging all events are included and when iterating over the events they have all receieved an eventIdentifier. However, on every occasion, about 5-10 events are not synced up to Google calendar and not shown on the phones calendar. The events that are not showing are different for each export, so it is not the event itself that is faulty. I have tried so many different approaches, but no success. What I have tried: - Removed the background operation. - Removed calendar status callback. - Moved the function outside of the closure and calling it directly. - Removed the @autorelease. - Checked that the EKEventStore and EKCalendar is alive during the whole operation.

Does anyone of you know a good explanation for this? I checked if google had any limits on saves, but according to the documents the calendar may turn into readonly when importing 10 000+ events in a short time, in which I am not even close to.

I would love any feedback. This is driving me crazy. As I said earlier, iCloud export works just fine.

Here is my export code:

import UIKit
import EventKit

struct Activity {
   var title : String!
   var startDate : NSDate!
   var endDate : NSDate!
}

class CalendarManager: NSObject {

class func saveToCalendarInBackground(activities: [Activity], eventStore: EKEventStore, calendar: EKCalendar, calendarStatus: (status: String!, progress: Float!) -> (), completion:(success: Bool!, error: NSError!) -> ()) -> Void {

    //Run the operations on another thread (not main), but do UI updates on the main thread
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {

        if activities.count > 0 {

            var formatter = NSDateFormatter()

            autoreleasepool {

                //Save duties to calendar
                for (index, activity) in enumerate(activities) {

                    //Update status
                    let progress = Float(index + 1) / Float(activities.count)

                    //Return callbacks on main thread
                    dispatch_sync(dispatch_get_main_queue(), {
                        calendarStatus(status: "Saving \(index+1) of \(activities.count)", progress: progress)
                    })

                    //Save activity
                    var event = EKEvent(eventStore: eventStore)
                    event.calendar = calendar
                    event.title = activity.title
                    event.startDate = activity.startDate
                    event.endDate = activity.endDate

                    var saveEventError : NSError?

                    if eventStore.saveEvent(event, span: EKSpanThisEvent, commit: false, error: &saveEventError) {

                        println("Activity saved. Commit needed.")

                    }
                    else {
                        println("Save error: \(saveEventError?.localizedDescription)")
                    }

                    //
                }

            }

            //Save all pending events
            var saveAllEventsError : NSError?

            if eventStore.commit(&saveAllEventsError) == true{
                println("Save all events complete!")

                //Return callbacks on main thread
                dispatch_async(dispatch_get_main_queue(), {
                    println("Calendar Save completion.")

                    calendarStatus(status: "Calendar save complete!", progress: 1)

                    completion(success: true, error: nil)
                })
                return
            }
            else {

                //Return callbacks on main thread
                dispatch_async(dispatch_get_main_queue(), {
                    completion(success: false, error: NSError(domain: "Calendar Save Error", code: 0, userInfo: [NSLocalizedFailureReasonErrorKey : "Error batch saving events: \(saveAllEventsError?.localizedDescription)"]))
                })

                println("Save all events ERROR: \(saveAllEventsError?.localizedDescription)")
                return
            }
        }
        else {

            //Return callbacks on main thread
            dispatch_async(dispatch_get_main_queue(), {
                completion(success: false, error: NSError(domain: "Calendar Save Error", code: 0, userInfo: [NSLocalizedFailureReasonErrorKey : "Found no events to save!"]))
            })
            return
        }
    })
}

}