2

I am getting a EXEC_BAD_ACCESS Error when I attempt to run this code, and the user has not allowed access to the calendar. Does requestAccessToEntityType run on a separate thread, if thats the case how do I access the main thread to display the UIAlertView?

EKEventStore *store = [[EKEventStore alloc] init];
if ([store respondsToSelector:@selector(requestAccessToEntityType:completion:)])
{
    [store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error)
     {
         if ( granted )
         {
             [self readEvents];
         }
         else
         {
             UIAlertView *alert = [[UIAlertView alloc] 
                                      initWithTitle:@"Denied Access To Calendar" 
                                      message:@"Access was denied to the calendar, please go into settings and allow this app access to the calendar!" 
                                      delegate:nil 
                                      cancelButtonTitle:@"Ok" 
                                      otherButtonTitles:nil, 
                                      nil];
             [alert show];
         }
     }];
}
ios85
  • 2,104
  • 7
  • 37
  • 55

2 Answers2

3

According to the docs for requestAccessToEntityType

When the user taps to grant or deny access, the completion handler will be called on an arbitrary queue.

So, yes, it could be on a different thread than the UI one. You can only put up alerts from the main GUI thread.

Look into performSelectorOnMainThread. More information here: Perform UI Changes on main thread using dispatch_async or performSelectorOnMainThread?

Community
  • 1
  • 1
Lou Franco
  • 87,846
  • 14
  • 132
  • 192
2

Reason why your app is crashing because you are trying to deal with your GUI elements i.e UIAlertView in background thread, you need to run it on the main thread or try to use dispatch queues

Using Dispatch Queues

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);

    dispatch_async(queue, ^{

     //show your UIAlertView here... or any GUI stuff

    });

OR you can show the GUI elements on the main thread like this

[alertView performSelectorOnMainThread:@selector(show) withObject:nil waitUntilDone:YES];

You can have more detail about using GUI elements on Threads on this link

nsgulliver
  • 12,655
  • 23
  • 43
  • 64