Browse Source

Added ios write stream implementation

Ben Hsieh 8 years ago
parent
commit
02683bd2b9
2 changed files with 130 additions and 10 deletions
  1. 4
    0
      src/ios/RNFetchBlob/RNFetchBlob.h
  2. 126
    10
      src/ios/RNFetchBlob/RNFetchBlob.m

+ 4
- 0
src/ios/RNFetchBlob/RNFetchBlob.h View File

@@ -37,6 +37,7 @@ extern NSString *const FS_EVENT_ERROR;
37 37
     int bufferSize;
38 38
     NSString * taskId;
39 39
     NSString * path;
40
+    NSString * streamId;
40 41
 }
41 42
 
42 43
 @property (nonatomic) NSOutputStream * outStream;
@@ -47,13 +48,16 @@ extern NSString *const FS_EVENT_ERROR;
47 48
 @property (nonatomic) NSString * taskId;
48 49
 @property (nonatomic) NSString * path;
49 50
 @property (nonatomic) int bufferSize;
51
+@property (nonatomic) NSString * streamId;
50 52
 
51 53
 + (NSString *) getTempPath;
54
++ (FetchBlobFS *) getFileStreams;
52 55
 - (id) init;
53 56
 - (void) initWithCallback;
54 57
 - (void) initWithBridgeRef;
55 58
 - (void) openWithDestination;
56 59
 - (void) openWithId;
60
+- (NSString *) openWithPath;
57 61
 - (void) write;
58 62
 - (void) read;
59 63
 - (void) closeInStream;

+ 126
- 10
src/ios/RNFetchBlob/RNFetchBlob.m View File

@@ -35,6 +35,7 @@ NSString *const FS_EVENT_ERROR = @"error";
35 35
 
36 36
 @implementation FetchBlobFS
37 37
 
38
+
38 39
 @synthesize outStream;
39 40
 @synthesize inStream;
40 41
 @synthesize encoding;
@@ -43,8 +44,14 @@ NSString *const FS_EVENT_ERROR = @"error";
43 44
 @synthesize path;
44 45
 @synthesize bufferSize;
45 46
 
46
-
47
-
47
+// static member getter
48
++ (NSArray *) getFileStreams {
49
+    
50
+    static NSMutableData *fileStreams = nil;
51
+    if(fileStreams == nil)
52
+        fileStreams = [[NSArray alloc] init];
53
+    return fileStreams;
54
+}
48 55
 
49 56
 + (NSString *) getCacheDir {
50 57
     return [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
@@ -67,22 +74,40 @@ NSString *const FS_EVENT_ERROR = @"error";
67 74
 }
68 75
 
69 76
 
77
++ (NSString *) getTempPath {
78
+    
79
+    return [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingString:@"/RNFetchBlob_tmp"];
80
+}
81
+
70 82
 + (NSString *) getTempPath:(NSString*)taskId withExtension:(NSString *)ext {
71 83
     
72 84
     NSString * documentDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
73
-    NSString * filename = [NSString stringWithFormat:@"/RNFetchBlobTmp_%@", taskId];
85
+    NSString * filename = [NSString stringWithFormat:@"/RNFetchBlob_tmp/RNFetchBlobTmp_%@", taskId];
74 86
     if(ext != nil)
75 87
         filename = [filename stringByAppendingString: [NSString stringWithFormat:@".%@", ext]];
76 88
     NSString * tempPath = [documentDir stringByAppendingString: filename];
77 89
     return tempPath;
78 90
 }
79 91
 
92
++ (BOOL) mkdir:(NSString *) path {
93
+    BOOL isDir;
94
+    NSError * err = nil;
95
+    // if temp folder not exists, create one
96
+    if(![[NSFileManager defaultManager] fileExistsAtPath: path isDirectory:&isDir]) {
97
+        [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&err];
98
+    }
99
+    return err == nil;
100
+}
101
+
102
++ (BOOL) exists:(NSString *) path {
103
+    return [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:NULL];
104
+}
105
+
80 106
 - (id)init {
81 107
     self = [super init];
82 108
     return self;
83 109
 }
84 110
 
85
-
86 111
 - (id)initWithCallback:(RCTResponseSenderBlock)callback {
87 112
     self = [super init];
88 113
     self.callback = callback;
@@ -95,15 +120,18 @@ NSString *const FS_EVENT_ERROR = @"error";
95 120
     return self;
96 121
 }
97 122
 
98
-- (void)openWithPath:(NSString *)destPath {
123
+- (NSString *)openWithPath:(NSString *)destPath {
99 124
     self.outStream = [[NSOutputStream alloc] initToFileAtPath:destPath append:YES];
100 125
     [self.outStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
101 126
     [self.outStream open];
127
+    NSString *uuid = [[NSUUID UUID] UUIDString];
128
+    self.streamId = uuid;
129
+    [[FetchBlobFS getFileStreams] setValue:self forKey:uuid];
130
+    return uuid;
102 131
 }
103 132
 
104
-
105 133
 // Write file chunk into an opened stream
106
-- (void)write:(NSData *) chunk toPath:(NSString *) path{
134
+- (void)write:(NSData *) chunk {
107 135
     NSUInteger left = [chunk length];
108 136
     NSUInteger nwr = 0;
109 137
     do {
@@ -134,7 +162,6 @@ NSString *const FS_EVENT_ERROR = @"error";
134 162
         [[NSRunLoop currentRunLoop] run];
135 163
     
136 164
     });
137
-    
138 165
 }
139 166
 
140 167
 // close file write stream
@@ -151,6 +178,8 @@ NSString *const FS_EVENT_ERROR = @"error";
151 178
     if(self.inStream != nil) {
152 179
         [self.inStream close];
153 180
         [self.inStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
181
+        [[FetchBlobFS getFileStreams] setValue:nil forKey:self.streamId];
182
+        self.streamId = nil;
154 183
     }
155 184
     
156 185
 }
@@ -345,12 +374,12 @@ void runOnMainQueueWithoutDeadlocking(void (^block)(void))
345 374
     Boolean fileCache = [self.options valueForKey:CONFIG_USE_TEMP];
346 375
     NSString * path = [self.options valueForKey:CONFIG_FILE_PATH];
347 376
     if(path != nil) {
348
-        [self.fileStream write:data toPath:path];
377
+        [self.fileStream write:data];
349 378
     }
350 379
     // write to tmp file
351 380
     else if( fileCache != nil) {
352 381
         NSString * ext = [self.options valueForKey:CONFIG_FILE_EXT];
353
-        [self.fileStream write:data toPath:[FetchBlobFS getTempPath:self.taskId withExtension:ext]];
382
+        [self.fileStream write:data];
354 383
     }
355 384
     // cache data in memory
356 385
     else {
@@ -457,6 +486,11 @@ RCT_EXPORT_MODULE();
457 486
 - (id) init {
458 487
     self = [super init];
459 488
     self.filePathPrefix = FILE_PREFIX;
489
+    BOOL isDir;
490
+    // if temp folder not exists, create one
491
+    if(![[NSFileManager defaultManager] fileExistsAtPath: [FetchBlobFS getTempPath] isDirectory:&isDir]) {
492
+        [[NSFileManager defaultManager] createDirectoryAtPath:[FetchBlobFS getTempPath] withIntermediateDirectories:YES attributes:nil error:NULL];
493
+    }
460 494
     return self;
461 495
 }
462 496
 
@@ -591,6 +625,32 @@ RCT_EXPORT_METHOD(readStream:(NSString *)path withEncoding:(NSString *)encoding
591 625
     [fileStream readWithPath:path useEncoding:encoding bufferSize:bufferSize];
592 626
 }
593 627
 
628
+RCT_EXPORT_METHOD(writeStream:(NSString *)path withEncoding:(NSString *)encoding callback:(RCTResponseSenderBlock)callback) {
629
+    FetchBlobFS *fileStream = [[FetchBlobFS alloc] initWithBridgeRef:self.bridge];
630
+    NSString * streamId = [fileStream openWithPath:path];
631
+    callback(@[streamId]);
632
+}
633
+
634
+RCT_EXPORT_METHOD(writeChunk:(NSString *)streamId withData:(NSString *)data encoding:(NSString *)encode callback:(RCTResponseSenderBlock) callback) {
635
+    FetchBlobFS *fs = [[FetchBlobFS getFileStreams] valueForKey:streamId];
636
+    NSMutableData * decodedData = [NSData alloc];
637
+    if([[encode lowercaseString] isEqualToString:@"base64"]) {
638
+        [fs write:[data dataUsingEncoding:NSUTF8StringEncoding]];
639
+    }
640
+    if([[encode lowercaseString] isEqualToString:@"utf8"]) {
641
+        [fs write:[data dataUsingEncoding:NSUTF8StringEncoding]];
642
+    }
643
+    else if([[encode lowercaseString] isEqualToString:@"ascii"]) {
644
+        [fs write:[data dataUsingEncoding:NSASCIIStringEncoding]];
645
+    }
646
+}
647
+
648
+RCT_EXPORT_METHOD(closeStream:(NSString *)streamId callback:(RCTResponseSenderBlock) callback) {
649
+    FetchBlobFS *fs = [[FetchBlobFS getFileStreams] valueForKey:streamId];
650
+    [fs closeOutStream];
651
+    callback(@[[NSNull null], @YES]);
652
+}
653
+
594 654
 RCT_EXPORT_METHOD(unlink:(NSString *)path callback:(RCTResponseSenderBlock) callback) {
595 655
     NSError * error = nil;
596 656
     NSString * tmpPath = nil;
@@ -601,6 +661,62 @@ RCT_EXPORT_METHOD(unlink:(NSString *)path callback:(RCTResponseSenderBlock) call
601 661
         callback(@[[NSString stringWithFormat:@"failed to unlink file or path at %@", path]]);
602 662
 }
603 663
 
664
+RCT_EXPORT_METHOD(removeSession:(NSArray *)paths callback:(RCTResponseSenderBlock) callback) {
665
+    NSError * error = nil;
666
+    NSString * tmpPath = nil;
667
+    
668
+    for(NSString * path in paths) {
669
+        [[NSFileManager defaultManager] removeItemAtPath:path error:&error];
670
+        if(error != nil) {
671
+            callback(@[[NSString stringWithFormat:@"failed to remove session path at %@", path]]);
672
+            return;
673
+        }
674
+    }
675
+    callback(@[[NSNull null]]);
676
+    
677
+}
678
+
679
+RCT_EXPORT_METHOD(ls:(NSString *)path callback:(RCTResponseSenderBlock) callback) {
680
+    NSError * error = nil;
681
+    NSArray * result = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:&error];
682
+    
683
+    if(error == nil)
684
+        callback(@[[NSNull null], result == nil ? [NSNull null] :result ]);
685
+    else
686
+        callback(@[[error localizedDescription], [NSNull null]]);
687
+    
688
+}
689
+
690
+RCT_EXPORT_METHOD(cp:(NSString *)path toPath:(NSString *)dest callback:(RCTResponseSenderBlock) callback) {
691
+    NSError * error = nil;
692
+    BOOL result = [[NSFileManager defaultManager] copyItemAtURL:path toURL:dest error:&error];
693
+    
694
+    if(error == nil)
695
+        callback(@[[NSNull null], @YES]);
696
+    else
697
+        callback(@[[error localizedDescription], @NO]);
698
+    
699
+}
700
+
701
+RCT_EXPORT_METHOD(mv:(NSString *)path toPath:(NSString *)dest callback:(RCTResponseSenderBlock) callback) {
702
+    NSError * error = nil;
703
+    BOOL result = [[NSFileManager defaultManager] moveItemAtURL:path toURL:dest error:&error];
704
+    
705
+    if(error == nil)
706
+        callback(@[[NSNull null], @YES]);
707
+    else
708
+        callback(@[[error localizedDescription], @NO]);
709
+    
710
+}
711
+
712
+RCT_EXPORT_METHOD(mkdir:(NSString *)path callback:(RCTResponseSenderBlock) callback) {
713
+    if([FetchBlobFS exists:path])
714
+        callback(@[@"file path exists"]);
715
+    else
716
+        [FetchBlobFS mkdir:path];
717
+    callback(@[[NSNull null]]);
718
+}
719
+
604 720
 RCT_EXPORT_METHOD(getEnvironmentDirs:(RCTResponseSenderBlock) callback) {
605 721
     
606 722
     callback(@[