Skip to content

Commit 6c82497

Browse files
committed
initial move to promises
1 parent a0ffb71 commit 6c82497

File tree

2 files changed

+91
-110
lines changed

2 files changed

+91
-110
lines changed

Diff for: README.md

+19-32
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# React-Native-Calendar-Events
22
React Native Module for IOS Calendar Events
33

4-
54
## Install
65
```
76
npm install react-native-calendar-events
@@ -12,12 +11,10 @@ For iOS 8 compatibility, you may need to link your project with `CoreFoundation.
1211

1312
## Usage
1413

15-
Require the `react-native-calendar-events` module and React Native's `NativeAppEventEmitter` module.
14+
Require the `react-native-calendar-events` module.
15+
1616
```javascript
17-
import React from 'react-native';
1817
import RNCalendarEvents from 'react-native-calendar-events';
19-
20-
const {NativeAppEventEmitter} = 'react-native';
2118
```
2219

2320
## Properties
@@ -36,61 +33,45 @@ const {NativeAppEventEmitter} = 'react-native';
3633
| notes | String | The notes associated with the calendar event. |
3734
| alarms | Array | The alarms associated with the calendar event, as an array of alarm objects. |
3835

39-
## Events
40-
41-
| Name | Body | Description |
42-
| :--------------- | :---------------- | :----------- |
43-
| calendarEventsChanged | (empty) | |
44-
| eventSaveSuccess | event id | The ID of the successfully saved event |
45-
| eventSaveError | error message | Error that occurred during save. |
46-
47-
Example:
48-
49-
```javascript
50-
componentWillMount () {
51-
this.eventEmitter = NativeAppEventEmitter.addListener('calendarEventsChanged', () => {
52-
RNCalendarEvents.fetchAllEvents(startDate, endDate, events => {...});
53-
});
54-
}
55-
56-
componentWillUnmount () {
57-
this.eventEmitter.remove();
58-
}
59-
```
6036

6137
## Get authorization status for IOS EventStore
62-
Finds the current authorization status: "denied", "restricted", "authorized" or "undetermined".
38+
Returns a promise with fulfilled authorization status of "denied", "restricted", "authorized" or "undetermined".
6339

6440
```javascript
65-
RNCalendarEvents.authorizationStatus(({status}) => {...});
41+
RNCalendarEvents.authorizationStatus();
6642
```
6743

6844
## Request authorization to IOS EventStore
6945
Authorization must be granted before accessing calendar events.
46+
Returns a promise with fulfilled authorization status of "denied", "restricted", "authorized" or "undetermined".
7047

7148
```javascript
72-
RNCalendarEvents.authorizeEventStore(({status}) => {...});
49+
RNCalendarEvents.authorizeEventStore();
7350
```
7451

75-
7652
## Fetch all calendar events from EventStore
53+
Returns a promise with fulfilled with found events.
7754

7855
```javascript
79-
RNCalendarEvents.fetchAllEvents(startDate, endDate, events => {...});
56+
RNCalendarEvents.fetchAllEvents(startDate, endDate);
8057
```
58+
8159
## Create calendar event
60+
Returns a promise with fulfilled with the created event's id.
8261

8362
```
8463
RNCalendarEvents.saveEvent(title, settings);
8564
```
8665
Example:
66+
8767
```javascript
8868
RNCalendarEvents.saveEvent('title', {
8969
location: 'location',
9070
notes: 'notes',
9171
startDate: '2016-10-01T09:45:00.000UTC',
9272
endDate: '2016-10-02T09:45:00.000UTC'
93-
});
73+
})
74+
.then(eventId => {...});
9475
```
9576

9677
## Create calendar event with alarms
@@ -123,6 +104,7 @@ RNCalendarEvents.saveEvent('title', {
123104
date: -1 // or absolute date
124105
}]
125106
});
107+
126108
```
127109
Example with structuredLocation:
128110

@@ -163,6 +145,7 @@ RNCalendarEvents.saveEvent('title', {
163145

164146
## Update calendar event
165147
Give the unique calendar event **id** to update an existing calendar event.
148+
Returns a promise with fulfilled with updated event's id.
166149

167150
```javascript
168151
RNCalendarEvents.saveEvent('title', {
@@ -176,13 +159,17 @@ RNCalendarEvents.saveEvent('title', {
176159

177160
## Remove calendar event
178161
Give the unique calendar event instance **id** to remove the calendar event.
162+
Returns a promise with fulfilled with updated event's id.
163+
179164

180165
```javascript
181166
RNCalendarEvents.removeEvent('id');
182167
```
183168

184169
## Remove future (recurring) calendar events
185170
Give the unique calendar event instance **id** to remove future calendar events.
171+
Returns a promise with fulfilled with updated event's id.
172+
186173

187174
```javascript
188175
RNCalendarEvents.removeFutureEvents('id');

Diff for: RNCalendarEvents.m

+72-78
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#import "RNCalendarEvents.h"
22
#import "RCTConvert.h"
3+
#import "RCTUtils.h"
34
#import <EventKit/EventKit.h>
45

56
@interface RNCalendarEvents ()
@@ -61,7 +62,6 @@ - (NSString *)authorizationStatusForEventStore
6162
self.isAccessToEventStoreGranted = NO;
6263
return @"restricted";
6364
case EKAuthorizationStatusAuthorized:
64-
[self addNotificationCenter];
6565
self.isAccessToEventStoreGranted = YES;
6666
return @"authorized";
6767
case EKAuthorizationStatusNotDetermined: {
@@ -73,29 +73,14 @@ - (NSString *)authorizationStatusForEventStore
7373
#pragma mark -
7474
#pragma mark Event Store Accessors
7575

76-
- (void)addCalendarEvent:(NSString *)title details:(NSDictionary *)details
76+
- (NSDictionary *)buildAndSaveEvent:(NSDictionary *)details
7777
{
78-
if (!self.isAccessToEventStoreGranted) {
79-
return;
80-
}
81-
82-
EKEvent *calendarEvent = [EKEvent eventWithEventStore:self.eventStore];
83-
calendarEvent.calendar = [self.eventStore defaultCalendarForNewEvents];
84-
85-
[self buildAndSaveEvent:calendarEvent details:details];
86-
}
87-
88-
- (void)editEvent:(EKEvent *)calendarEvent details:(NSDictionary *)details
89-
{
90-
if (!self.isAccessToEventStoreGranted) {
91-
return;
78+
if ([[self authorizationStatusForEventStore] isEqualToString:@"granted"]) {
79+
return @{@"success": [NSNull null], @"error": @"unauthorized to access calendar"};
9280
}
9381

94-
[self buildAndSaveEvent:calendarEvent details:details];
95-
}
96-
97-
-(void)buildAndSaveEvent:(EKEvent *)calendarEvent details:(NSDictionary *)details
98-
{
82+
EKEvent *calendarEvent = nil;
83+
NSString *eventId = [RCTConvert NSString:details[_id]];
9984
NSString *title = [RCTConvert NSString:details[_title]];
10085
NSString *location = [RCTConvert NSString:details[_location]];
10186
NSDate *startDate = [RCTConvert NSDate:details[_startDate]];
@@ -105,6 +90,14 @@ -(void)buildAndSaveEvent:(EKEvent *)calendarEvent details:(NSDictionary *)detail
10590
NSArray *alarms = [RCTConvert NSArray:details[_alarms]];
10691
NSString *recurrence = [RCTConvert NSString:details[_recurrence]];
10792

93+
if (eventId) {
94+
calendarEvent = (EKEvent *)[self.eventStore calendarItemWithIdentifier:eventId];
95+
96+
} else {
97+
calendarEvent = [EKEvent eventWithEventStore:self.eventStore];
98+
calendarEvent.calendar = [self.eventStore defaultCalendarForNewEvents];
99+
}
100+
108101
if (title) {
109102
calendarEvent.title = title;
110103
}
@@ -141,36 +134,43 @@ -(void)buildAndSaveEvent:(EKEvent *)calendarEvent details:(NSDictionary *)detail
141134
calendarEvent.URL = URL;
142135
}
143136

144-
[self saveEvent:calendarEvent];
137+
return [self saveEvent:calendarEvent];
145138
}
146139

147-
-(void)saveEvent:(EKEvent *)calendarEvent
140+
- (NSDictionary *)saveEvent:(EKEvent *)calendarEvent
148141
{
142+
NSMutableDictionary *response = [NSMutableDictionary dictionaryWithDictionary:@{@"success": [NSNull null], @"error": [NSNull null]}];
143+
149144
NSError *error = nil;
150145
BOOL success = [self.eventStore saveEvent:calendarEvent span:EKSpanFutureEvents commit:YES error:&error];
146+
151147
if (!success) {
152-
[self.bridge.eventDispatcher sendAppEventWithName:@"eventSaveError"
153-
body:@{@"error": [error.userInfo valueForKey:@"NSLocalizedDescription"]}];
148+
[response setValue:[error.userInfo valueForKey:@"NSLocalizedDescription"] forKey:@"error"];
154149
} else {
155-
[self.bridge.eventDispatcher sendAppEventWithName:@"eventSaveSuccess"
156-
body:calendarEvent.calendarItemIdentifier];
150+
[response setValue:calendarEvent.calendarItemIdentifier forKey:@"success"];
157151
}
152+
return [response copy];
158153
}
159154

160-
- (void)deleteEvent:(NSString *)eventId span:(EKSpan *)span
155+
- (NSDictionary *)deleteEvent:(NSString *)eventId span:(EKSpan *)span
161156
{
162-
if (!self.isAccessToEventStoreGranted) {
163-
return;
157+
if ([[self authorizationStatusForEventStore] isEqualToString:@"granted"]) {
158+
return @{@"success": [NSNull null], @"error": @"unauthorized to access calendar"};
164159
}
165160

161+
NSMutableDictionary *response = [NSMutableDictionary dictionaryWithDictionary:@{@"success": [NSNull null], @"error": [NSNull null]}];
162+
166163
EKEvent *calendarEvent = (EKEvent *)[self.eventStore calendarItemWithIdentifier:eventId];
164+
167165
NSError *error = nil;
168166
BOOL success = [self.eventStore removeEvent:calendarEvent span:span commit:YES error:&error];
169167

170168
if (!success) {
171-
[self.bridge.eventDispatcher sendAppEventWithName:@"eventSaveError"
172-
body:@{@"error": [error.userInfo valueForKey:@"NSLocalizedDescription"]}];
169+
[response setValue:[error.userInfo valueForKey:@"NSLocalizedDescription"] forKey:@"error"];
170+
} else {
171+
[response setValue:@YES forKey:@"success"];
173172
}
173+
return [response copy];
174174
}
175175

176176
#pragma mark -
@@ -403,7 +403,7 @@ - (NSArray *)serializeCalendarEvents:(NSArray *)calendarEvents
403403
if (event.occurrenceDate) {
404404
[formedCalendarEvent setValue:[dateFormatter stringFromDate:event.occurrenceDate] forKey:_occurrenceDate];
405405
}
406-
406+
407407
[formedCalendarEvent setValue:[NSNumber numberWithBool:event.isDetached] forKey:_isDetached];
408408

409409
[formedCalendarEvent setValue:[NSNumber numberWithBool:event.allDay] forKey:_allDay];
@@ -419,56 +419,36 @@ - (NSArray *)serializeCalendarEvents:(NSArray *)calendarEvents
419419
return [serializedCalendarEvents copy];
420420
}
421421

422-
#pragma mark -
423-
#pragma mark notifications
424-
425-
- (void)addNotificationCenter
426-
{
427-
[[NSNotificationCenter defaultCenter] addObserver:self
428-
selector:@selector(calendarEventUpdateReceived:)
429-
name:EKEventStoreChangedNotification
430-
object:nil];
431-
}
432-
433-
- (void)calendarEventUpdateReceived:(NSNotification *)notification
434-
{
435-
__weak RNCalendarEvents *weakSelf = self;
436-
dispatch_async(dispatch_get_main_queue(), ^{
437-
[weakSelf.bridge.eventDispatcher sendAppEventWithName:@"calendarEventsChanged"
438-
body:nil];
439-
});
440-
}
441-
442-
- (void) dealloc
443-
{
444-
[[NSNotificationCenter defaultCenter] removeObserver:self];
445-
}
446-
447422
#pragma mark -
448423
#pragma mark RCT Exports
449424

450-
RCT_EXPORT_METHOD(authorizationStatus:(RCTResponseSenderBlock)callback)
425+
RCT_EXPORT_METHOD(authorizationStatus:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
451426
{
452427
NSString *status = [self authorizationStatusForEventStore];
453-
callback(@[@{@"status": status}]);
428+
if (status) {
429+
resolve(status);
430+
} else {
431+
reject(@"error", @"authorization status error", nil);
432+
}
454433
}
455434

456-
RCT_EXPORT_METHOD(authorizeEventStore:(RCTResponseSenderBlock)callback)
435+
RCT_EXPORT_METHOD(authorizeEventStore:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
457436
{
458437
__weak RNCalendarEvents *weakSelf = self;
459438
[self.eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
460439
dispatch_async(dispatch_get_main_queue(), ^{
461440
NSString *status = granted ? @"authorized" : @"denied";
462441
weakSelf.isAccessToEventStoreGranted = granted;
463442
if (!error) {
464-
[weakSelf addNotificationCenter];
465-
callback(@[@{@"status": status}]);
443+
resolve(status);
444+
} else {
445+
reject(@"error", @"authorization request error", error);
466446
}
467447
});
468448
}];
469449
}
470450

471-
RCT_EXPORT_METHOD(fetchAllEvents:(NSDate *)startDate endDate:(NSDate *)endDate callback:(RCTResponseSenderBlock)callback)
451+
RCT_EXPORT_METHOD(fetchAllEvents:(NSDate *)startDate endDate:(NSDate *)endDate resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
472452
{
473453
NSPredicate *predicate = [self.eventStore predicateForEventsWithStartDate:startDate
474454
endDate:endDate
@@ -478,35 +458,49 @@ - (void) dealloc
478458
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
479459
weakSelf.calendarEvents = [[weakSelf.eventStore eventsMatchingPredicate:predicate] sortedArrayUsingSelector:@selector(compareStartDateWithEvent:)];
480460
dispatch_async(dispatch_get_main_queue(), ^{
481-
callback(@[[weakSelf serializeCalendarEvents:weakSelf.calendarEvents]]);
461+
if (weakSelf.calendarEvents) {
462+
resolve([weakSelf serializeCalendarEvents:weakSelf.calendarEvents]);
463+
} else {
464+
reject(@"error", @"calendar event request error", nil);
465+
}
482466
});
483467
});
484468
}
485469

486-
RCT_EXPORT_METHOD(saveEvent:(NSString *)title details:(NSDictionary *)details)
470+
RCT_EXPORT_METHOD(saveEvent:(NSString *)title details:(NSDictionary *)details resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
487471
{
488-
NSString *eventId = [RCTConvert NSString:details[_id]];
489-
490-
NSMutableDictionary* options = [NSMutableDictionary dictionaryWithDictionary:details];
472+
NSMutableDictionary *options = [NSMutableDictionary dictionaryWithDictionary:details];
491473
[options setValue:title forKey:_title];
492474

493-
if (eventId) {
494-
EKEvent *calendarEvent = (EKEvent *)[self.eventStore calendarItemWithIdentifier:eventId];
495-
[self editEvent:calendarEvent details:options];
475+
NSDictionary *response = [self buildAndSaveEvent:options];
496476

477+
if ([response valueForKey:@"success"] != [NSNull null]) {
478+
resolve([response valueForKey:@"success"]);
497479
} else {
498-
[self addCalendarEvent:title details:options];
480+
reject(@"error", [response valueForKey:@"error"], nil);
499481
}
500482
}
501483

502-
RCT_EXPORT_METHOD(removeEvent:(NSString *)eventId)
484+
RCT_EXPORT_METHOD(removeEvent:(NSString *)eventId resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
503485
{
504-
[self deleteEvent:eventId span:EKSpanThisEvent];
486+
NSDictionary *response = [self deleteEvent:eventId span:EKSpanThisEvent];
487+
488+
if ([response valueForKey:@"success"] != [NSNull null]) {
489+
resolve([response valueForKey:@"success"]);
490+
} else {
491+
reject(@"error", [response valueForKey:@"error"], nil);
492+
}
505493
}
506494

507-
RCT_EXPORT_METHOD(removeFutureEvents:(NSString *)eventId)
495+
RCT_EXPORT_METHOD(removeFutureEvents:(NSString *)eventId resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
508496
{
509-
[self deleteEvent:eventId span:EKSpanFutureEvents];
497+
NSDictionary *response = [self deleteEvent:eventId span:EKSpanFutureEvents];
498+
499+
if ([response valueForKey:@"success"] != [NSNull null]) {
500+
resolve([response valueForKey:@"success"]);
501+
} else {
502+
reject(@"error", [response valueForKey:@"error"], nil);
503+
}
510504
}
511505

512-
@end
506+
@end

0 commit comments

Comments
 (0)