|
@@ -2,13 +2,14 @@
|
2
|
2
|
// RNFetchBlob.m
|
3
|
3
|
//
|
4
|
4
|
// Created by suzuri04x2 on 2016/4/28.
|
5
|
|
-// Copyright © 2016年 Facebook. All rights reserved.
|
6
|
5
|
//
|
7
|
6
|
|
8
|
7
|
#import "RNFetchBlob.h"
|
9
|
8
|
#import "RCTConvert.h"
|
10
|
9
|
#import "RCTLog.h"
|
11
|
10
|
#import <Foundation/Foundation.h>
|
|
11
|
+#import "RCTBridge.h"
|
|
12
|
+#import "RCTEventDispatcher.h"
|
12
|
13
|
|
13
|
14
|
|
14
|
15
|
////////////////////////////////////////
|
|
@@ -19,24 +20,14 @@
|
19
|
20
|
|
20
|
21
|
@implementation FetchBlobUtils
|
21
|
22
|
|
22
|
|
-// callback class method to handle request
|
23
|
|
-+ (void) onBlobResponse:(NSURLResponse * _Nullable)response withData:(NSData * _Nullable)data withError:(NSError * _Nullable)connectionError withCallback:(RCTResponseSenderBlock)callback{
|
24
|
|
-
|
25
|
|
- NSHTTPURLResponse* resp = (NSHTTPURLResponse *) response;
|
26
|
|
- NSString* status = [NSString stringWithFormat:@"%d", resp.statusCode];
|
27
|
|
-
|
28
|
|
- if(connectionError)
|
29
|
|
- {
|
30
|
|
- callback(@[[connectionError localizedDescription], [NSNull null]]);
|
31
|
|
- }
|
32
|
|
- else if(![status isEqualToString:@"200"]) {
|
33
|
|
- callback(@[status, [NSNull null]]);
|
34
|
|
- }
|
35
|
|
- else {
|
36
|
|
- callback(@[[NSNull null], [data base64EncodedStringWithOptions:0]]);
|
37
|
|
- }
|
38
|
|
-
|
39
|
|
-}
|
|
23
|
+
|
|
24
|
+@synthesize taskId;
|
|
25
|
+@synthesize expectedBytes;
|
|
26
|
+@synthesize receivedBytes;
|
|
27
|
+@synthesize respData;
|
|
28
|
+@synthesize callback;
|
|
29
|
+@synthesize bridge;
|
|
30
|
+
|
40
|
31
|
|
41
|
32
|
// removing case of headers
|
42
|
33
|
+ (NSMutableDictionary *) normalizeHeaders:(NSDictionary *)headers {
|
|
@@ -49,6 +40,90 @@
|
49
|
40
|
return mheaders;
|
50
|
41
|
}
|
51
|
42
|
|
|
43
|
+- (id)init {
|
|
44
|
+ self = [super init];
|
|
45
|
+ return self;
|
|
46
|
+}
|
|
47
|
+
|
|
48
|
+- (id)delegate:(id)delegate {
|
|
49
|
+ return delegate;
|
|
50
|
+}
|
|
51
|
+
|
|
52
|
+- (void) sendRequest:(RCTBridge *)bridgeRef taskId:(NSString *)taskId withRequest:(NSURLRequest *)req callback:(RCTResponseSenderBlock) callback {
|
|
53
|
+ self.taskId = taskId;
|
|
54
|
+ self.respData = [[NSMutableData alloc] initWithLength:0];
|
|
55
|
+ self.callback = callback;
|
|
56
|
+ self.bridge = bridgeRef;
|
|
57
|
+ // Call long-running code on background thread
|
|
58
|
+ NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:req delegate:self startImmediately:NO];
|
|
59
|
+ [conn scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
|
|
60
|
+ [conn start];
|
|
61
|
+
|
|
62
|
+ if(!conn) {
|
|
63
|
+ callback(@[[NSString stringWithFormat:@"RNFetchBlob could not initialize connection"], [NSNull null]]);
|
|
64
|
+ }
|
|
65
|
+}
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+#pragma mark NSURLConnection delegate methods
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+- (void) connection:(NSURLConnection *)connection didReceiveResponse:(nonnull NSURLResponse *)response {
|
|
72
|
+ [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
|
|
73
|
+ expectedBytes = [response expectedContentLength];
|
|
74
|
+}
|
|
75
|
+
|
|
76
|
+- (void) connection:(NSURLConnection *)connection didReceiveData:(nonnull NSData *)data {
|
|
77
|
+ receivedBytes = data.length;
|
|
78
|
+ [respData appendData:data];
|
|
79
|
+
|
|
80
|
+ [self.bridge.eventDispatcher
|
|
81
|
+ sendAppEventWithName:@"RNFetchBlobProgress"
|
|
82
|
+ body:@{
|
|
83
|
+ @"taskId": taskId,
|
|
84
|
+ @"written": [NSString stringWithFormat:@"%d", receivedBytes],
|
|
85
|
+ @"total": [NSString stringWithFormat:@"%d", expectedBytes]
|
|
86
|
+ }
|
|
87
|
+ ];
|
|
88
|
+}
|
|
89
|
+
|
|
90
|
+- (void) connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite {
|
|
91
|
+
|
|
92
|
+ expectedBytes = totalBytesExpectedToWrite;
|
|
93
|
+ receivedBytes = totalBytesWritten;
|
|
94
|
+ [self.bridge.eventDispatcher
|
|
95
|
+ sendAppEventWithName:@"RNFetchBlobProgress"
|
|
96
|
+ body:@{
|
|
97
|
+ @"taskId": taskId,
|
|
98
|
+ @"written": [NSString stringWithFormat:@"%d", receivedBytes],
|
|
99
|
+ @"total": [NSString stringWithFormat:@"%d", expectedBytes]
|
|
100
|
+ }
|
|
101
|
+ ];
|
|
102
|
+
|
|
103
|
+}
|
|
104
|
+
|
|
105
|
+- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
|
|
106
|
+ [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
|
|
107
|
+ callback(@[[error localizedDescription], [NSNull null]]);
|
|
108
|
+}
|
|
109
|
+
|
|
110
|
+- (NSCachedURLResponse *) connection:(NSURLConnection *)connection willCacheResponse: (NSCachedURLResponse *)cachedResponse {
|
|
111
|
+ return nil;
|
|
112
|
+}
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+// handle 301 and 302 responses
|
|
116
|
+- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:response {
|
|
117
|
+
|
|
118
|
+ return request;
|
|
119
|
+}
|
|
120
|
+
|
|
121
|
+// request complete
|
|
122
|
+- (void) connectionDidFinishLoading:(NSURLConnection *)connection {
|
|
123
|
+ NSData * data = [NSData dataWithData:respData];
|
|
124
|
+ callback(@[[NSNull null], [data base64EncodedStringWithOptions:0]]);
|
|
125
|
+}
|
|
126
|
+
|
52
|
127
|
@end
|
53
|
128
|
|
54
|
129
|
|
|
@@ -60,16 +135,19 @@
|
60
|
135
|
|
61
|
136
|
@implementation RNFetchBlob
|
62
|
137
|
|
|
138
|
+@synthesize bridge = _bridge;
|
|
139
|
+
|
63
|
140
|
RCT_EXPORT_MODULE();
|
64
|
141
|
|
65
|
142
|
// Fetch blob data request
|
66
|
|
-RCT_EXPORT_METHOD(fetchBlobForm:(NSString *)method url:(NSString *)url headers:(NSDictionary *)headers form:(NSArray *)form callback:(RCTResponseSenderBlock)callback)
|
|
143
|
+RCT_EXPORT_METHOD(fetchBlobForm:(NSString *)taskId method:(NSString *)method url:(NSString *)url headers:(NSDictionary *)headers form:(NSArray *)form callback:(RCTResponseSenderBlock)callback)
|
67
|
144
|
{
|
68
|
145
|
|
69
|
146
|
// send request
|
70
|
147
|
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]
|
71
|
148
|
initWithURL:[NSURL
|
72
|
149
|
URLWithString: url]];
|
|
150
|
+
|
73
|
151
|
NSMutableDictionary *mheaders = [[NSMutableDictionary alloc] initWithDictionary:[ FetchBlobUtils normalizeHeaders:headers]];
|
74
|
152
|
|
75
|
153
|
|
|
@@ -120,18 +198,20 @@ RCT_EXPORT_METHOD(fetchBlobForm:(NSString *)method url:(NSString *)url headers:(
|
120
|
198
|
[request setHTTPMethod: method];
|
121
|
199
|
[request setAllHTTPHeaderFields:mheaders];
|
122
|
200
|
|
|
201
|
+ [[[FetchBlobUtils alloc] init] sendRequest:self.bridge taskId:taskId withRequest:request callback:callback];
|
|
202
|
+
|
123
|
203
|
// create thread for http request
|
124
|
|
- NSOperationQueue *queue = [[NSOperationQueue alloc] init];
|
125
|
|
- [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
|
126
|
|
-
|
127
|
|
- [FetchBlobUtils onBlobResponse:response withData:data withError: connectionError withCallback: callback];
|
128
|
|
-
|
129
|
|
- }];
|
|
204
|
+// NSOperationQueue *queue = [[NSOperationQueue alloc] init];
|
|
205
|
+// [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
|
|
206
|
+//
|
|
207
|
+// [FetchBlobUtils onBlobResponse:response withData:data withError: connectionError withCallback: callback];
|
|
208
|
+//
|
|
209
|
+// }];
|
130
|
210
|
|
131
|
211
|
}
|
132
|
212
|
|
133
|
213
|
// Fetch blob data request
|
134
|
|
-RCT_EXPORT_METHOD(fetchBlob:(NSString *)method url:(NSString *)url headers:(NSDictionary *)headers body:(NSString *)body callback:(RCTResponseSenderBlock)callback)
|
|
214
|
+RCT_EXPORT_METHOD(fetchBlob:(NSString *)taskId method:(NSString *)method url:(NSString *)url headers:(NSDictionary *)headers body:(NSString *)body callback:(RCTResponseSenderBlock)callback)
|
135
|
215
|
{
|
136
|
216
|
// send request
|
137
|
217
|
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]
|
|
@@ -155,14 +235,18 @@ RCT_EXPORT_METHOD(fetchBlob:(NSString *)method url:(NSString *)url headers:(NSDi
|
155
|
235
|
[request setHTTPMethod: method];
|
156
|
236
|
[request setAllHTTPHeaderFields:mheaders];
|
157
|
237
|
|
|
238
|
+ [[[FetchBlobUtils alloc] init] sendRequest:self.bridge taskId:taskId withRequest:request callback:callback];
|
|
239
|
+
|
158
|
240
|
// create thread for http request
|
159
|
|
- NSOperationQueue *queue = [[NSOperationQueue alloc] init];
|
160
|
|
- [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
|
161
|
|
-
|
162
|
|
- [FetchBlobUtils onBlobResponse:response withData:data withError: connectionError withCallback: callback];
|
163
|
|
-
|
164
|
|
- }];
|
|
241
|
+// NSOperationQueue *queue = [[NSOperationQueue alloc] init];
|
|
242
|
+//
|
|
243
|
+//
|
|
244
|
+// [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
|
|
245
|
+//
|
|
246
|
+// [FetchBlobUtils onBlobResponse:response withData:data withError: connectionError withCallback: callback];
|
|
247
|
+//
|
|
248
|
+// }];
|
165
|
249
|
|
166
|
250
|
}
|
167
|
|
-@end
|
168
|
251
|
|
|
252
|
+@end
|