Skip to content

Commit bbcd0f1

Browse files
author
Riccardo Cipolleschi
committed
feat: update iOS implementation
1 parent e67a50c commit bbcd0f1

14 files changed

+347
-117
lines changed

codegenSpecs/NativeBlobUtils.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ import { TurboModuleRegistry } from 'react-native';
44

55
export interface Spec extends TurboModule {
66
+getConstants: () => {|
7-
'CacheDir': string,
8-
'DocumentDir': string,
9-
'DownloadDir': string,
10-
'LibraryDir': string,
11-
'MainBundleDir': string,
12-
'MovieDir': string,
13-
'MusicDir': string,
14-
'PictureDir': string,
15-
'ApplicationSupportDir': string,
7+
CacheDir: string,
8+
DocumentDir: string,
9+
DownloadDir: string,
10+
LibraryDir: string,
11+
MainBundleDir: string,
12+
MovieDir: string,
13+
MusicDir: string,
14+
PictureDir: string,
15+
ApplicationSupportDir: string,
1616
|};
1717

1818
+fetchBlobForm: (options: Object, taskId: string, method: string, url: string, headers: Object, form: Array<any>, callback: (value: Array<any>) => void) => void;

ios/ReactNativeBlobUtil/ReactNativeBlobUtil.m renamed to ios/ReactNativeBlobUtil/ReactNativeBlobUtil.mm

Lines changed: 234 additions & 35 deletions
Large diffs are not rendered by default.
File renamed without changes.

ios/ReactNativeBlobUtilFS.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@
1818
#import "RCTBridgeModule.h"
1919
#endif
2020

21-
@import AssetsLibrary;
21+
#import <AssetsLibrary/AssetsLibrary.h>
2222

2323
@interface ReactNativeBlobUtilFS : NSObject <NSStreamDelegate> {
2424
NSOutputStream * outStream;
2525
NSInputStream * inStream;
2626
RCTResponseSenderBlock callback;
27-
RCTBridge * bridge;
27+
RCTEventDispatcher * eventDispatcher;
2828
Boolean isOpen;
2929
NSString * encoding;
3030
int bufferSize;
@@ -37,7 +37,7 @@
3737
@property (nonatomic) NSOutputStream * _Nullable outStream;
3838
@property (nonatomic) NSInputStream * _Nullable inStream;
3939
@property (strong, nonatomic) RCTResponseSenderBlock callback;
40-
@property (nonatomic) RCTBridge * bridge;
40+
@property (nonatomic) RCTEventDispatcher * eventDispatcher;
4141
@property (nonatomic) NSString * encoding;
4242
@property (nonatomic) NSString * taskId;
4343
@property (nonatomic) NSString * path;
@@ -85,13 +85,13 @@
8585
rejecter:(RCTPromiseRejectBlock)reject;
8686
//+ (void) writeFileFromFile:(NSString *)src toFile:(NSString *)dest append:(BOOL)append;
8787
+ (void) writeAssetToPath:(ALAssetRepresentation * )rep dest:(NSString *)dest;
88-
+ (void) readStream:(NSString *)uri encoding:(NSString * )encoding bufferSize:(int)bufferSize tick:(int)tick streamId:(NSString *)streamId bridgeRef:(RCTBridge *)bridgeRef;
88+
+ (void) readStream:(NSString *)uri encoding:(NSString * )encoding bufferSize:(int)bufferSize tick:(int)tick streamId:(NSString *)streamId eventDispatcherRef:(RCTEventDispatcher *)eventDispatcherRef;
8989
+ (void) df:(RCTResponseSenderBlock)callback;
9090

9191
// constructor
9292
- (id) init;
9393
- (id)initWithCallback:(RCTResponseSenderBlock)callback;
94-
- (id)initWithBridgeRef:(RCTBridge *)bridgeRef;
94+
- (id)initWithEventDispatcherRef:(RCTEventDispatcher *)eventDispatcherRef;
9595

9696
// file stream
9797
- (void) openWithDestination;

ios/ReactNativeBlobUtilFS.m renamed to ios/ReactNativeBlobUtilFS.mm

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#import "ReactNativeBlobUtilFS.h"
1212
#import "ReactNativeBlobUtilConst.h"
1313
#import "ReactNativeBlobUtilFileTransformer.h"
14-
@import AssetsLibrary;
14+
#import <AssetsLibrary/AssetsLibrary.h>
1515

1616
#import <CommonCrypto/CommonDigest.h>
1717

@@ -58,9 +58,9 @@ - (id)initWithCallback:(RCTResponseSenderBlock)callback {
5858
return self;
5959
}
6060

61-
- (id)initWithBridgeRef:(RCTBridge *)bridgeRef {
61+
- (id)initWithEventDispatcherRef:(RCTEventDispatcher *)eventDispatcherRef {
6262
self = [super init];
63-
self.bridge = bridgeRef;
63+
self.eventDispatcher = eventDispatcherRef;
6464
return self;
6565
}
6666

@@ -69,7 +69,7 @@ + (NSArray *) getFileStreams {
6969

7070
if(fileStreams == nil)
7171
fileStreams = [[NSMutableDictionary alloc] init];
72-
return fileStreams;
72+
return fileStreams.allValues;
7373
}
7474

7575
+(void) setFileStream:(ReactNativeBlobUtilFS *) instance withId:(NSString *) uuid {
@@ -160,11 +160,11 @@ + (void) readStream:(NSString *)uri
160160
bufferSize:(int)bufferSize
161161
tick:(int)tick
162162
streamId:(NSString *)streamId
163-
bridgeRef:(RCTBridge *)bridgeRef
163+
eventDispatcherRef:(RCTEventDispatcher *)eventDispatcherRef
164164
{
165165
[[self class] getPathFromUri:uri completionHandler:^(NSString *path, ALAssetRepresentation *asset) {
166166

167-
__block RCTEventDispatcher * event = bridgeRef.eventDispatcher;
167+
__block RCTEventDispatcher * event = eventDispatcherRef;
168168
__block int read = 0;
169169
__block int backoff = tick *1000;
170170
__block int chunkSize = bufferSize;
@@ -508,15 +508,16 @@ + (void) readFile:(NSString *)path
508508
__block Byte * buffer;
509509
if(asset != nil)
510510
{
511-
buffer = malloc(asset.size);
511+
int size = asset.size;
512+
buffer = (Byte *)malloc(size);
512513
[asset getBytes:buffer fromOffset:0 length:asset.size error:&err];
513514
if(err != nil)
514515
{
515516
onComplete(nil, @"EUNSPECIFIED", [err description]);
516517
free(buffer);
517518
return;
518519
}
519-
fileContent = [NSData dataWithBytes:buffer length:asset.size];
520+
fileContent = [NSData dataWithBytes:buffer length:size];
520521
free(buffer);
521522
}
522523
else
@@ -555,21 +556,25 @@ + (void) readFile:(NSString *)path
555556
if([[encoding lowercaseString] isEqualToString:@"utf8"])
556557
{
557558
NSString * utf8 = [[NSString alloc] initWithData:fileContent encoding:NSUTF8StringEncoding];
558-
if(utf8 == nil)
559-
onComplete([[NSString alloc] initWithData:fileContent encoding:NSISOLatin1StringEncoding], nil, nil);
560-
else
561-
onComplete(utf8, nil, nil);
559+
if(utf8 == nil) {
560+
NSString * latin1 = [[NSString alloc] initWithData:fileContent encoding:NSISOLatin1StringEncoding];
561+
NSData * latin1Data = [latin1 dataUsingEncoding:NSISOLatin1StringEncoding];
562+
onComplete(latin1Data, nil, nil);
563+
} else {
564+
onComplete(fileContent, nil, nil);
565+
}
562566
}
563567
else if ([[encoding lowercaseString] isEqualToString:@"base64"]) {
564-
onComplete([fileContent base64EncodedStringWithOptions:0], nil, nil);
568+
NSString * base64String = [fileContent base64EncodedStringWithOptions:0];
569+
onComplete([[NSData alloc] initWithBase64EncodedString:base64String options:0], nil, nil);
565570
}
566571
else if ([[encoding lowercaseString] isEqualToString:@"ascii"]) {
567572
NSMutableArray * resultArray = [NSMutableArray array];
568-
char * bytes = [fileContent bytes];
573+
char * bytes = (char *)[fileContent bytes];
569574
for(int i=0;i<[fileContent length];i++) {
570575
[resultArray addObject:[NSNumber numberWithChar:bytes[i]]];
571576
}
572-
onComplete(resultArray, nil, nil);
577+
onComplete((NSData *)resultArray, nil, nil);
573578
}
574579
}
575580
else
@@ -690,11 +695,11 @@ + (NSDictionary *) stat:(NSString *) path error:(NSError **) error {
690695
if([fm fileExistsAtPath:path isDirectory:&isDir] == NO) {
691696
return nil;
692697
}
693-
NSDictionary * info = [fm attributesOfItemAtPath:path error:&error];
694-
NSString * size = [NSString stringWithFormat:@"%d", [info fileSize]];
698+
NSDictionary * info = [fm attributesOfItemAtPath:path error:error];
699+
NSString * size = [NSString stringWithFormat:@"%llu", [info fileSize]];
695700
NSString * filename = [path lastPathComponent];
696701
NSDate * lastModified;
697-
[[NSURL fileURLWithPath:path] getResourceValue:&lastModified forKey:NSURLContentModificationDateKey error:&error];
702+
[[NSURL fileURLWithPath:path] getResourceValue:&lastModified forKey:NSURLContentModificationDateKey error:error];
698703
return @{
699704
@"size" : size,
700705
@"filename" : filename,
@@ -759,7 +764,7 @@ - (void)writeEncodeChunk:(NSString *) chunk {
759764
NSUInteger left = [decodedData length];
760765
NSUInteger nwr = 0;
761766
do {
762-
nwr = [self.outStream write:[decodedData bytes] maxLength:left];
767+
nwr = [self.outStream write:(const uint8_t *)[decodedData bytes] maxLength:left];
763768
if (-1 == nwr) break;
764769
left -= nwr;
765770
} while (left > 0);
@@ -773,7 +778,7 @@ - (void)write:(NSData *) chunk {
773778
NSUInteger left = [chunk length];
774779
NSUInteger nwr = 0;
775780
do {
776-
nwr = [self.outStream write:[chunk bytes] maxLength:left];
781+
nwr = [self.outStream write:(const uint8_t *)[chunk bytes] maxLength:left];
777782
if (-1 == nwr) break;
778783
left -= nwr;
779784
} while (left > 0);
@@ -826,7 +831,7 @@ + (void)slice:(NSString *)path
826831
long max = MIN(size, [end longValue]);
827832

828833
if(![fm fileExistsAtPath:dest]) {
829-
if(![fm createFileAtPath:dest contents:@"" attributes:nil]) {
834+
if(![fm createFileAtPath:dest contents:[NSData new] attributes:nil]) {
830835
return reject(@"ENOENT", [NSString stringWithFormat:@"File '%@' does not exist and could not be created", path], nil);
831836
}
832837
}
@@ -842,15 +847,15 @@ + (void)slice:(NSString *)path
842847
}
843848
else
844849
{
845-
NSLog(@"read chunk %lu", 10240);
850+
NSLog(@"read chunk %d", 10240);
846851
chunkSize = 10240;
847852
chunk = [handle readDataOfLength:10240];
848853
}
849854
if([chunk length] <= 0)
850855
break;
851856
long remain = expected - read;
852857

853-
[os write:[chunk bytes] maxLength:chunkSize];
858+
[os write:(const uint8_t *)[chunk bytes] maxLength:chunkSize];
854859
read += [chunk length];
855860
}
856861
[handle closeFile];
@@ -868,19 +873,20 @@ + (void)slice:(NSString *)path
868873
long max = MIN(size, [end longValue]);
869874

870875
while(read < expected) {
871-
uint8_t * chunk[10240];
876+
uint8_t chunk[10240];
877+
uint8_t * pointerToChunk = &chunk[0];
872878
long chunkSize = 0;
873879
if([start longValue] + read + 10240 > max)
874880
{
875881
NSLog(@"read chunk %lu", max - read - [start longValue]);
876882
chunkSize = max - read - [start longValue];
877-
chunkRead = [asset getBytes:chunk fromOffset:[start longValue] + read length:chunkSize error:nil];
883+
chunkRead = [asset getBytes:pointerToChunk fromOffset:[start longValue] + read length:chunkSize error:nil];
878884
}
879885
else
880886
{
881887
NSLog(@"read chunk %lu", 10240);
882888
chunkSize = 10240;
883-
chunkRead = [asset getBytes:chunk fromOffset:[start longValue] + read length:chunkSize error:nil];
889+
chunkRead = [asset getBytes:pointerToChunk fromOffset:[start longValue] + read length:chunkSize error:nil];
884890
}
885891
if( chunkRead <= 0)
886892
break;

ios/ReactNativeBlobUtilNetwork.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@
3030

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

3535
- (nullable id) init;
3636
- (void) sendRequest:(NSDictionary * _Nullable )options
3737
contentLength:(long)contentLength
38-
bridge:(RCTBridge * _Nullable)bridgeRef
38+
eventDispatcher:(RCTEventDispatcher * _Nullable)eventDispatcherRef
3939
taskId:(NSString * _Nullable)taskId
4040
withRequest:(NSURLRequest * _Nullable)req
4141
callback:(_Nullable RCTResponseSenderBlock) callback;

ios/ReactNativeBlobUtilNetwork.m renamed to ios/ReactNativeBlobUtilNetwork.mm

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#import <Foundation/Foundation.h>
1111
#import "ReactNativeBlobUtilNetwork.h"
1212

13-
#import "ReactNativeBlobUtil.h"
1413
#import "ReactNativeBlobUtilConst.h"
1514
#import "ReactNativeBlobUtilProgress.h"
1615

@@ -49,14 +48,14 @@ - (id)init {
4948
self = [super init];
5049
if (self) {
5150
self.requestsTable = [NSMapTable mapTableWithKeyOptions:NSMapTableStrongMemory valueOptions:NSMapTableWeakMemory];
52-
51+
5352
self.taskQueue = [[NSOperationQueue alloc] init];
5453
self.taskQueue.qualityOfService = NSQualityOfServiceUtility;
5554
self.taskQueue.maxConcurrentOperationCount = 10;
5655
self.rebindProgressDict = [NSMutableDictionary dictionary];
5756
self.rebindUploadProgressDict = [NSMutableDictionary dictionary];
5857
}
59-
58+
6059
return self;
6160
}
6261

@@ -67,26 +66,26 @@ + (ReactNativeBlobUtilNetwork* _Nullable)sharedInstance {
6766
dispatch_once(&onceToken, ^{
6867
_sharedInstance = [[self alloc] init];
6968
});
70-
69+
7170
return _sharedInstance;
7271
}
7372

7473
- (void) sendRequest:(__weak NSDictionary * _Nullable )options
7574
contentLength:(long) contentLength
76-
bridge:(RCTBridge * _Nullable)bridgeRef
75+
eventDispatcher:(RCTEventDispatcher * _Nullable)eventDispatcherRef
7776
taskId:(NSString * _Nullable)taskId
7877
withRequest:(__weak NSURLRequest * _Nullable)req
7978
callback:(_Nullable RCTResponseSenderBlock) callback
8079
{
8180
ReactNativeBlobUtilRequest *request = [[ReactNativeBlobUtilRequest alloc] init];
8281
[request sendRequest:options
8382
contentLength:contentLength
84-
bridge:bridgeRef
83+
eventDispatcher:eventDispatcherRef
8584
taskId:taskId
8685
withRequest:req
8786
taskOperationQueue:self.taskQueue
8887
callback:callback];
89-
88+
9089
@synchronized([ReactNativeBlobUtilNetwork class]) {
9190
[self.requestsTable setObject:request forKey:taskId];
9291
[self checkProgressConfigForTask:taskId];
@@ -100,7 +99,7 @@ - (void) checkProgressConfigForTask:(NSString *)taskId {
10099
[self enableProgressReport:taskId config:downloadConfig];
101100
[self.rebindProgressDict removeObjectForKey:taskId];
102101
}
103-
102+
104103
//reconfig uploadProgress
105104
ReactNativeBlobUtilProgress *uploadConfig = self.rebindUploadProgressDict[taskId];
106105
if (uploadConfig != nil) {
@@ -138,11 +137,11 @@ - (void) enableUploadProgress:(NSString *) taskId config:(ReactNativeBlobUtilPro
138137
- (void) cancelRequest:(NSString *)taskId
139138
{
140139
NSURLSessionDataTask * task;
141-
140+
142141
@synchronized ([ReactNativeBlobUtilNetwork class]) {
143142
task = [self.requestsTable objectForKey:taskId].task;
144143
}
145-
144+
146145
if (task && task.state == NSURLSessionTaskStateRunning) {
147146
[task cancel];
148147
}
@@ -155,25 +154,24 @@ + (NSMutableDictionary *) normalizeHeaders:(NSDictionary *)headers
155154
for (NSString * key in headers) {
156155
[mheaders setValue:[headers valueForKey:key] forKey:[key lowercaseString]];
157156
}
158-
157+
159158
return mheaders;
160159
}
161160

162161
// #115 Invoke fetch.expire event on those expired requests so that the expired event can be handled
163-
+ (void) emitExpiredTasks
162+
+ (void) emitExpiredTasks:(RCTEventDispatcher *)eventDispatcher
164163
{
165164
@synchronized ([ReactNativeBlobUtilNetwork class]){
166165
NSEnumerator * emu = [expirationTable keyEnumerator];
167166
NSString * key;
168-
167+
169168
while ((key = [emu nextObject]))
170169
{
171-
RCTBridge * bridge = [ReactNativeBlobUtil getRCTBridge];
172170
id args = @{ @"taskId": key };
173-
[bridge.eventDispatcher sendDeviceEventWithName:EVENT_EXPIRE body:args];
174-
171+
[eventDispatcher sendDeviceEventWithName:EVENT_EXPIRE body:args];
172+
175173
}
176-
174+
177175
// clear expired task entries
178176
[expirationTable removeAllObjects];
179177
expirationTable = [[NSMapTable alloc] init];

0 commit comments

Comments
 (0)