-
Notifications
You must be signed in to change notification settings - Fork 0
/
MyScheduleViewController.m
232 lines (187 loc) · 7.99 KB
/
MyScheduleViewController.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
//
// MyScheduleViewController.m
// Kickoff South Bend
//
// Created by Christian Poellabauer on 3/6/13.
// Copyright (c) 2013 Christian Poellabauer. All rights reserved.
//
#import "MyScheduleViewController.h"
#import <EventKit/EventKit.h>
#import <EventKitUI/EventKitUI.h>
@interface MyScheduleViewController () <EKEventEditViewDelegate>
// EKEventStore instance associated with the current Calendar application
@property (nonatomic, strong) EKEventStore *eventStore;
// Default calendar associated with the above event store
@property (nonatomic, strong) EKCalendar *defaultCalendar;
// Array of all events happening within the next 24 hours
@property (nonatomic, strong) NSMutableArray *eventsList;
// Used to add events to Calendar
@property (weak, nonatomic) IBOutlet UIBarButtonItem *addButton;
@end
@implementation MyScheduleViewController
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Initialize the event store
self.eventStore = [[EKEventStore alloc] init];
// Initialize the events list
self.eventsList = [[NSMutableArray alloc] initWithCapacity:0];
// The Add button is initially disabled
self.addButton.enabled = NO;
}
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// Check whether we are authorized to access Calendar
[self checkEventStoreAccessForCalendar];
}
// This method is called when the user selects an event in the table view. It configures the destination
// event view controller with this event.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"showEventViewController"])
{
// Configure the destination event view controller
EKEventViewController* eventViewController = (EKEventViewController *)[segue destinationViewController];
// Fetch the index path associated with the selected event
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
// Set the view controller to display the selected event
eventViewController.event = [self.eventsList objectAtIndex:indexPath.row];
// Allow event editing
eventViewController.allowsEditing = YES;
}
}
#pragma mark -
#pragma mark Table View
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.eventsList.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"eventCell" forIndexPath:indexPath];
// Get the event at the row selected and display its title
cell.textLabel.text = [[self.eventsList objectAtIndex:indexPath.row] title];
return cell;
}
#pragma mark -
#pragma mark Access Calendar
// Check the authorization status of our application for Calendar
-(void)checkEventStoreAccessForCalendar
{
EKAuthorizationStatus status = [EKEventStore authorizationStatusForEntityType:EKEntityTypeEvent];
switch (status)
{
// Update our UI if the user has granted access to their Calendar
case EKAuthorizationStatusAuthorized: [self accessGrantedForCalendar];
break;
// Prompt the user for access to Calendar if there is no definitive answer
case EKAuthorizationStatusNotDetermined: [self requestCalendarAccess];
break;
// Display a message if the user has denied or restricted access to Calendar
case EKAuthorizationStatusDenied:
case EKAuthorizationStatusRestricted:
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Privacy Warning" message:@"Permission was not granted for Calendar"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
break;
default:
break;
}
}
// Prompt the user for access to their Calendar
-(void)requestCalendarAccess
{
[self.eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error)
{
if (granted)
{
MyScheduleViewController * __weak weakSelf = self;
// Let's ensure that our code will be executed from the main queue
dispatch_async(dispatch_get_main_queue(), ^{
// The user has granted access to their Calendar; let's populate our UI with all events occuring in the next 24 hours.
[weakSelf accessGrantedForCalendar];
});
}
}];
}
// This method is called when the user has granted permission to Calendar
-(void)accessGrantedForCalendar
{
// Let's get the default calendar associated with our event store
self.defaultCalendar = self.eventStore.defaultCalendarForNewEvents;
// Enable the Add button
self.addButton.enabled = YES;
// Fetch all events happening in the next 24 hours and put them into eventsList
self.eventsList = [self fetchEvents];
// Update the UI with the above events
[self.tableView reloadData];
}
#pragma mark -
#pragma mark Fetch events
// Fetch all events happening in the next 24 hours
- (NSMutableArray *)fetchEvents
{
NSDate *startDate = [NSDate date];
//Create the end date components
NSDateComponents *tomorrowDateComponents = [[NSDateComponents alloc] init];
tomorrowDateComponents.day = 1;
NSDate *endDate = [[NSCalendar currentCalendar] dateByAddingComponents:tomorrowDateComponents
toDate:startDate
options:0];
// We will only search the default calendar for our events
NSArray *calendarArray = [NSArray arrayWithObject:self.defaultCalendar];
// Create the predicate
NSPredicate *predicate = [self.eventStore predicateForEventsWithStartDate:startDate
endDate:endDate
calendars:calendarArray];
// Fetch all events that match the predicate
NSMutableArray *events = [NSMutableArray arrayWithArray:[self.eventStore eventsMatchingPredicate:predicate]];
return events;
}
#pragma mark -
#pragma mark Add a new event
// Display an event edit view controller when the user taps the "+" button.
// A new event is added to Calendar when the user taps the "Done" button in the above view controller.
- (IBAction)addEvent:(id)sender
{
// Create an instance of EKEventEditViewController
EKEventEditViewController *addController = [[EKEventEditViewController alloc] init];
// Set addController's event store to the current event store
addController.eventStore = self.eventStore;
addController.editViewDelegate = self;
[self presentViewController:addController animated:YES completion:nil];
}
#pragma mark -
#pragma mark EKEventEditViewDelegate
// Overriding EKEventEditViewDelegate method to update event store according to user actions.
- (void)eventEditViewController:(EKEventEditViewController *)controller
didCompleteWithAction:(EKEventEditViewAction)action
{
MyScheduleViewController * __weak weakSelf = self;
// Dismiss the modal view controller
[self dismissViewControllerAnimated:YES completion:^
{
if (action != EKEventEditViewActionCanceled)
{
dispatch_async(dispatch_get_main_queue(), ^{
// Re-fetch all events happening in the next 24 hours
weakSelf.eventsList = [self fetchEvents];
// Update the UI with the above events
[weakSelf.tableView reloadData];
});
}
}];
}
// Set the calendar edited by EKEventEditViewController to our chosen calendar - the default calendar.
- (EKCalendar *)eventEditViewControllerDefaultCalendarForNewEvents:(EKEventEditViewController *)controller
{
return self.defaultCalendar;
}
@end