richardtop / CalendarKit

📅 Calendar for Apple platforms in Swift
https://www.youtube.com/watch?v=cJ63-_z1qg8
MIT License
2.48k stars 333 forks source link

App Crashes #346

Closed R35Master closed 1 year ago

R35Master commented 1 year ago

New Issue Checklist

Issue Description

Hi @richardtop I found a bug (maybe not) when I add invitee from ios calendar and go to calenderkit view and click that event app directly crashes or when I click add invitee in the app in calender kit view it directly crashes. Is there a way to solve it or a way to remove that section that says add invitee? Even I remove the add invitee in the calender kit view if a user has added an invitee from ios calender it will keep crushing. do you have a solution for that? Any document or walktrough video smth?

Code I'm using with CalendarKit

<!-- INSERT CODE HERE -->

import UIKit
import CalendarKit
import EventKit
import EventKitUI
import Firebase
import FirebaseAuth

class BsCalendarViewController: DayViewController, EKEventEditViewDelegate {

    private let eventStore =  EKEventStore()

    let db = Firestore.firestore()
    let currentUserMail = Auth.auth().currentUser?.email
    var xx = ""

    override func viewDidLoad() {
        super.viewDidLoad()
        requestAccessToCalendar()
        subscribeToNotifications()
        getCurrentUserData()

        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: self.uploadCurrentUserCalendar)

        let appearance = UINavigationBarAppearance()
        appearance.configureWithTransparentBackground()
        appearance.shadowColor = nil

        let navigationBar = navigationController!.navigationBar
        navigationBar.standardAppearance = appearance
        navigationBar.scrollEdgeAppearance = appearance

        self.navigationController?.setToolbarHidden(true, animated: false)

    }

    func getCurrentUserData() {

        db.collection("xx").document(xx!).getDocument { (document, error) in

            if let document = document, document.exists {
                   let dataDescription = document.data()
                guard let type = dataDescription?["x x"] else {return}
                self.xx = type as! String
               } else {
                   print("Document does not exist")
               }
        }
    }

    var eventBox: [EventBox] = []

    func uploadCurrentUserCalendar() {

        self.db.collection(xx).document(xx!).collection("Calendar").getDocuments() { (querySnapshot, err) in
            if let err = err {
                let alert = UIAlertController(title: "Upload Error", message: err.localizedDescription, preferredStyle: UIAlertController.Style.alert)
                alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
                self.present(alert, animated: true, completion: nil)
                return
            } else {
                for document in querySnapshot!.documents {
                    document.reference.delete()
                }
                let startDate = Calendar.current.date(byAdding: .day, value: -7, to: Date())

                var oneDayComponents = DateComponents()
                oneDayComponents.day = 35
                let endDate = self.calendar.date(byAdding: oneDayComponents, to: startDate!)!
                let predicate = self.eventStore.predicateForEvents(withStart: startDate!, end: endDate, calendars: nil)
                let eventKitEvents = self.eventStore.events(matching: predicate)

                for event in eventKitEvents {
                   if let startDate = event.startDate,
                      let endDate = event.endDate,
                      let isAllDay = event.isAllDay as? Bool,
                      let title = event.title{
                       let newEventBox = EventBox(startDate: startDate, endDate: endDate, isAllDay: isAllDay, title: title)
                       self.eventBox.append(newEventBox)

                   }
                }
                for uploadData in self.eventBox {
                    self.db.collection(x.xx).document(x.xx!).collection("Calendar").document(uploadData.title).setData([ "title" : uploadData.title, "startDate" : uploadData.startDate, "endDate" : uploadData.endDate, "isAllDay" : uploadData.isAllDay])
                }
            }
        }

    }

    override func viewWillDisappear(_ animated: Bool) {
        self.navigationController?.setToolbarHidden(true, animated: false)

    }
    override func viewWillAppear(_ animated: Bool) {
        self.navigationController?.setToolbarHidden(true, animated: false)

    }

    func subscribeToNotifications() {
        NotificationCenter.default.addObserver(self, selector: #selector(storeChanged(_:)), name: .EKEventStoreChanged, object: nil)
    }

    @objc func storeChanged(_ notification: Notification) {
        reloadData()
        uploadCurrentUserCalendar()
    }

    func requestAccessToCalendar() {

        eventStore.requestAccess(to: .event) { success, error in

        }
    }

    override func eventsForDate(_ date: Date) -> [EventDescriptor] {

        let startDate = date

        var oneDayComponents = DateComponents()
        oneDayComponents.day = 1

        let endDate = calendar.date(byAdding: oneDayComponents, to: startDate)!

        let predicate = eventStore.predicateForEvents(withStart: startDate, end: endDate, calendars: nil)

        let eventKitEvents = eventStore.events(matching: predicate)
        let calenderKitEvents = eventKitEvents.map(EKWrapper.init)

        return calenderKitEvents
    }

    override func dayViewDidSelectEventView(_ eventView: EventView) {

        guard let ckEvent = eventView.descriptor as? EKWrapper else {
            return
        }

        let ekEvent = ckEvent.ekEvent
        presentDetailView(ekEvent)
    }

    private func presentDetailView(_ ekEvent: EKEvent) {

        let eventViewController = EKEventViewController()
        eventViewController.event = ekEvent
        eventViewController.allowsCalendarPreview = true
        eventViewController.allowsEditing = true
        navigationController?.pushViewController(eventViewController, animated: true)
    }

    override func dayViewDidLongPressEventView(_ eventView: EventView) {
        endEventEditing()
        guard let ckEvent = eventView.descriptor as? EKWrapper else { return }

        beginEditing(event: ckEvent, animated: true)
    }

    override func dayView(dayView: DayView, didUpdate event: EventDescriptor) {
        guard let editingEvent = event as? EKWrapper else { return }
        if let originalEvent = event.editedEvent {
            editingEvent.commitEditing()

            if originalEvent === editingEvent {
                // event creation flow
                presentEditingViewForEvent(editingEvent.ekEvent)
            } else {
                // editing flow
                try! eventStore.save(editingEvent.ekEvent, span: .thisEvent)
            }

        }
        reloadData()
    }

    func presentEditingViewForEvent(_ ekEvent: EKEvent) {
        let editingViewController = EKEventEditViewController()
        editingViewController.editViewDelegate = self
        editingViewController.event = ekEvent
        editingViewController.eventStore = eventStore
        present(editingViewController, animated: true, completion: nil)
    }

    override func dayView(dayView: DayView, didTapTimelineAt date: Date) {
        endEventEditing()
    }

    override func dayViewDidBeginDragging(dayView: DayView) {
        endEventEditing()
    }

    override func dayView(dayView: DayView, didLongPressTimelineAt date: Date) {
        let newEKEvent = EKEvent(eventStore: eventStore)
        newEKEvent.calendar = eventStore.defaultCalendarForNewEvents

        var oneHourComponents = DateComponents()
        oneHourComponents.hour = 1

        let endDate = calendar.date(byAdding: oneHourComponents, to: date)

        newEKEvent.startDate = date
        newEKEvent.endDate = endDate
        newEKEvent.title = "New Event"

        let newEKWrapper = EKWrapper(eventKitEvent: newEKEvent)
        newEKWrapper.editedEvent = newEKWrapper

        create(event: newEKWrapper, animated: true)
    }

    func eventEditViewController(_ controller: EKEventEditViewController, didCompleteWith action: EKEventEditViewAction) {
        endEventEditing()
        reloadData()
        controller.dismiss(animated: true, completion: nil)
    }
}

Result I am trying to achieve

richardtop commented 1 year ago

Could you please share a code and a video?

richardtop commented 1 year ago

I cannot see the record, looks like it's an image. Also looks like the right repository to add this issue is to CalendarApp and not CalendarKit https://github.com/richardtop/CalendarApp

I was able to check the record, it seems that the issue is related to the CalendarApp not CalendarKit, please file a bug there and close this one.

R35Master commented 1 year ago
Screen Shot 2022-08-20 at 11 11 48

It's a video? Could you please confirm you see it?

richardtop commented 1 year ago

Yep, I can see it. It's a CalendarApp bug, not CalendarKit's