Skip to content

Commit

Permalink
Updated EventKit example app to asynchronously fetch events from the …
Browse files Browse the repository at this point in the history
…EKEventStore using a GCD queue.
  • Loading branch information
klazuka committed Jul 12, 2010
1 parent 522dd6c commit a6a06b5
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 8 deletions.
8 changes: 5 additions & 3 deletions Examples/NativeCal/Classes/EventKitDataSource.h
Expand Up @@ -4,14 +4,16 @@
*/

#import "Kal.h"
#import <dispatch/dispatch.h>

@class EKEventStore, EKEvent;

@interface EventKitDataSource : NSObject <KalDataSource>
{
EKEventStore *eventStore;
NSMutableArray *items;
NSMutableArray *events;
NSMutableArray *items; // The list of events corresponding to the currently selected day in the calendar. These events are used to configure cells vended by the UITableView below the calendar month view.
NSMutableArray *events; // Must be used on the main thread
EKEventStore *eventStore; // Must be used on a background thread managed by eventStoreQueue
dispatch_queue_t eventStoreQueue; // Serializes access to eventStore and offloads the query work to a background thread.
}

+ (EventKitDataSource *)dataSource;
Expand Down
26 changes: 21 additions & 5 deletions Examples/NativeCal/Classes/EventKitDataSource.m
Expand Up @@ -29,6 +29,7 @@ - (id)init
eventStore = [[EKEventStore alloc] init];
events = [[NSMutableArray alloc] init];
items = [[NSMutableArray alloc] init];
eventStoreQueue = dispatch_queue_create("com.thepolypeptides.nativecalexample", NULL);
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(eventStoreChanged:) name:EKEventStoreChangedNotification object:nil];
}
return self;
Expand All @@ -52,6 +53,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.imageView.contentMode = UIViewContentModeScaleAspectFill;
}
Expand All @@ -70,25 +72,36 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger

- (void)presentingDatesFrom:(NSDate *)fromDate to:(NSDate *)toDate delegate:(id<KalDataSourceCallbacks>)delegate
{
// asynchronous callback on the main thread
[events removeAllObjects];
NSLog(@"Fetching events from EventKit between %@ and %@...", fromDate, toDate);
NSPredicate *predicate = [eventStore predicateForEventsWithStartDate:fromDate endDate:toDate calendars:nil];
[events addObjectsFromArray:[eventStore eventsMatchingPredicate:predicate]];
[delegate loadedDataSource:self];
NSLog(@"Fetching events from EventKit between %@ and %@ on a GCD-managed background thread...", fromDate, toDate);
dispatch_async(eventStoreQueue, ^{
NSDate *fetchProfilerStart = [NSDate date];
NSPredicate *predicate = [eventStore predicateForEventsWithStartDate:fromDate endDate:toDate calendars:nil];
NSArray *matchedEvents = [eventStore eventsMatchingPredicate:predicate];
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"Fetched %d events in %f seconds", [matchedEvents count], -1.f * [fetchProfilerStart timeIntervalSinceNow]);
[events addObjectsFromArray:matchedEvents];
[delegate loadedDataSource:self];
});
});
}

- (NSArray *)markedDatesFrom:(NSDate *)fromDate to:(NSDate *)toDate
{
// synchronous callback on the main thread
return [[self eventsFrom:fromDate to:toDate] valueForKeyPath:@"startDate"];
}

- (void)loadItemsFromDate:(NSDate *)fromDate toDate:(NSDate *)toDate
{
// synchronous callback on the main thread
[items addObjectsFromArray:[self eventsFrom:fromDate to:toDate]];
}

- (void)removeAllItems
{
// synchronous callback on the main thread
[items removeAllObjects];
}

Expand All @@ -107,9 +120,12 @@ - (NSArray *)eventsFrom:(NSDate *)fromDate to:(NSDate *)toDate
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:EKEventStoreChangedNotification object:nil];
[eventStore release];
[items release];
[events release];
dispatch_sync(eventStoreQueue, ^{
[eventStore release];
});
dispatch_release(eventStoreQueue);
[super dealloc];
}

Expand Down

0 comments on commit a6a06b5

Please sign in to comment.