richardtop / CalendarApp

đź“… Reference implementation of a Calendar App with CalendarKit (template repository)
https://www.youtube.com/watch?v=cJ63-_z1qg8
MIT License
206 stars 61 forks source link

Crash #6

Closed R35Master closed 1 year ago

R35Master commented 2 years ago

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?

` 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)
}

}`

https://user-images.githubusercontent.com/109156022/185787187-5a07a2dd-298c-4de1-a739-4c36e7d389cb.MP4

richardtop commented 2 years ago

Could you please try to reproduce this issue with the latest version of this CalendarApp in order to further isolate it and find the root cause?

R35Master commented 2 years ago

Just released a new update with latest version, it crashed again. Same.

In calendar app when I click to Add Invitee and click + button app crashes. In ios calendar, I add an event with invitee added, going back to calendar app, clicking that event immediate crash. @richardtop

richardtop commented 2 years ago

This could be simply due to the fact that the CalendarApp has access to the calendar but doesn't have to the contacts and crashes when it tries to access it.