1// Copyright 2018-present 650 Industries. All rights reserved. 2 3#import <EXNotifications/EXNotificationsHandlerModule.h> 4#import <EXNotifications/EXNotificationSerializer.h> 5#import <EXNotifications/EXNotificationCenterDelegate.h> 6 7#import <ExpoModulesCore/EXEventEmitterService.h> 8 9@interface EXNotificationsHandlerModule () 10 11@property (nonatomic, weak) id<EXNotificationCenterDelegate> notificationCenterDelegate; 12 13@property (nonatomic, assign) BOOL isListening; 14@property (nonatomic, assign) BOOL isBeingObserved; 15 16@property (nonatomic, weak) id<EXEventEmitterService> eventEmitter; 17 18@property (nonatomic, strong) NSMutableDictionary<NSString *, EXSingleNotificationHandlerTask *> *tasksMap; 19 20@end 21 22@implementation EXNotificationsHandlerModule 23 24EX_EXPORT_MODULE(ExpoNotificationsHandlerModule); 25 26- (instancetype)init 27{ 28 if (self = [super init]) { 29 _tasksMap = [NSMutableDictionary dictionary]; 30 } 31 return self; 32} 33 34# pragma mark - Exported methods 35 36EX_EXPORT_METHOD_AS(handleNotificationAsync, 37 handleNotificationAsync:(NSString *)identifier withBehavior:(NSDictionary *)behavior resolver:(EXPromiseResolveBlock)resolve rejecter:(EXPromiseRejectBlock)reject) 38{ 39 EXSingleNotificationHandlerTask *task = _tasksMap[identifier]; 40 if (!task) { 41 NSString *message = [NSString stringWithFormat:@"Failed to handle notification %@, it has already been handled.", identifier]; 42 return reject(@"ERR_NOTIFICATION_HANDLED", message, nil); 43 } 44 NSError *error = [task handleResponse:behavior]; 45 if (error) { 46 return reject(error.userInfo[@"code"], error.userInfo[@"message"], error); 47 } else { 48 resolve(nil); 49 } 50} 51 52# pragma mark - EXModuleRegistryConsumer 53 54- (void)setModuleRegistry:(EXModuleRegistry *)moduleRegistry 55{ 56 _eventEmitter = [moduleRegistry getModuleImplementingProtocol:@protocol(EXEventEmitterService)]; 57 _notificationCenterDelegate = [moduleRegistry getSingletonModuleForName:@"NotificationCenterDelegate"]; 58} 59 60# pragma mark - EXEventEmitter 61 62- (NSArray<NSString *> *)supportedEvents 63{ 64 return [EXSingleNotificationHandlerTask eventNames]; 65} 66 67- (void)startObserving 68{ 69 [self setIsBeingObserved:YES]; 70} 71 72- (void)stopObserving 73{ 74 [self setIsBeingObserved:NO]; 75} 76 77- (void)setIsBeingObserved:(BOOL)isBeingObserved 78{ 79 _isBeingObserved = isBeingObserved; 80 BOOL shouldListen = _isBeingObserved; 81 if (shouldListen && !_isListening) { 82 [_notificationCenterDelegate addDelegate:self]; 83 _isListening = YES; 84 } else if (!shouldListen && _isListening) { 85 [_notificationCenterDelegate removeDelegate:self]; 86 _isListening = NO; 87 } 88} 89 90# pragma mark - EXNotificationsDelegate 91 92- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler 93{ 94 EXSingleNotificationHandlerTask *task = [[EXSingleNotificationHandlerTask alloc] initWithEventEmitter:_eventEmitter 95 notification:notification 96 completionHandler:completionHandler 97 delegate:self]; 98 [_tasksMap setObject:task forKey:task.identifier]; 99 [task start]; 100} 101 102# pragma mark - EXSingleNotificationHandlerTaskDelegate 103 104- (void)taskDidFinish:(EXSingleNotificationHandlerTask *)task 105{ 106 [_tasksMap removeObjectForKey:task.identifier]; 107} 108 109@end 110