Skip to content

Commit fa124db

Browse files
author
Ron Radtke
committed
ios part version 2
1 parent ebbbe17 commit fa124db

9 files changed

+74
-115
lines changed

index.js

-10
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,6 @@ const {
3636
const Blob = polyfill.Blob;
3737
const wrap = URIUtil.wrap;
3838

39-
// when app resumes, check if there's any expired network task and trigger
40-
// their .expire event
41-
if (Platform.OS === 'ios') {
42-
AppState.addEventListener('change', (e) => {
43-
if (e === 'active')
44-
ReactNativeBlobUtil.emitExpiredEvent(() => {
45-
});
46-
});
47-
}
48-
4939
// Show warning if native module not detected
5040
if (!ReactNativeBlobUtil || !ReactNativeBlobUtil.fetchBlobForm || !ReactNativeBlobUtil.fetchBlob) {
5141
console.warn(

ios/ReactNativeBlobUtil/ReactNativeBlobUtil.h

+5-4
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@
1616
#import <React/RCTLog.h>
1717
#import <React/RCTRootView.h>
1818
#import <React/RCTBridge.h>
19-
#import <React/RCTEventDispatcher.h>
2019
#import <React/RCTBridgeModule.h>
20+
#import <React/RCTEventEmitter.h>
2121
#else
2222
#import "RCTBridgeModule.h"
2323
#import "RCTLog.h"
2424
#import "RCTRootView.h"
2525
#import "RCTBridge.h"
26-
#import "RCTEventDispatcher.h"
26+
#import "RCTEventEmitter.h"
2727
#endif
2828

2929
#import <UIKit/UIKit.h>
@@ -33,7 +33,7 @@
3333
#endif
3434

3535

36-
@interface ReactNativeBlobUtil : NSObject <RCTBridgeModule, UIDocumentInteractionControllerDelegate> {
36+
@interface ReactNativeBlobUtil : RCTEventEmitter <RCTBridgeModule, UIDocumentInteractionControllerDelegate> {
3737

3838
NSString * filePathPrefix;
3939

@@ -42,7 +42,8 @@
4242
@property (nonatomic) NSString * filePathPrefix;
4343
@property (retain) UIDocumentInteractionController * documentController;
4444

45-
+ (RCTEventDispatcher *)getRCTEventDispatcher;
45+
-(void) emitEvent:(NSString *)name body:(NSString *) body;
46+
-(void) emitEventDict:(NSString *)name body:(NSDictionary *) body;
4647

4748
@end
4849

ios/ReactNativeBlobUtil/ReactNativeBlobUtil.mm

+39-26
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#import <ReactNativeBlobUtilSpec/ReactNativeBlobUtilSpec.h>
1616
#endif
1717

18-
__strong RCTEventDispatcher * eventDispatcherRef;
1918
dispatch_queue_t commonTaskQueue;
2019
dispatch_queue_t fsQueue;
2120

@@ -32,22 +31,47 @@ @implementation ReactNativeBlobUtil
3231
@synthesize filePathPrefix;
3332
@synthesize documentController;
3433
@synthesize bridge;
34+
bool hasListeners;
35+
36+
// Will be called when this module's first listener is added.
37+
-(void)startObserving {
38+
hasListeners = YES;
39+
// Set up any upstream listeners or background tasks as necessary
40+
}
41+
42+
// Will be called when this module's last listener is removed, or on dealloc.
43+
-(void)stopObserving {
44+
hasListeners = NO;
45+
// Remove upstream listeners, stop unnecessary background tasks
46+
}
47+
48+
- (void)emitEvent:(NSString *)name body:(NSString *) body
49+
{
50+
if (hasListeners) {// Only send events if anyone is listening
51+
[self sendEventWithName:name body:body];
52+
}
53+
}
54+
- (void)emitEventDict:(NSString *)name body:(NSDictionary *) body
55+
{
56+
NSError *error;
57+
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:body
58+
options:NSJSONWritingPrettyPrinted
59+
error:&error];
60+
61+
if (error) {
62+
NSLog(@"Got an error: %@", error);
63+
} else {
64+
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
65+
[self emitEvent:name body:jsonString];
66+
}
67+
}
3568

3669
- (dispatch_queue_t) methodQueue {
3770
if(commonTaskQueue == nil)
3871
commonTaskQueue = dispatch_queue_create("ReactNativeBlobUtil.queue", DISPATCH_QUEUE_SERIAL);
3972
return commonTaskQueue;
4073
}
4174

42-
+ (RCTEventDispatcher *)getRCTEventDispatcher
43-
{
44-
RCTRootView * rootView = (RCTRootView*) [[UIApplication sharedApplication] keyWindow].rootViewController.view;
45-
#if RCT_NEW_ARCH_ENABLED
46-
return (RCTEventDispatcher *)[rootView.moduleRegistry moduleForName:"EventDispatcher"];
47-
#else
48-
return rootView.bridge.eventDispatcher;
49-
#endif
50-
}
5175

5276
+ (BOOL)requiresMainQueueSetup {
5377
return NO;
@@ -67,10 +91,6 @@ - (id) init {
6791
if(![[NSFileManager defaultManager] fileExistsAtPath: [ReactNativeBlobUtilFS getTempPath] isDirectory:&isDir]) {
6892
[[NSFileManager defaultManager] createDirectoryAtPath:[ReactNativeBlobUtilFS getTempPath] withIntermediateDirectories:YES attributes:nil error:NULL];
6993
}
70-
dispatch_async(dispatch_get_main_queue(), ^{
71-
eventDispatcherRef = bridge.eventDispatcher;
72-
[ReactNativeBlobUtilNetwork emitExpiredTasks: eventDispatcherRef];
73-
});
7494

7595
return self;
7696
}
@@ -96,7 +116,7 @@ - (NSDictionary *)constantsToExport
96116
@"SDCardDir": @"",
97117
@"SDCardApplicationDir": @"",
98118
@"DCIMDir": @"",
99-
// Android only legacy constants
119+
// Android only legacy constants
100120
@"LegacyDCIMDir": @"",
101121
@"LegacyPictureDir": @"",
102122
@"LegacyMusicDir": @"",
@@ -135,7 +155,7 @@ - (NSDictionary *)constantsToExport
135155
{
136156
[[ReactNativeBlobUtilNetwork sharedInstance] sendRequest:options
137157
contentLength:bodyLength
138-
eventDispatcher:eventDispatcherRef
158+
baseModule:self
139159
taskId:taskId
140160
withRequest:req
141161
callback:callback];
@@ -172,7 +192,7 @@ - (NSDictionary *)constantsToExport
172192
{
173193
[[ReactNativeBlobUtilNetwork sharedInstance] sendRequest:options
174194
contentLength:bodyLength
175-
eventDispatcher:eventDispatcherRef
195+
baseModule:self
176196
taskId:taskId
177197
withRequest:req
178198
callback:callback];
@@ -366,7 +386,7 @@ - (void)writeFileArray:(NSString *)path
366386
appendData:(BOOL)append
367387
callback:(RCTResponseSenderBlock)callback)
368388
{
369-
ReactNativeBlobUtilFS * fileStream = [[ReactNativeBlobUtilFS alloc] initWithEventDispatcherRef:eventDispatcherRef];
389+
ReactNativeBlobUtilFS * fileStream = [[ReactNativeBlobUtilFS alloc] init];
370390
NSFileManager * fm = [NSFileManager defaultManager];
371391
NSString * folder = [path stringByDeletingLastPathComponent];
372392
NSError* err = nil;
@@ -696,7 +716,7 @@ - (void)hash:(NSString *)path
696716
}
697717

698718
dispatch_async(fsQueue, ^{
699-
[ReactNativeBlobUtilFS readStream:path encoding:encoding bufferSize:bufferSize tick:tick streamId:streamId eventDispatcherRef:eventDispatcherRef];
719+
[ReactNativeBlobUtilFS readStream:path encoding:encoding bufferSize:bufferSize tick:tick streamId:streamId baseModule:self];
700720
});
701721
}
702722

@@ -877,13 +897,6 @@ - (UIViewController *)documentInteractionControllerViewControllerForPreview: (UI
877897
return window.rootViewController;
878898
}
879899

880-
# pragma mark - check expired network events
881-
882-
RCT_EXPORT_METHOD(emitExpiredEvent:(RCTResponseSenderBlock)callback)
883-
{
884-
[ReactNativeBlobUtilNetwork emitExpiredTasks:eventDispatcherRef];
885-
}
886-
887900
# pragma mark - Android Only methods
888901
// These methods are required because in the New Arch we have a single spec for both platforms
889902
- (void)actionViewIntent:(NSString *) path

ios/ReactNativeBlobUtilFS.h

+1-4
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
NSOutputStream * outStream;
2525
NSInputStream * inStream;
2626
RCTResponseSenderBlock callback;
27-
RCTEventDispatcher * eventDispatcher;
2827
Boolean isOpen;
2928
NSString * encoding;
3029
int bufferSize;
@@ -37,7 +36,6 @@
3736
@property (nonatomic) NSOutputStream * _Nullable outStream;
3837
@property (nonatomic) NSInputStream * _Nullable inStream;
3938
@property (strong, nonatomic) RCTResponseSenderBlock callback;
40-
@property (nonatomic) RCTEventDispatcher * eventDispatcher;
4139
@property (nonatomic) NSString * encoding;
4240
@property (nonatomic) NSString * taskId;
4341
@property (nonatomic) NSString * path;
@@ -85,13 +83,12 @@
8583
rejecter:(RCTPromiseRejectBlock)reject;
8684
//+ (void) writeFileFromFile:(NSString *)src toFile:(NSString *)dest append:(BOOL)append;
8785
+ (void) writeAssetToPath:(ALAssetRepresentation * )rep dest:(NSString *)dest;
88-
+ (void) readStream:(NSString *)uri encoding:(NSString * )encoding bufferSize:(int)bufferSize tick:(int)tick streamId:(NSString *)streamId eventDispatcherRef:(RCTEventDispatcher *)eventDispatcherRef;
86+
+ (void) readStream:(NSString *)uri encoding:(NSString * )encoding bufferSize:(int)bufferSize tick:(int)tick streamId:(NSString *)streamId baseModule:(ReactNativeBlobUtil *)baseModule;
8987
+ (void) df:(RCTResponseSenderBlock)callback;
9088

9189
// constructor
9290
- (id) init;
9391
- (id)initWithCallback:(RCTResponseSenderBlock)callback;
94-
- (id)initWithEventDispatcherRef:(RCTEventDispatcher *)eventDispatcherRef;
9592

9693
// file stream
9794
- (void) openWithDestination;

ios/ReactNativeBlobUtilFS.mm

+15-24
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,8 @@
1717

1818
#if __has_include(<React/RCTAssert.h>)
1919
#import <React/RCTBridge.h>
20-
#import <React/RCTEventDispatcher.h>
2120
#else
2221
#import "RCTBridge.h"
23-
#import "RCTEventDispatcher.h"
2422
#endif
2523

2624

@@ -58,12 +56,6 @@ - (id)initWithCallback:(RCTResponseSenderBlock)callback {
5856
return self;
5957
}
6058

61-
- (id)initWithEventDispatcherRef:(RCTEventDispatcher *)eventDispatcherRef {
62-
self = [super init];
63-
self.eventDispatcher = eventDispatcherRef;
64-
return self;
65-
}
66-
6759
// static member getter
6860
+ (NSDictionary *) getFileStreams {
6961

@@ -160,11 +152,10 @@ + (void) readStream:(NSString *)uri
160152
bufferSize:(int)bufferSize
161153
tick:(int)tick
162154
streamId:(NSString *)streamId
163-
eventDispatcherRef:(RCTEventDispatcher *)eventDispatcherRef
155+
baseModule:(ReactNativeBlobUtil*)baseModule
164156
{
165157
[[self class] getPathFromUri:uri completionHandler:^(NSString *path, ALAssetRepresentation *asset) {
166158

167-
__block RCTEventDispatcher * event = eventDispatcherRef;
168159
__block int read = 0;
169160
__block int backoff = tick *1000;
170161
__block int chunkSize = bufferSize;
@@ -179,15 +170,15 @@ + (void) readStream:(NSString *)uri
179170
{
180171
NSString * message = [NSString stringWithFormat:@"File does not exist at path %@", path];
181172
NSDictionary * payload = @{ @"event": FS_EVENT_ERROR, @"code": @"ENOENT", @"detail": message };
182-
[event sendDeviceEventWithName:streamId body:payload];
173+
[baseModule emitEventDict:streamId body:payload];
183174
free(buffer);
184175
return ;
185176
}
186177
NSInputStream * stream = [[NSInputStream alloc] initWithFileAtPath:path];
187178
[stream open];
188179
while((read = [stream read:buffer maxLength:bufferSize]) > 0)
189180
{
190-
[[self class] emitDataChunks:[NSData dataWithBytes:buffer length:read] encoding:encoding streamId:streamId event:event];
181+
[[self class] emitDataChunks:[NSData dataWithBytes:buffer length:read] encoding:encoding streamId:streamId baseModule:baseModule];
191182
if(tick > 0)
192183
{
193184
usleep(backoff);
@@ -202,7 +193,7 @@ + (void) readStream:(NSString *)uri
202193
while((read = [asset getBytes:buffer fromOffset:cursor length:bufferSize error:&err]) > 0)
203194
{
204195
cursor += read;
205-
[[self class] emitDataChunks:[NSData dataWithBytes:buffer length:read] encoding:encoding streamId:streamId event:event];
196+
[[self class] emitDataChunks:[NSData dataWithBytes:buffer length:read] encoding:encoding streamId:streamId baseModule:baseModule];
206197
if(tick > 0)
207198
{
208199
usleep(backoff);
@@ -212,7 +203,7 @@ + (void) readStream:(NSString *)uri
212203
else
213204
{
214205
NSDictionary * payload = @{ @"event": FS_EVENT_ERROR, @"code": @"EINVAL", @"detail": @"Unable to resolve URI" };
215-
[event sendDeviceEventWithName:streamId body:payload];
206+
[baseModule emitEventDict:streamId body:payload];
216207
}
217208
// release buffer
218209
if(buffer != nil)
@@ -222,12 +213,12 @@ + (void) readStream:(NSString *)uri
222213
@catch (NSError * err)
223214
{
224215
NSDictionary * payload = @{ @"event": FS_EVENT_ERROR, @"code": @"EUNSPECIFIED", @"detail": [err description] };
225-
[event sendDeviceEventWithName:streamId body:payload];
216+
[baseModule emitEventDict:streamId body:payload];
226217
}
227218
@finally
228219
{
229220
NSDictionary * payload = @{ @"event": FS_EVENT_END, @"detail": @"" };
230-
[event sendDeviceEventWithName:streamId body:payload];
221+
[baseModule emitEventDict:streamId body:payload];
231222
}
232223

233224
}];
@@ -236,7 +227,7 @@ + (void) readStream:(NSString *)uri
236227
}
237228

238229
// send read stream chunks via native event emitter
239-
+ (void) emitDataChunks:(NSData *)data encoding:(NSString *) encoding streamId:(NSString *)streamId event:(RCTEventDispatcher *)event
230+
+ (void) emitDataChunks:(NSData *)data encoding:(NSString *) encoding streamId:(NSString *)streamId baseModule:(ReactNativeBlobUtil *)baseModule
240231
{
241232
@try
242233
{
@@ -247,12 +238,12 @@ + (void) emitDataChunks:(NSData *)data encoding:(NSString *) encoding streamId:(
247238
@"event": FS_EVENT_DATA,
248239
@"detail" : [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]
249240
};
250-
[event sendDeviceEventWithName:streamId body:payload];
241+
[baseModule emitEventDict:streamId body:payload];
251242
}
252243
else if ([[encoding lowercaseString] isEqualToString:@"base64"])
253244
{
254245
NSDictionary * payload = @{ @"event": FS_EVENT_DATA, @"detail" : [data base64EncodedStringWithOptions:0] };
255-
[event sendDeviceEventWithName:streamId body:payload];
246+
[baseModule emitEventDict:streamId body:payload];
256247
}
257248
else if([[encoding lowercaseString] isEqualToString:@"ascii"])
258249
{
@@ -270,21 +261,21 @@ + (void) emitDataChunks:(NSData *)data encoding:(NSString *) encoding streamId:(
270261
}
271262

272263
NSDictionary * payload = @{ @"event": FS_EVENT_DATA, @"detail" : asciiArray };
273-
[event sendDeviceEventWithName:streamId body:payload];
264+
[baseModule emitEventDict:streamId body:payload];
274265
}
275266

276267
}
277268
@catch (NSException * ex)
278269
{
279270
NSString * message = [NSString stringWithFormat:@"Failed to convert data to '%@' encoded string, this might due to the source data is not able to convert using this encoding. source = %@", encoding, [ex description]];
280-
[event
281-
sendDeviceEventWithName:streamId
271+
[baseModule
272+
emitEventDict:streamId
282273
body:@{
283274
@"event" : MSG_EVENT_ERROR,
284275
@"detail" : message
285276
}];
286-
[event
287-
sendDeviceEventWithName:MSG_EVENT
277+
[baseModule
278+
emitEventDict:MSG_EVENT
288279
body:@{
289280
@"event" : MSG_EVENT_WARN,
290281
@"detail" : message

ios/ReactNativeBlobUtilNetwork.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,11 @@
3030

3131
+ (ReactNativeBlobUtilNetwork* _Nullable)sharedInstance;
3232
+ (NSMutableDictionary * _Nullable ) normalizeHeaders:(NSDictionary * _Nullable)headers;
33-
+ (void) emitExpiredTasks:(RCTEventDispatcher *) eventDispatcher;
3433

3534
- (nullable id) init;
3635
- (void) sendRequest:(NSDictionary * _Nullable )options
3736
contentLength:(long)contentLength
38-
eventDispatcher:(RCTEventDispatcher * _Nullable)eventDispatcherRef
37+
baseModule:(ReactNativeBlobUtil * _Nullable)baseModule
3938
taskId:(NSString * _Nullable)taskId
4039
withRequest:(NSURLRequest * _Nullable)req
4140
callback:(_Nullable RCTResponseSenderBlock) callback;

0 commit comments

Comments
 (0)