Skip to content
This repository was archived by the owner on Mar 16, 2019. It is now read-only.

Commit 05ade3a

Browse files
committed
Add ios task cancel implementation, add test case for task cancel #39
1 parent 4fe6a3e commit 05ade3a

File tree

6 files changed

+115
-38
lines changed

6 files changed

+115
-38
lines changed

src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ function fetch(...args:any):Promise {
160160
return promise
161161
}
162162
promise.cancel = (fn) => {
163+
fn = fn || function(){}
163164
RNFetchBlob.cancelRequest(taskId, fn)
164165
}
165166

src/ios/RNFetchBlob/RNFetchBlob.m

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,12 @@ - (NSDictionary *)constantsToExport
347347
]);
348348
}
349349

350+
RCT_EXPORT_METHOD(cancelRequest:(NSString *)taskId callback:(RCTResponseSenderBlock)callback) {
351+
[RNFetchBlobNetwork cancelRequest:taskId];
352+
callback(@[[NSNull null], taskId]);
353+
354+
}
355+
350356
#pragma mark RNFetchBlob private methods
351357

352358

src/ios/RNFetchBlobNetwork.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ typedef void(^DataTaskCompletionHander) (NSData * _Nullable resp, NSURLResponse
3535
- (void) sendRequest;
3636

3737
+ (NSMutableDictionary * _Nullable ) normalizeHeaders:(NSDictionary * _Nullable)headers;
38+
+ (void) cancelRequest:(NSString *)taskId;
3839
- (void) sendRequest:(NSDictionary * _Nullable )options contentLength:(long)contentLength bridge:(RCTBridge * _Nullable)bridgeRef taskId:(NSString * _Nullable)taskId withRequest:(NSURLRequest * _Nullable)req callback:(_Nullable RCTResponseSenderBlock) callback;
3940

4041

src/ios/RNFetchBlobNetwork.m

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
//
2222
////////////////////////////////////////
2323

24+
NSMutableDictionary * taskTable;
25+
2426
@interface RNFetchBlobNetwork ()
2527
{
2628
BOOL * respFile;
@@ -53,6 +55,9 @@ - (id)init {
5355
if(taskQueue == nil) {
5456
taskQueue = [[NSOperationQueue alloc] init];
5557
}
58+
if(taskTable == nil) {
59+
taskTable = [[NSMutableDictionary alloc] init];
60+
}
5661
return self;
5762
}
5863

@@ -109,7 +114,7 @@ - (void) sendRequest:(NSDictionary * _Nullable )options
109114
respFile = NO;
110115
}
111116
NSURLSessionDataTask * task = [session dataTaskWithRequest:req];
112-
117+
[taskTable setValue:task forKey:taskId];
113118
[task resume];
114119

115120
// network status indicator
@@ -189,7 +194,7 @@ - (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCom
189194
- (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesWritten totalBytesExpectedToSend:(int64_t)totalBytesExpectedToWrite
190195
{
191196
[self.bridge.eventDispatcher
192-
sendDeviceEventWithName:@"RNFetchBlobProgress"
197+
sendDeviceEventWithName:@"RNFetchBlobProgress-upload"
193198
body:@{
194199
@"taskId": taskId,
195200
@"written": [NSString stringWithFormat:@"%d", totalBytesWritten],
@@ -198,6 +203,13 @@ - (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSen
198203
];
199204
}
200205

206+
+ (void) cancelRequest:(NSString *)taskId
207+
{
208+
NSURLSessionDataTask * task = (NSURLSessionDataTask *)[taskTable objectForKey:taskId];
209+
if(task != nil && task.state == NSURLSessionTaskStateRunning)
210+
[task cancel];
211+
}
212+
201213
//- (void) application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler {
202214
//
203215
//}

test/test-0.7.0.js

Lines changed: 85 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ const { TEST_SERVER_URL, TEST_SERVER_URL_SSL, DROPBOX_TOKEN, styles } = prop()
2626
const dirs = RNFetchBlob.fs.dirs
2727

2828
let prefix = ((Platform.OS === 'android') ? 'file://' : '')
29+
let bigfile = null
2930

3031
describe('Upload and download large file', (report, done) => {
31-
let filename = '22mb-dummy-' + Date.now()
32+
let filename = Platform.OS+'-0.7.0-22mb-dummy-' + Date.now()
3233
let begin = -1
3334
let begin2 = -1
3435
let deb = Date.now()
@@ -49,35 +50,91 @@ describe('Upload and download large file', (report, done) => {
4950
</Info>)
5051
})
5152
.then((res) => {
52-
try {
53+
bigfile = res.path()
54+
done()
55+
})
56+
// .then((res) => {
57+
// bigfile = res.path()
58+
// try {
59+
// deb = Date.now()
60+
// let promise = RNFetchBlob.fetch('POST', 'https://content.dropboxapi.com/2/files/upload', {
61+
// Authorization : `Bearer ${DROPBOX_TOKEN}`,
62+
// 'Dropbox-API-Arg': '{\"path\": \"/rn-upload/'+filename+'\",\"mode\": \"add\",\"autorename\": true,\"mute\": false}',
63+
// 'Content-Type' : 'application/octet-stream',
64+
// }, RNFetchBlob.wrap(res.path()))
65+
// promise.uploadProgress((now, total) => {
66+
// if(Date.now() - deb < 1000)
67+
// return
68+
// deb = Date.now()
69+
// if(begin2 === -1)
70+
// begin2 = Date.now()
71+
// let speed = Math.floor(now / (Date.now() - begin2))
72+
// report(<Info uid="100" key="progress">
73+
// <Text>
74+
// {`upload ${now} / ${total} bytes (${speed} kb/s)`}
75+
// {` ${Math.floor((total-now)/speed/1000)} seconds left`}
76+
// </Text>
77+
// </Info>)
78+
// })
79+
// return promise
80+
// } catch(err) { console.log(err) }
81+
// })
82+
// .then((res) => {
83+
// report(<Assert
84+
// key="upload should success without crashing app"
85+
// expect={filename}
86+
// actual={res.json().name}/>)
87+
// done()
88+
// })
89+
})
90+
91+
describe('cancel task should work properly', (report, done) => {
92+
let filename = Platform.OS+'-0.7.0-cancel-test-22mb-dummy-' + Date.now()
93+
let bytesWitten = 0
94+
let deb = Date.now()
95+
let begin = -1
96+
let promise = RNFetchBlob.fetch('POST', 'https://content.dropboxapi.com/2/files/upload', {
97+
Authorization : `Bearer ${DROPBOX_TOKEN}`,
98+
'Dropbox-API-Arg': '{\"path\": \"/rn-upload/'+filename+'\",\"mode\": \"add\",\"autorename\": true,\"mute\": false}',
99+
'Content-Type' : 'application/octet-stream',
100+
}, RNFetchBlob.wrap(bigfile))
101+
promise.uploadProgress((now, total) => {
102+
bytesWitten = now
103+
if(Date.now() - deb < 1000)
104+
return
53105
deb = Date.now()
54-
let promise = RNFetchBlob.fetch('POST', 'https://content.dropboxapi.com/2/files/upload', {
55-
Authorization : `Bearer ${DROPBOX_TOKEN}`,
56-
'Dropbox-API-Arg': '{\"path\": \"/rn-upload/'+filename+'\",\"mode\": \"add\",\"autorename\": true,\"mute\": false}',
57-
'Content-Type' : 'application/octet-stream',
58-
}, RNFetchBlob.wrap(res.path()))
59-
promise.uploadProgress((now, total) => {
60-
if(Date.now() - deb < 1000)
61-
return
62-
deb = Date.now()
63-
if(begin2 === -1)
64-
begin2 = Date.now()
65-
let speed = Math.floor(now / (Date.now() - begin2))
66-
report(<Info uid="100" key="progress">
67-
<Text>
68-
{`upload ${now} / ${total} bytes (${speed} kb/s)`}
69-
{` ${Math.floor((total-now)/speed/1000)} seconds left`}
70-
</Text>
71-
</Info>)
72-
})
73-
return promise
74-
} catch(err) { console.log(err) }
106+
if(begin === -1)
107+
begin = Date.now()
108+
let speed = Math.floor(now / (Date.now() - begin))
109+
report(<Info uid="100" key="progress">
110+
<Text>
111+
{`upload ${now} / ${total} bytes (${speed} kb/s)`}
112+
{` ${Math.floor((total-now)/speed/1000)} seconds left`}
113+
</Text>
114+
</Info>)
75115
})
76-
.then((res) => {
77-
report(<Assert
78-
key="upload should success without crashing app"
79-
expect={filename}
80-
actual={res.json().name}/>)
116+
let checkpoint1 = 0
117+
Timer.setTimeout(() => {
118+
promise.cancel()
119+
}, 5000)
120+
Timer.setTimeout(() => {
121+
checkpoint1 = bytesWitten
122+
}, 6000)
123+
Timer.setTimeout(() => {
124+
report(<Assert key="data should not write to stream after task is canceled"
125+
expect={checkpoint1}
126+
actual={bytesWitten}/>)
81127
done()
128+
}, 10000)
129+
promise.then((res) => {
130+
report(
131+
<Assert key="task not canceled"
132+
expected={false}
133+
actual={true}/>)
134+
})
135+
promise.catch((resp) => {
136+
report(<Assert key="task cancelled rejection should be catachable"
137+
expect={true}
138+
actual={true}/>)
82139
})
83140
})

test/test-init.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,12 @@ describe('GET image from server', (report, done) => {
5858
})
5959

6060

61-
require('./test-0.1.x-0.4.x')
62-
require('./test-0.5.1')
63-
require('./test-0.5.2')
64-
require('./test-0.6.0')
65-
require('./test-0.6.2')
66-
require('./test-0.6.3')
61+
// require('./test-0.1.x-0.4.x')
62+
// require('./test-0.5.1')
63+
// require('./test-0.5.2')
64+
// require('./test-0.6.0')
65+
// require('./test-0.6.2')
66+
// require('./test-0.6.3')
6767
require('./test-0.7.0')
68-
require('./test-fs')
69-
require('./test-android')
68+
// require('./test-fs')
69+
// require('./test-android')

0 commit comments

Comments
 (0)