Advertise

Thursday, March 16, 2017

PART 2: Manage Events using EventKit Framework in Swift





Before you manage events if you missed how to create custom calendar then take a look PART 1

What we will do in this post?


We are going to add custom event to calendar, get all list of events, update event details and delete event. In this post you will get all concept of event management in calendar using EventKit framework.

Create New Event


If you want user to add event start time, end time and name then create a new swift controller class and add following components 1 UITextField, 2 DatePicker. If you want to know all source code with features then download the source code from link given at the end of the post. Here, I am going to give you simple code which creates new event in calendar.

Here is a code,

 func addEvent(){

        
        // Create an Event Store instance
        let eventStore = EKEventStore()
        
        // Use Event Store to create a new calendar instance
        if let calendarForEvent = eventStore.calendar(withIdentifier: self.calendar.calendarIdentifier)
        {
            var newEvent = EKEvent(eventStore: eventStore)
            newEvent.calendar = calendarForEvent
            newEvent.title = self.eventNmField.text ?? "Some Event Name"
            newEvent.startDate = self.startDatePicker.date
            newEvent.endDate = self.endDatePicker.date
            newEvent.addAlarm(.init(relativeOffset: 0))
            // Save the event using the Event Store instance
            do {
                try eventStore.save(newEvent, span: .thisEvent, commit: true)                
                self.navigationController?.popViewController(animated: true)
            } catch {
                let alert = UIAlertController(title: "Event could not save", message: (error as NSError).localizedDescription, preferredStyle: .alert)
                let OKAction = UIAlertAction(title: "OK", style: .default, handler: nil)
                alert.addAction(OKAction)
                
                self.present(alert, animated: true, completion: nil)
            }
        }
    }

Note that, You need a Calendar identifier in which you are going to add event. For that you can transfer Calendar object from one controller to another OR you can save into UserDefaults and get it when required to add event. Here, assume that self.calendar is a calendar object in which I have created a event. Title, startDate and endDate fields are user defined, you can give it static for demo purpose.

Update event


func updateEvent(){
        let eventStore = EKEventStore()
        eventStore.requestAccess(to: .event, completion: {
        granted, error in
            if(!granted){
                print("Access to store not granted")
                print(error?.localizedDescription)
            }else{
                let savedEvent = eventStore.event(withIdentifier: self.event4Update.eventIdentifier)
                if(savedEvent != nil){
                    savedEvent?.title = self.eventNmField.text ?? "Some Event Name"
                    savedEvent?.addAlarm(.init(relativeOffset: 0))
                    savedEvent?.startDate = self.startDatePicker.date
                    savedEvent?.endDate = self.endDatePicker.date
                    do{
                        try eventStore.save(savedEvent!, span: .thisEvent)
                        DispatchQueue.main.async {
                            self.navigationController?.popViewController(animated: true)
                        }
                    }catch{
                        print("Event couldnot update : \(error.localizedDescription)")
                    }
                }else{
                    print("Event not available")
                }
            }
        })
    }

Above code updates selected event, for that you must have a event object which you want to update. Above code is clearly mentioned that we have created a new object with the event4Update identifier, set new parameters and then we commit to the event.


Delete event


It is very simple to delete/remove event from calendar. You just need to call one method to remove event from eventStore. Here is the code to remove event, to delete you just pass that event to this method.

    func deleteEntry(event : EKEvent){
        do{
            try eventStore.remove(event, span: EKSpan.thisEvent, commit: true)
            self.loadEvents()
            self.tableView.reloadData()
        }catch{
            print("Error while deleting event: \(error.localizedDescription)")
        }
    }

Get list of all events



As we saw in Part 1, we get all calendar in a array and place it into TableView. Same way we are going to get all events, store it into array and display in tableView. So, We start step by step.

1. Import EventKit on header and declare objects as below:

    var events: [EKEvent]?
    var eventStore : EKEventStore!

2. Create method to load events of selected calendar for specific time period and call this method in viewDidLoad.

 func loadEvents() {
        // Create a date formatter instance to use for converting a string to a date
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd"
        
        // Create start and end date NSDate instances to build a predicate for which events to select
        let startDate = dateFormatter.date(from: "2017-01-01")
        let endDate = dateFormatter.date(from: "2017-12-31")
        
        if let startDate = startDate, let endDate = endDate {
            eventStore = EKEventStore()
            
            // Use an event store instance to create and properly configure an NSPredicate
            let eventsPredicate = eventStore.predicateForEvents(withStart: startDate, end: endDate, calendars: [calendar])
            
            // Use the configured NSPredicate to find and return events in the store that match
            self.events = eventStore.events(matching: eventsPredicate).sorted(){
                (e1: EKEvent, e2: EKEvent) -> Bool in
                return e1.startDate.compare(e2.startDate) == ComparisonResult.orderedAscending
            }
        }
    }

3. Update TableView Methods as given below:

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if let events = events {
            return events.count
        }
        return 0
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")!
        cell.textLabel?.text = events?[(indexPath as NSIndexPath).row].title
        cell.detailTextLabel?.text = "\(formatDate(events?[(indexPath as NSIndexPath).row].startDate)) TO \(formatDate(events?[(indexPath as NSIndexPath).row].endDate))"
        return cell
    }

Done! It will load all events of specific calendar to tableview. You can download full source code from given link. It has following features:
  • Ask permission and grant access to use Calendar
  • Create Calendar and get a list of all Calendars
  • Create,Update,Delete,Get Events

Download Full Source Code


No comments:

Post a Comment