UNPKG

6.18 kBPlain TextView Raw
1// Copyright 2018-present 650 Industries. All rights reserved.
2
3#import <UMCore/UMDefines.h>
4#import <UMCore/UMUtilities.h>
5#import <UMCore/UMEventEmitterService.h>
6
7#import <UMConstantsInterface/UMConstantsInterface.h>
8
9#import <EXTaskManager/EXTaskManager.h>
10#import <EXTaskManager/EXTaskService.h>
11#import <UMTaskManagerInterface/UMTaskServiceInterface.h>
12
13NSString * const EXTaskManagerEventName = @"TaskManager.executeTask";
14
15@interface EXTaskManager ()
16
17@property (nonatomic, strong) NSString *appId;
18@property (nonatomic, strong) NSMutableArray<NSDictionary *> *eventsQueue;
19@property (nonatomic, weak) id<UMEventEmitterService> eventEmitter;
20@property (nonatomic, weak) id<UMConstantsInterface> constantsService;
21@property (nonatomic, weak) id<UMTaskServiceInterface> taskService;
22
23@end
24
25@implementation EXTaskManager
26
27UM_EXPORT_MODULE(ExpoTaskManager);
28
29+ (const NSArray<Protocol *> *)exportedInterfaces
30{
31 return @[@protocol(UMTaskManagerInterface)];
32}
33
34- (instancetype)init
35{
36 return [self initWithExperienceId:@"mainApplication"];
37}
38
39// TODO: Remove when adding bare React Native support
40- (instancetype)initWithExperienceId:(NSString *)experienceId
41{
42 if (self = [super init]) {
43 _appId = experienceId;
44 _eventsQueue = [NSMutableArray new];
45 }
46 return self;
47}
48
49- (void)setModuleRegistry:(UMModuleRegistry *)moduleRegistry
50{
51 _eventEmitter = [moduleRegistry getModuleImplementingProtocol:@protocol(UMEventEmitterService)];
52 _constantsService = [moduleRegistry getModuleImplementingProtocol:@protocol(UMConstantsInterface)];
53 _taskService = [moduleRegistry getSingletonModuleForName:@"TaskService"];
54
55 // Register task manager in task service.
56 [_taskService setTaskManager:self forAppId:_appId withUrl:[self _findAppUrl]];
57}
58
59- (NSDictionary *)constantsToExport
60{
61 return @{
62 @"EVENT_NAME": EXTaskManagerEventName,
63 };
64}
65
66# pragma mark - UMEventEmitter
67
68- (NSArray<NSString *> *)supportedEvents
69{
70 return @[EXTaskManagerEventName];
71}
72
73/**
74 * When `startObserving` is called, it means the app is ready to execute new tasks.
75 * It also sends all events that were queued before this call.
76 */
77- (void)startObserving
78{
79 if (_eventsQueue && _eventsQueue.count > 0) {
80 // Emit queued events
81 for (NSDictionary *eventBody in _eventsQueue) {
82 [_eventEmitter sendEventWithName:EXTaskManagerEventName body:eventBody];
83 }
84 }
85 _eventsQueue = nil;
86}
87
88- (void)stopObserving {}
89
90# pragma mark - Exported methods
91
92UM_EXPORT_METHOD_AS(notifyTaskFinishedAsync,
93 notifyTaskFinished:(nonnull NSString *)taskName
94 withResponse:(nonnull NSDictionary *)response
95 resolve:(UMPromiseResolveBlock)resolve
96 reject:(UMPromiseRejectBlock)reject)
97{
98 [_taskService notifyTaskWithName:taskName forAppId:_appId didFinishWithResponse:response];
99 resolve(nil);
100}
101
102UM_EXPORT_METHOD_AS(isTaskRegisteredAsync,
103 isTaskRegistered:(nonnull NSString *)taskName
104 resolve:(UMPromiseResolveBlock)resolve
105 reject:(UMPromiseRejectBlock)reject)
106{
107 resolve(@([self hasRegisteredTaskWithName:taskName]));
108}
109
110UM_EXPORT_METHOD_AS(getRegisteredTasksAsync,
111 getRegisteredTasks:(UMPromiseResolveBlock)resolve
112 reject:(UMPromiseRejectBlock)reject)
113{
114 resolve([_taskService getRegisteredTasksForAppId:_appId]);
115}
116
117UM_EXPORT_METHOD_AS(getTaskOptionsAsync,
118 getConfigurationForTaskName:(nonnull NSString *)taskName
119 resolve:(UMPromiseResolveBlock)resolve
120 reject:(UMPromiseRejectBlock)reject)
121{
122 resolve(UMNullIfNil([_taskService getOptionsForTaskName:taskName forAppId:_appId]));
123}
124
125UM_EXPORT_METHOD_AS(unregisterTaskAsync,
126 unregisterTaskWithName:(nonnull NSString *)taskName
127 resolve:(UMPromiseResolveBlock)resolve
128 reject:(UMPromiseRejectBlock)reject)
129{
130 @try {
131 [self unregisterTaskWithName:taskName consumerClass:nil];
132 } @catch (NSException *e) {
133 return reject(e.name, e.reason, nil);
134 }
135 resolve(nil);
136}
137
138UM_EXPORT_METHOD_AS(unregisterAllTasksAsync,
139 unregisterAllTasks:(UMPromiseResolveBlock)resolve
140 reject:(UMPromiseRejectBlock)reject)
141{
142 [_taskService unregisterAllTasksForAppId:_appId];
143 resolve(nil);
144}
145
146# pragma mark - UMTaskManagerInterface
147
148- (BOOL)hasRegisteredTaskWithName:(nonnull NSString *)taskName
149{
150 return [_taskService hasRegisteredTaskWithName:taskName forAppId:_appId];
151}
152
153- (BOOL)taskWithName:(nonnull NSString *)taskName hasConsumerOfClass:(Class)consumerClass
154{
155 return [_taskService taskWithName:taskName forAppId:_appId hasConsumerOfClass:consumerClass];
156}
157
158- (void)registerTaskWithName:(nonnull NSString *)taskName
159 consumer:(Class)consumerClass
160 options:(nonnull NSDictionary *)options
161{
162 NSString *appUrl = [self _findAppUrl];
163
164 [_taskService registerTaskWithName:taskName
165 appId:_appId
166 appUrl:appUrl
167 consumerClass:consumerClass
168 options:options];
169}
170
171- (void)unregisterTaskWithName:(nonnull NSString *)taskName
172 consumerClass:(Class)consumerClass
173{
174 [_taskService unregisterTaskWithName:taskName forAppId:_appId consumerClass:consumerClass];
175}
176
177- (BOOL)hasBackgroundModeEnabled:(nonnull NSString *)backgroundMode
178{
179 return [EXTaskService hasBackgroundModeEnabled:backgroundMode];
180}
181
182- (void)executeWithBody:(NSDictionary *)body
183{
184 if (!_eventsQueue) {
185 // Module's event emitter is already being observed, so we can send events.
186 [_eventEmitter sendEventWithName:EXTaskManagerEventName body:body];
187 } else {
188 // Otherwise add event body to the queue (it will be send in `startObserving`).
189 [_eventsQueue addObject:body];
190 }
191}
192
193- (BOOL)isRunningInHeadlessMode
194{
195 return [[_constantsService constants][@"isHeadless"] boolValue];
196}
197
198# pragma mark - internals
199
200- (NSString *)_findAppUrl
201{
202 // TODO(@tsapeta): find app url for vanilla RN apps
203 return [_constantsService constants][@"experienceUrl"];
204}
205
206@end