145 lines
5.4 KiB
Objective-C
145 lines
5.4 KiB
Objective-C
#import "Uploader.h"
|
|
|
|
@implementation RNFSUploadParams
|
|
|
|
@end
|
|
|
|
@interface RNFSUploader()
|
|
|
|
@property (copy) RNFSUploadParams* params;
|
|
|
|
@property (retain) NSURLSessionDataTask* task;
|
|
|
|
@end
|
|
|
|
@implementation RNFSUploader
|
|
|
|
- (void)uploadFiles:(RNFSUploadParams*)params
|
|
{
|
|
_params = params;
|
|
|
|
NSString *method = _params.method;
|
|
NSURL *url = [NSURL URLWithString:_params.toUrl];
|
|
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
|
|
[req setHTTPMethod:method];
|
|
|
|
// set headers
|
|
NSString *formBoundaryString = [self generateBoundaryString];
|
|
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", formBoundaryString];
|
|
[req setValue:contentType forHTTPHeaderField:@"Content-Type"];
|
|
for (NSString *key in _params.headers) {
|
|
id val = [_params.headers objectForKey:key];
|
|
if ([val respondsToSelector:@selector(stringValue)]) {
|
|
val = [val stringValue];
|
|
}
|
|
if (![val isKindOfClass:[NSString class]]) {
|
|
continue;
|
|
}
|
|
[req setValue:val forHTTPHeaderField:key];
|
|
}
|
|
|
|
NSData *formBoundaryData = [[NSString stringWithFormat:@"--%@\r\n", formBoundaryString] dataUsingEncoding:NSUTF8StringEncoding];
|
|
NSMutableData* reqBody = [NSMutableData data];
|
|
|
|
// add fields
|
|
for (NSString *key in _params.fields) {
|
|
id val = [_params.fields objectForKey:key];
|
|
if ([val respondsToSelector:@selector(stringValue)]) {
|
|
val = [val stringValue];
|
|
}
|
|
if (![val isKindOfClass:[NSString class]]) {
|
|
continue;
|
|
}
|
|
|
|
[reqBody appendData:formBoundaryData];
|
|
[reqBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]];
|
|
[reqBody appendData:[val dataUsingEncoding:NSUTF8StringEncoding]];
|
|
[reqBody appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
|
|
}
|
|
|
|
// add files
|
|
for (NSDictionary *file in _params.files) {
|
|
NSString *name = file[@"name"];
|
|
NSString *filename = file[@"filename"];
|
|
NSString *filepath = file[@"filepath"];
|
|
NSString *filetype = file[@"filetype"];
|
|
|
|
// Check if file exists
|
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
if (![fileManager fileExistsAtPath:filepath]){
|
|
// NSError* error = [NSError errorWithDomain:@"Uploader" code:NSURLErrorFileDoesNotExist userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat: @"Failed to open target file at path: %@", filepath]}];
|
|
// return _params.errorCallback(error);
|
|
NSLog(@"Failed to open target file at path: %@", filepath);
|
|
continue;
|
|
}
|
|
|
|
NSData *fileData = [NSData dataWithContentsOfFile:filepath];
|
|
|
|
[reqBody appendData:formBoundaryData];
|
|
[reqBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", name.length ? name : filename, filename] dataUsingEncoding:NSUTF8StringEncoding]];
|
|
|
|
if (filetype) {
|
|
[reqBody appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n", filetype] dataUsingEncoding:NSUTF8StringEncoding]];
|
|
} else {
|
|
[reqBody appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n", [self mimeTypeForPath:filename]] dataUsingEncoding:NSUTF8StringEncoding]];
|
|
}
|
|
|
|
[reqBody appendData:[[NSString stringWithFormat:@"Content-Length: %ld\r\n\r\n", (long)[fileData length]] dataUsingEncoding:NSUTF8StringEncoding]];
|
|
[reqBody appendData:fileData];
|
|
[reqBody appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
|
|
}
|
|
|
|
// add end boundary
|
|
NSData* end = [[NSString stringWithFormat:@"--%@--\r\n", formBoundaryString] dataUsingEncoding:NSUTF8StringEncoding];
|
|
[reqBody appendData:end];
|
|
|
|
// send request
|
|
[req setHTTPBody:reqBody];
|
|
|
|
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
|
|
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:(id)self delegateQueue:[NSOperationQueue mainQueue]];
|
|
_task = [session dataTaskWithRequest:req completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
|
|
NSString * str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
|
return _params.completeCallback(str, response);
|
|
}];
|
|
[_task resume];
|
|
_params.beginCallback();
|
|
}
|
|
|
|
- (NSString *)generateBoundaryString
|
|
{
|
|
NSString *uuid = [[NSUUID UUID] UUIDString];
|
|
return [NSString stringWithFormat:@"----%@", uuid];
|
|
}
|
|
|
|
- (NSString *)mimeTypeForPath:(NSString *)filepath
|
|
{
|
|
NSString *fileExtension = [filepath pathExtension];
|
|
NSString *UTI = (__bridge_transfer NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)fileExtension, NULL);
|
|
NSString *contentType = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)UTI, kUTTagClassMIMEType);
|
|
|
|
if (contentType) {
|
|
return contentType;
|
|
}
|
|
return @"application/octet-stream";
|
|
}
|
|
|
|
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
|
|
{
|
|
if(error != nil) {
|
|
return _params.errorCallback(error);
|
|
}
|
|
}
|
|
|
|
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(NSInteger)totalBytesExpectedToSend
|
|
{
|
|
return _params.progressCallback([NSNumber numberWithLongLong:totalBytesExpectedToSend], [NSNumber numberWithLongLong:totalBytesSent]);
|
|
}
|
|
|
|
- (void)stopUpload
|
|
{
|
|
[_task cancel];
|
|
}
|
|
|
|
@end
|