1 // 2 // ViewController.h 3 // Remind Me 4 // 5 // Created by Hans-Eric Grönlund on 8/28/12. 6 // Copyright (c) 2012 Hans-Eric Grönlund. All rights reserved. 7 // 8 9 #import <UIKit/UIKit.h> 10 #import <EventKit/EventKit.h> 11 #import <CoreLocation/CoreLocation.h> 12 13 typedef void(^RestrictedEventStoreActionHandler)(); 14 typedef void(^RetrieveCurrentLocationHandler)(CLLocation *); 15 16 @interface ViewController : UIViewController<CLLocationManagerDelegate> 17 { 18 @private 19 CLLocationManager *_locationManager; 20 RetrieveCurrentLocationHandler _retrieveCurrentLocationBlock; 21 int _numberOfTries; 22 } 23 24 @property (weak, nonatomic) IBOutlet UIButton *addTimeBasedReminderButton; 25 @property (weak, nonatomic) IBOutlet UIButton *addLocationBasedReminderButton; 26 @property (weak, nonatomic) IBOutlet UIActivityIndicatorView *activityIndicator; 27 @property (strong, nonatomic)EKEventStore *eventStore; 28 29 - (IBAction)addTimeBasedReminder:(id)sender; 30 - (IBAction)addLocationBasedReminder:(id)sender; 31 32 - (void)handleReminderAction:(RestrictedEventStoreActionHandler)block; 33 - (void)retrieveCurrentLocation:(RetrieveCurrentLocationHandler)block; 34 35 @end
1 // 2 // ViewController.m 3 // Remind Me 4 // 5 // Created by Hans-Eric Grönlund on 8/28/12. 6 // Copyright (c) 2012 Hans-Eric Grönlund. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 11 @interface ViewController () 12 13 @end 14 15 @implementation ViewController 16 17 - (EKEventStore *)eventStore 18 { 19 if (_eventStore == nil) 20 { 21 _eventStore = [[EKEventStore alloc] init]; 22 } 23 return _eventStore; 24 } 25 26 - (void)viewDidLoad 27 { 28 [super viewDidLoad]; 29 // Do any additional setup after loading the view, typically from a nib. 30 } 31 32 - (void)didReceiveMemoryWarning 33 { 34 [super didReceiveMemoryWarning]; 35 // Dispose of any resources that can be recreated. 36 } 37 38 - (void)handleReminderAction:(RestrictedEventStoreActionHandler)block 39 { 40 self.addTimeBasedReminderButton.enabled = NO; 41 self.addLocationBasedReminderButton.enabled = NO; 42 [self.eventStore requestAccessToEntityType:EKEntityTypeReminder 43 completion:^(BOOL granted, NSError *error) 44 { 45 if (granted) 46 { 47 block(); 48 } 49 else 50 { 51 UIAlertView *notGrantedAlert = [[UIAlertView alloc] initWithTitle:@"Access Denied" message:@"Access to device‘s reminders has been denied for this app." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; 52 53 dispatch_async(dispatch_get_main_queue(), ^{ 54 [notGrantedAlert show]; 55 }); 56 } 57 dispatch_async(dispatch_get_main_queue(), ^{ 58 self.addTimeBasedReminderButton.enabled = YES; 59 self.addLocationBasedReminderButton.enabled = YES; 60 }); 61 }]; 62 } 63 64 - (IBAction)addTimeBasedReminder:(id)sender 65 { 66 [self.activityIndicator startAnimating]; 67 68 [self handleReminderAction:^() 69 { 70 // Create Reminder 71 EKReminder *newReminder = [EKReminder reminderWithEventStore:self.eventStore]; 72 newReminder.title = @"Simpsons is on"; 73 newReminder.calendar = [self.eventStore defaultCalendarForNewReminders]; 74 75 // Calculate the date exactly one day from now 76 NSCalendar *calendar = [NSCalendar currentCalendar]; 77 NSDateComponents *oneDayComponents = [[NSDateComponents alloc] init]; 78 oneDayComponents.day = 1; 79 NSDate *nextDay = [calendar dateByAddingComponents:oneDayComponents toDate:[NSDate date] options:0]; 80 81 NSUInteger unitFlags = NSEraCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit; 82 NSDateComponents *tomorrowAt6PMComponents = [calendar components:unitFlags fromDate:nextDay]; 83 tomorrowAt6PMComponents.hour = 18; 84 tomorrowAt6PMComponents.minute = 0; 85 tomorrowAt6PMComponents.second = 0; 86 NSDate *nextDayAt6PM = [calendar dateFromComponents:tomorrowAt6PMComponents]; 87 88 // Create an Alarm 89 EKAlarm *alarm = [EKAlarm alarmWithAbsoluteDate:nextDayAt6PM]; 90 [newReminder addAlarm:alarm]; 91 newReminder.dueDateComponents = tomorrowAt6PMComponents; 92 93 // Save Reminder 94 NSString *alertTitle; 95 NSString *alertMessage; 96 NSString *alertButtonTitle; 97 NSError *error; 98 [self.eventStore saveReminder:newReminder commit:YES error:&error]; 99 if (error == nil) 100 { 101 alertTitle = @"Information"; 102 alertMessage = [NSString stringWithFormat:@"\"%@\" was added to Reminders", newReminder.title]; 103 alertButtonTitle = @"OK"; 104 } 105 else 106 { 107 alertTitle = @"Error"; 108 alertMessage = [NSString stringWithFormat:@"Unable to save reminder: %@", error]; 109 alertButtonTitle = @"Dismiss"; 110 } 111 112 dispatch_async(dispatch_get_main_queue(), ^{ 113 UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:alertTitle message:alertMessage delegate:nil cancelButtonTitle:alertButtonTitle otherButtonTitles:nil]; 114 [alertView show]; 115 [self.activityIndicator stopAnimating]; 116 }); 117 118 }]; 119 } 120 121 - (void)retrieveCurrentLocation:(RetrieveCurrentLocationHandler)block 122 { 123 if ([CLLocationManager locationServicesEnabled] == NO) 124 { 125 UIAlertView *locationServicesDisabledAlert = [[UIAlertView alloc] initWithTitle:@"Location Services Disabled" message:@"This feature requires location services. Enable it in the privacy settings on your device" delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles:nil]; 126 [locationServicesDisabledAlert show]; 127 return; 128 } 129 130 if (_locationManager == nil) 131 { 132 _locationManager = [[CLLocationManager alloc] init]; 133 _locationManager.desiredAccuracy = kCLLocationAccuracyBest; 134 _locationManager.distanceFilter = 1; // meter 135 _locationManager.activityType = CLActivityTypeOther; 136 _locationManager.delegate = self; 137 } 138 _numberOfTries = 0; 139 _retrieveCurrentLocationBlock = block; 140 [_locationManager startUpdatingLocation]; 141 } 142 143 - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations 144 { 145 // Make sure this is a recent location event 146 CLLocation *lastLocation = [locations lastObject]; 147 NSTimeInterval eventInterval = [lastLocation.timestamp timeIntervalSinceNow]; 148 if(fabs(eventInterval) < 30.0) 149 { 150 // Make sure the event is accurate enough 151 if (lastLocation.horizontalAccuracy >= 0 && lastLocation.horizontalAccuracy < 20) 152 { 153 [_locationManager stopUpdatingLocation]; 154 _retrieveCurrentLocationBlock(lastLocation); 155 return; 156 } 157 } 158 if (_numberOfTries++ == 10) 159 { 160 [_locationManager stopUpdatingLocation]; 161 UIAlertView *unableToGetLocationAlert = [[UIAlertView alloc]initWithTitle:@"Error" message:@"Unable to get the current location." delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles: nil]; 162 [unableToGetLocationAlert show]; 163 } 164 } 165 166 - (IBAction)addLocationBasedReminder:(id)sender 167 { 168 [self.activityIndicator startAnimating]; 169 170 [self retrieveCurrentLocation: 171 ^(CLLocation *currentLocation) 172 { 173 if (currentLocation != nil) 174 { 175 [self handleReminderAction:^() 176 { 177 // Create Reminder 178 EKReminder *newReminder = [EKReminder reminderWithEventStore:self.eventStore]; 179 newReminder.title = @"Buy milk!"; 180 newReminder.calendar = [self.eventStore defaultCalendarForNewReminders]; 181 182 // Create Location-based Alarm 183 EKStructuredLocation *currentStructuredLocation = [EKStructuredLocation locationWithTitle:@"Current Location"]; 184 currentStructuredLocation.geoLocation = currentLocation; 185 186 EKAlarm *alarm = [[EKAlarm alloc] init]; 187 alarm.structuredLocation = currentStructuredLocation; 188 alarm.proximity = EKAlarmProximityLeave; 189 190 [newReminder addAlarm:alarm]; 191 192 // Save Reminder 193 NSString *alertTitle; 194 NSString *alertMessage; 195 NSString *alertButtonTitle; 196 NSError *error; 197 [self.eventStore saveReminder:newReminder commit:YES error:&error]; 198 if (error == nil) 199 { 200 alertTitle = @"Information"; 201 alertMessage = [NSString stringWithFormat:@"\"%@\" was added to Reminders", newReminder.title]; 202 alertButtonTitle = @"OK"; 203 } 204 else 205 { 206 alertTitle = @"Error"; 207 alertMessage = [NSString stringWithFormat:@"Unable to save reminder: %@", error]; 208 alertButtonTitle = @"Dismiss"; 209 } 210 211 dispatch_async(dispatch_get_main_queue(), ^{ 212 UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:alertTitle message:alertMessage delegate:nil cancelButtonTitle:alertButtonTitle otherButtonTitles:nil]; 213 [alertView show]; 214 [self.activityIndicator stopAnimating]; 215 }); 216 }]; 217 } 218 }]; 219 } 220 @end
创建基于时间和基于位置的提醒事件,导入框架Event Kit与Core Location。
时间: 2024-08-24 17:38:44