IOS: sources EKEventStore / defaultCalendarForNewEvents / calendarsForEntityType all return nothing AFTER authorization

I have an application that I'm trying to help get out of a door. This code was originally written by iOS5 in the head of another team. I added requestAccessToEntityType: termination: a call that succeeds. However, after gaining access, I do not get any sources / defaultCalendar or entity-based calendars. And I can not create a new calendar.

When calling defaultCalendarForNewEvents I get this error

Error Domain=EKCADErrorDomain Code=1013 "The operation couldn't be completed. (EKCADErrorDomain error 1013.)" and the result is nil.

If I return from viewController trying to do this and return, everything works fine. If, after receiving a warning about the lack of a source, I continue to try (without the support of the viewController), it fails many times.

I want to emphasize that an authorization call is working (the user is invited to access the calendars and provide it, and then call to confirm the authorization pass). All other questions that I have found look like that as a solution - make sure you requestAccessToEntityType

 [eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) { if (granted) { //[self performSelectorOnMainThread:@selector(doScheduleActivity:) withObject:activity waitUntilDone:YES]; dispatch_async(dispatch_get_main_queue(), ^{ [self doScheduleActivity:activity]; }); } else { // probably should force the main thread dispatch_async(dispatch_get_main_queue(), ^{ UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Calendar Access Required" message:@"In order to schedule activities, APP needs access to your Calendar. You can change this in your device Settings." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [av show]; }); } }] ; 

granted returned true, and [self doScheduleActivity :. is called. The following code is a function called at the very beginning of this procedure and where failures occur.

 EKCalendar *saCalendar; EKSource *source; NSError *error; UIAlertView *alert; LogDebug(@"eventStore defaultCalendar %@", [eventStore defaultCalendarForNewEvents]); // validate access to calendar prior to segueing if ([EKEventStore respondsToSelector:@selector(authorizationStatusForEntityType:)]) { switch([EKEventStore authorizationStatusForEntityType:EKEntityTypeEvent]) { case EKAuthorizationStatusAuthorized: break; case EKAuthorizationStatusNotDetermined: { dispatch_async(dispatch_get_main_queue(), ^{ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:SA_ALERT_CAPTION_CALENDAR_ACCESS_NOT_DETERMINED message:SA_ALERT_BODY_CALENDAR_ACCESS_NOT_DETERMINED delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil]; [alert show]; }); return false; } case EKAuthorizationStatusDenied: { dispatch_async(dispatch_get_main_queue(), ^{ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:SA_ALERT_CAPTION_CALENDAR_ACCESS_DENIED message:SA_ALERT_BODY_CALENDAR_ACCESS_DENIED delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil]; [alert show]; }); return false; } case EKAuthorizationStatusRestricted: { dispatch_async(dispatch_get_main_queue(), ^{ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:SA_ALERT_CAPTION_CALENDAR_ACCESS_RESTRICTED message:SA_ALERT_BODY_CALENDAR_ACCESS_RESTRICTED delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil]; [alert show]; }); return false; } default: break; } } // search for application specifc calendar.. saCalendar = nil; for(EKCalendar *calendar in [eventStore calendarsForEntityType:EKEntityTypeEvent]) { if([calendar.title isEqualToString:SA_ACTIVITIES_CALENDAR_TITLE]) { saCalendar = calendar; break; } } // ..and create from scratch if nonexistent if(nil == saCalendar) { // find local source to hook up new calendar to for(source in [eventStore sources]) { if(source.sourceType == EKSourceTypeLocal) { break; } } // if could not find local source type, something is wrong if( source == nil || source.sourceType != EKSourceTypeLocal) { alert = [[UIAlertView alloc] initWithTitle:SA_ALERT_CAPTION_CALENDAR_ERROR_NO_SOURCE message:SA_ALERT_BODY_CALENDAR_ERROR delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil]; [alert show]; return false; } // create calendar for applcation, name it, color it and assign source saCalendar = [EKCalendar calendarForEntityType:EKEntityTypeEvent eventStore:eventStore]; [saCalendar setSource:source]; [saCalendar setTitle:SA_ACTIVITIES_CALENDAR_TITLE]; [saCalendar setCGColor:[[UIColor yellowColor] CGColor]]; // create immediately error = nil; if(![eventStore saveCalendar:saCalendar commit:true error:&error]) { dispatch_async(dispatch_get_main_queue(), ^{ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:SA_ALERT_CAPTION_CALENDAR_ERROR_CANT_SAVE message:SA_ALERT_BODY_CALENDAR_ERROR delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil]; [alert show]; }); return false; } } return true; 

Everything returns zero, although it was allowed, and check [EKEventStore authorizationStatusForEntity:EKEntityType returns EKAuthorizationStatusAuthorized

After I get a crash here, if I return from this controller and return, it works. This only happens the first time the system asks the user for access to the calendar, and they answer "OK."

Thank you for understanding. I went through the debugger and also do printf type debugging to avoid any synchronization problems, etc. And I don’t see anything that contradicts the events that I was looking for on the Apple website.

My target device is 6.1.3 iPhone 5

+4
source share
2 answers

OK, it turned out that there was a small line of code in viewDidLoad that came before the code [eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error and tried to access eventStore. This was redundant and did not need to happen, and I didn’t have to I didn’t notice. As soon as I deleted this code, now everything works, so it returns to the need for authorization, because even after authorization, eventStore was already "bad" due to this previous access.

+6
source

The issue can also be resolved by re-creating the EKEventStore instance in the callback after granting access.

+7
source

Source: https://habr.com/ru/post/1494547/


All Articles