Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Errors when launching the app for the first time #9

Closed
skegget opened this issue Feb 24, 2021 · 14 comments
Closed

Errors when launching the app for the first time #9

skegget opened this issue Feb 24, 2021 · 14 comments

Comments

@skegget
Copy link

skegget commented Feb 24, 2021

Hi,

I noticed two console errors when launching your app for the first time on a clean simulator:

EventKit Example[9647:3259614] [EventKit] Error getting default calendar for new events: Error Domain=EKCADErrorDomain Code=1013 "(null)"

Followed by:

EventKit Example[9647:3259614] [EventKit] No object ID provided. Will not find out if the object exists.

Also (I don't know if this is related to the above errors), when you launch the app for the first time, approve the calendar access and then try to select calendars, the list of available calendars is empty. If I however kill the app and restart it, the list is populated and I can select calendars.

Also note that if I kill the app and restart it, it seems that the error messages are gone.

Edit: The above is also repeatable when the app is installed on my device

Edit2: Forgot to mention that this is in your SwiftUI example.

@nemecek-filip
Copy link
Owner

Hi, thanks for pointing this out. The issue with clean simulator appears to be related to Calendar not being yet initialized. Someone added info to README about this which I just merged.

Thanks for the clarification, I will look into it. Or if you want, you can try to fix the SwiftUI example and open PR :-)

@skegget
Copy link
Author

skegget commented Feb 27, 2021

I've spent quite some time on the errors but I can't seem to find a solution, or even a source. I will continue digging but it would be great if you can take a look as well. I don't trust my SwiftUI skills yet 😀

For some reason I think the errors and the empty calendar list are related. As I mentioned, if I run the app on my daily driver device I still get the errors and an empty calendar list the first time the app is started after a clean install. On this device the calendar is definitely initiated.

Is almost like the available calendars are not refreshed after you accept calendar access.

@skegget
Copy link
Author

skegget commented Feb 27, 2021

One step forward, two steps back.
I did some experiments and I might have found something that can be of help.

In the EventsRepository.swift, if you change let eventStore = EKEventStore() to var eventStore = EKEventStore() and then change the requestAccess function to:

func requestAccess(onGranted: @escaping Action, onDenied: @escaping Action) {
        eventStore.requestAccess(to: .event) { (granted, error) in
            if granted {
                self.eventStore = EKEventStore()
                onGranted()
            } else {
                onDenied()
            }
        }
    }

By doing this the calendar list is populated directly. However, this causes a bunch of other errors, like a EKEvent duplicate key error if you add an event. As mentioned, I was experimenting but it might be worth taking a closer look.

@nemecek-filip
Copy link
Owner

Thanks. I will try to look into it, but I havent done much of SwiftUI since creating this update..

@skegget
Copy link
Author

skegget commented Feb 27, 2021

Sorry for hammering you with posts and information, but here is a SO post with the exact same issue. The possible solution seems to be to "Make sure you aren't initializing EKEventStore before requesting calendar permissions."

https://stackoverflow.com/questions/58873603/ekeventstore-calendars-is-always-empty-after-clean-install

@nemecek-filip
Copy link
Owner

Thanks for the search. However you need an instance of EKEventStore to request permissions 🤔 You said UIKit version is working fine? Since there the EKEventStore is created immediately by the view controller.

@skegget
Copy link
Author

skegget commented Feb 27, 2021

Hm, weird . I have not tested the UIKit version.

I also found this in apples documentation on EKEventStore

"If your app has never requested access before, you must request access to events or reminders before attempting to fetch or create them. If you request data before prompting the user for access with this method, you’ll need to reset the event store with the reset() method in order to start receiving data after the user grants access."

https://developer.apple.com/documentation/eventkit/ekeventstore/1507547-requestaccess

Something like eventStore.reset(), I guess. But I'm not sure where to reset the event store?

@nemecek-filip
Copy link
Owner

Based on the docs it makes sense to call reset before the onGranted closure is called in the requestAccess method. I dont have access to my Mac right now so I cannot try this.

@skegget
Copy link
Author

skegget commented Feb 27, 2021

Unfortunately no luck. I'm really struggling with this, so if you could take a look I would really appreciate it. This is basically the last piece of my app puzzle :)

@nemecek-filip
Copy link
Owner

I will try to fix this issue 👍

@skegget
Copy link
Author

skegget commented Feb 28, 2021

Great! I've experimented with another thing and this might be the definition of bad coding, I don't know :) But it seems to work so maybe you can take some inspiration from it.

I added the requestAccess function to the top of init(), like this:

init() {
        requestAccess(onGranted: {
            self.eventStore = EKEventStore()
        }) {
           
        }
...
}

So when we gain access I'm getting a new eventStore instance. If this is usable, I don't know if you need to requestAccess in the loadEvents function?

Also, I came across authorizationStatus(for:) which seems to be used as a check on which you can act on the current status (authorized, denied, notDetermined, restricted).
https://developer.apple.com/documentation/eventkit/ekeventstore/1507239-authorizationstatus

@nemecek-filip
Copy link
Owner

Think I found it:

selectedCalendars = loadSelectedCalendars() ?? Set([eventStore.defaultCalendarForNewEvents].compactMap({ $0 }))

This line was likely responsible for accessing eventStore before permissions were available and thus causing the issues. If you remove the ?? part, then it works.

I have updated the repo with this fix:

selectedCalendars = loadSelectedCalendars()
        
if selectedCalendars == nil {
    if EKEventStore.authorizationStatus(for: .event) == .authorized {
        selectedCalendars = Set([eventStore.defaultCalendarForNewEvents].compactMap({ $0 }))
    }
}

@skegget
Copy link
Author

skegget commented Feb 28, 2021

Amazing Filip, just tested the fix and it seems to work perfectly!

I also noticed that the errors I mentioned in my first post seems to be gone as well :)

Thank you and great job!

@nemecek-filip
Copy link
Owner

Awesome! Thanks for help fixing this :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants