0

In my app, I am reading the calendar as soon as the app launches. So for the first time as per the guidelines my app asks for calendar access but what's happening is it never shows up and all i can see is the splash screen.

When i close the app i see the popup for granting access to calendar on my phone. I grant access to it and after that point everything works fine.

Here's my code :

-(NSArray*) listOfEventsInCalendar
{
    _eventStore = [[EKEventStore alloc]init];
    __block NSArray * events;

    if ([_eventStore respondsToSelector:@selector(requestAccessToEntityType:completion:)])
    {
        dispatch_semaphore_t sema = dispatch_semaphore_create(0);
        /* iOS Settings > Privacy > Calendars > MY APP > ENABLE | DISABLE */
        [_eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error)
         {

             if ( granted )
             {

                 NSDate * startDate = [NSDate date];
                 NSDate * endDate = [NSDate distantFuture];
                 NSPredicate * predicate = [_eventStore predicateForEventsWithStartDate:startDate endDate:endDate calendars:nil];
                 events = [_eventStore eventsMatchingPredicate:predicate];
                 if (events) {
                    insideArray = [self castEvents:events];
                 }
                 else{
                     NSLog(@"No Events found in the calendar");
                 }

             }
             else
             {
                 NSLog(@"User has not granted permission!");
             }

             dispatch_semaphore_signal(sema);
         }];

        dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);

    }
    return insideArray;
}

What am i doing wrong??

Thanks,

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Ashutosh
  • 5,614
  • 13
  • 52
  • 84

1 Answers1

0

The problem is simple. You are blocking the main thread with your semaphore. This is a bad idea.

Don't have your listOfEventsInCalendar block. Let it return immediately. Let the completion block handle the result. One option would be to add a block parameter to your listOfEventsInCalendar method. Then call the block from the completion block passing the obtained array.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • I was doing the same but it was returning an empty array (insideArray) so that's why i and to wait on this thread to complete. – Ashutosh Mar 15 '14 at 03:36
  • What I'm saying is you need to refactor this code so the array isn't returned at the end of the method. It needs to be processed when the completion method is called. You can't block the main thread. On a real device, when not run through Xcode, iOS will kill your app for taking to long to startup. – rmaddy Mar 15 '14 at 03:47
  • I got your idea but not sure how to implement in code. Can you please direct me in right direction via some sample code. Thanks, – Ashutosh Mar 15 '14 at 03:56