Files
phonegap-plugins/iOS/FileUploader/FileUploader.m
Randy McMillan cc55edb5f0 FileUploader CDV 1.5.0 only
Preserve /iphone for PhoneGap - use /iOS for Cordova moving forward.
Not all projects are going to update to Cordova immediately and we
should preserve the PhoneGap plugins.
2012-03-22 16:34:28 -04:00

223 lines
7.1 KiB
Objective-C

//
// FileUploader.m
//
// Created by Matt Kane on 14/01/2011.
// Copyright 2011 Matt Kane. All rights reserved.
//
#import "FileUploader.h"
@implementation FileUploader
- (void) upload:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
{
NSUInteger argc = [arguments count];
if(argc < 2) {
return;
}
NSString* successCallback = [arguments objectAtIndex:0];
NSString* failCallback = [arguments objectAtIndex:1];
if(argc < 6) {
[self writeJavascript: [NSString stringWithFormat:@"%@(\"Argument error\");", failCallback]];
return;
}
NSString* progressCallback = [arguments objectAtIndex:2];
NSString* server = [arguments objectAtIndex:3];
NSURL* file = [NSURL fileURLWithPath:[arguments objectAtIndex:4] isDirectory: NO];
NSString* fileKey = nil;
NSString* fileName = nil;
NSString* mimeType = nil;
if(argc > 5) {
fileKey = [arguments objectAtIndex:5];
}
if(argc > 6) {
fileName = [arguments objectAtIndex:6];
}
if(argc > 7) {
mimeType = [arguments objectAtIndex:7];
}
[self uploadFile:file toServer:server withParams:options fileKey:fileKey fileName:fileName mimeType:mimeType successCallback:successCallback failCallback:failCallback progressCallback:progressCallback];
}
- (void) uploadByUri:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
{
NSUInteger argc = [arguments count];
if(argc < 2) {
return;
}
NSString* successCallback = [arguments objectAtIndex:0];
NSString* failCallback = [arguments objectAtIndex:1];
if(argc < 6) {
[self writeJavascript: [NSString stringWithFormat:@"%@(\"Argument error\");", failCallback]];
return;
}
NSString* progressCallback = [arguments objectAtIndex:2];
NSString* server = [arguments objectAtIndex:3];
NSURL* file = [NSURL URLWithString:[arguments objectAtIndex:4]];
NSString* fileKey = nil;
NSString* fileName = nil;
NSString* mimeType = nil;
if(argc > 5) {
fileKey = [arguments objectAtIndex:5];
}
if(argc > 6) {
fileName = [arguments objectAtIndex:6];
}
if(argc > 7) {
mimeType = [arguments objectAtIndex:7];
}
[self uploadFile:file toServer:server withParams:options fileKey:fileKey fileName:fileName mimeType:mimeType successCallback:successCallback failCallback:failCallback progressCallback:progressCallback];
}
- (void) uploadFile:(NSURL*)file toServer:(NSString*)server withParams:(NSMutableDictionary*)params fileKey:(NSString*)fileKey fileName:(NSString*)fileName mimeType:(NSString*)mimeType successCallback:(NSString*)successCallback failCallback:(NSString*)failCallback progressCallback:(NSString*)progressCallback
{
if (![file isFileURL]) {
[self writeJavascript: [NSString stringWithFormat:@"%@(\"Is not a valid file\");", failCallback]];
return;
}
if(!fileName) {
fileName = @"image.jpg";
}
if(!mimeType) {
mimeType = @"image/jpeg";
}
if(!fileKey) {
fileKey = @"file";
}
NSURL *url = [NSURL URLWithString:server];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
[req setHTTPMethod:@"POST"];
if([params objectForKey:@"__cookie"]) {
[req setValue:[params objectForKey:@"__cookie"] forHTTPHeaderField:@"Cookie"];
[params removeObjectForKey:@"__cookie"];
[req setHTTPShouldHandleCookies:NO];
}
NSString *boundary = @"*****com.beetight.formBoundary";
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
[req setValue:contentType forHTTPHeaderField:@"Content-type"];
[req setValue:@"XMLHttpRequest" forHTTPHeaderField:@"X-Requested-With"];
NSString* userAgent = [[self.webView request] valueForHTTPHeaderField:@"User-agent"];
if(userAgent) {
[req setValue: userAgent forHTTPHeaderField:@"User-agent"];
}
NSData *imageData = [NSData dataWithContentsOfURL:file];
if(!imageData) {
[self writeJavascript: [NSString stringWithFormat:@"%@(\"Could not open file\");", failCallback]];
return;
}
NSMutableData *postBody = [NSMutableData data];
NSEnumerator *enumerator = [params keyEnumerator];
id key;
id val;
while ((key = [enumerator nextObject])) {
val = [params objectForKey:key];
if(!val || val == [NSNull null]) {
continue;
}
[postBody appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[val dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
}
[postBody appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", fileKey, fileName] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", mimeType] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:imageData];
[postBody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[req setHTTPBody:postBody];
FileUploadDelegate* delegate = [[FileUploadDelegate alloc] init];
delegate.command = self;
delegate.successCallback = successCallback;
delegate.failCallback = failCallback;
delegate.progressCallback = progressCallback;
[[NSURLConnection connectionWithRequest:req delegate:delegate] retain];
}
@end
@implementation FileUploadDelegate
@synthesize successCallback, failCallback, progressCallback, responseData, command;
- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
{
if(!self.progressCallback) {
return;
}
if (uploadIdx++ % 10 == 0) {
[command writeJavascript: [NSString stringWithFormat:@"%@(%d, %d);", self.progressCallback, totalBytesWritten, totalBytesExpectedToWrite]];
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString* response = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
NSLog(@"reponse: %@", response);
NSString* js = [NSString stringWithFormat:@"%@(\"%@\");", self.successCallback, [response stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
[command writeJavascript: js];
[connection autorelease];
[self autorelease];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
[command writeJavascript: [NSString stringWithFormat:@"%@(\"%@\");", self.failCallback, [[error localizedDescription] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]];
[connection autorelease];
[self autorelease];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[responseData appendData:data];
}
- (id) init
{
if (self = [super init]) {
self.responseData = [NSMutableData data];
uploadIdx = 0;
}
return self;
}
- (void) dealloc
{
[successCallback release];
[failCallback release];
[responseData release];
[command release];
[super dealloc];
}
@end;