1+ //
2+ // FileUploader.m
3+ //
4+ // Created by Matt Kane on 14/01/2011.
5+ // Copyright 2011 Matt Kane. All rights reserved.
6+ //
7+
8+ #import " FileUploader.h"
9+
10+
11+ @implementation FileUploader
12+
13+ - (void ) upload : (NSMutableArray *)arguments withDict : (NSMutableDictionary *)options
14+ {
15+ NSUInteger argc = [arguments count ];
16+
17+ if (argc < 2 ) {
18+ return ;
19+ }
20+
21+ NSString * successCallback = [arguments objectAtIndex: 0 ];
22+ NSString * failCallback = [arguments objectAtIndex: 1 ];
23+
24+ if (argc < 6 ) {
25+ [self writeJavascript: [NSString stringWithFormat: @" %@ (\" Argument error\" );" , failCallback]];
26+ return ;
27+ }
28+
29+ NSString * progressCallback = [arguments objectAtIndex: 2 ];
30+ NSString * server = [arguments objectAtIndex: 3 ];
31+ NSURL * file = [NSURL fileURLWithPath: [arguments objectAtIndex: 4 ] isDirectory: NO ];
32+ NSString * fileKey = nil ;
33+ NSString * fileName = nil ;
34+ NSString * mimeType = nil ;
35+
36+ if (argc > 5 ) {
37+ fileKey = [arguments objectAtIndex: 5 ];
38+ }
39+
40+ if (argc > 6 ) {
41+ fileName = [arguments objectAtIndex: 6 ];
42+ }
43+
44+ if (argc > 7 ) {
45+ mimeType = [arguments objectAtIndex: 7 ];
46+ }
47+ [self uploadFile: file toServer: server withParams: options fileKey: fileKey fileName: fileName mimeType: mimeType successCallback: successCallback failCallback: failCallback progressCallback: progressCallback];
48+ }
49+
50+ - (void ) uploadByUri : (NSMutableArray *)arguments withDict : (NSMutableDictionary *)options
51+ {
52+ NSUInteger argc = [arguments count ];
53+
54+ if (argc < 2 ) {
55+ return ;
56+ }
57+
58+ NSString * successCallback = [arguments objectAtIndex: 0 ];
59+ NSString * failCallback = [arguments objectAtIndex: 1 ];
60+
61+ if (argc < 6 ) {
62+ [self writeJavascript: [NSString stringWithFormat: @" %@ (\" Argument error\" );" , failCallback]];
63+ return ;
64+ }
65+ NSString * progressCallback = [arguments objectAtIndex: 2 ];
66+ NSString * server = [arguments objectAtIndex: 3 ];
67+ NSURL * file = [NSURL URLWithString: [arguments objectAtIndex: 4 ]];
68+ NSString * fileKey = nil ;
69+ NSString * fileName = nil ;
70+ NSString * mimeType = nil ;
71+
72+ if (argc > 5 ) {
73+ fileKey = [arguments objectAtIndex: 5 ];
74+ }
75+
76+ if (argc > 6 ) {
77+ fileName = [arguments objectAtIndex: 6 ];
78+ }
79+
80+ if (argc > 7 ) {
81+ mimeType = [arguments objectAtIndex: 7 ];
82+ }
83+ [self uploadFile: file toServer: server withParams: options fileKey: fileKey fileName: fileName mimeType: mimeType successCallback: successCallback failCallback: failCallback progressCallback: progressCallback];
84+ }
85+
86+ - (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
87+ {
88+
89+ if (![file isFileURL ]) {
90+ [self writeJavascript: [NSString stringWithFormat: @" %@ (\" Is not a valid file\" );" , failCallback]];
91+ return ;
92+ }
93+
94+ if (!fileName) {
95+ fileName = @" image.jpg" ;
96+ }
97+
98+ if (!mimeType) {
99+ mimeType = @" image/jpeg" ;
100+ }
101+
102+ if (!fileKey) {
103+ fileKey = @" file" ;
104+ }
105+
106+ NSString *boundary = @" *****com.beetight.formBoundary" ;
107+
108+ NSURL *url = [NSURL URLWithString: server];
109+
110+ NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL: url];
111+ [req setHTTPMethod: @" POST" ];
112+
113+ NSString *contentType = [NSString stringWithFormat: @" multipart/form-data; boundary=%@ " , boundary];
114+ [req setValue: contentType forHTTPHeaderField: @" Content-type" ];
115+ NSString * userAgent = [[webView request ] valueForHTTPHeaderField: @" User-agent" ];
116+ if (userAgent) {
117+ [req setValue: userAgent forHTTPHeaderField: @" User-agent" ];
118+ }
119+
120+ NSData *imageData = [NSData dataWithContentsOfURL: file];
121+
122+ if (!imageData) {
123+ [self writeJavascript: [NSString stringWithFormat: @" %@ (\" Could not open file\" );" , failCallback]];
124+ return ;
125+ }
126+
127+ NSMutableData *postBody = [NSMutableData data ];
128+
129+ NSEnumerator *enumerator = [params keyEnumerator ];
130+ id key;
131+ id val;
132+ while ((key = [enumerator nextObject ])) {
133+ val = [params objectForKey: key];
134+ if (!val || val == [NSNull null ]) {
135+ continue ;
136+ }
137+ [postBody appendData: [[NSString stringWithFormat: @" --%@ \r\n " , boundary] dataUsingEncoding: NSUTF8StringEncoding]];
138+ [postBody appendData: [[NSString stringWithFormat: @" Content-Disposition: form-data; name=\" %@ \"\r\n\r\n " , key] dataUsingEncoding: NSUTF8StringEncoding]];
139+ [postBody appendData: [val dataUsingEncoding: NSUTF8StringEncoding]];
140+ [postBody appendData: [@" \r\n " dataUsingEncoding: NSUTF8StringEncoding]];
141+ }
142+
143+ [postBody appendData: [[NSString stringWithFormat: @" --%@ \r\n " , boundary] dataUsingEncoding: NSUTF8StringEncoding]];
144+ [postBody appendData: [[NSString stringWithFormat: @" Content-Disposition: form-data; name=\" %@ \" ; filename=\" %@ \"\r\n " , fileKey, fileName] dataUsingEncoding: NSUTF8StringEncoding]];
145+ [postBody appendData: [[NSString stringWithFormat: @" Content-Type: %@ \r\n\r\n " , mimeType] dataUsingEncoding: NSUTF8StringEncoding]];
146+ [postBody appendData: imageData];
147+ [postBody appendData: [[NSString stringWithFormat: @" \r\n --%@ \r\n " , boundary] dataUsingEncoding: NSUTF8StringEncoding]];
148+ [req setHTTPBody: postBody];
149+
150+ FileUploadDelegate* delegate = [[[FileUploadDelegate alloc ] init ] retain ];
151+ delegate.command = self;
152+ delegate.successCallback = successCallback;
153+ delegate.failCallback = failCallback;
154+ delegate.progressCallback = progressCallback;
155+
156+ NSURLConnection * connection = [[NSURLConnection connectionWithRequest: req delegate: delegate] retain ];
157+ }
158+
159+ @end
160+
161+
162+ @implementation FileUploadDelegate
163+
164+ @synthesize successCallback, failCallback, progressCallback, responseData, command;
165+
166+ - (void )connection : (NSURLConnection *)connection didSendBodyData : (NSInteger )bytesWritten totalBytesWritten : (NSInteger )totalBytesWritten totalBytesExpectedToWrite : (NSInteger )totalBytesExpectedToWrite
167+ {
168+ if (!self.progressCallback ) {
169+ return ;
170+ }
171+ if (uploadIdx++ % 10 == 0 ) {
172+ [command writeJavascript: [NSString stringWithFormat: @" %@ (%d , %d );" , self .progressCallback, totalBytesWritten, totalBytesExpectedToWrite]];
173+ }
174+ }
175+
176+ - (void )connectionDidFinishLoading : (NSURLConnection *)connection
177+ {
178+ NSString * response = [[NSString alloc ] initWithData: self .responseData encoding: NSUTF8StringEncoding];
179+ NSLog (@" reponse: %@ " , response);
180+ NSString * js = [NSString stringWithFormat: @" %@ (\" %@ \" );" , self .successCallback, [response stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
181+ [command writeJavascript: js];
182+ [connection autorelease ];
183+ [self autorelease ];
184+ }
185+
186+ - (void )connection : (NSURLConnection *)connection didFailWithError : (NSError *)error
187+ {
188+ [command writeJavascript: [NSString stringWithFormat: @" %@ (\" %@ \" );" , self .failCallback, [[error localizedDescription ] stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]]];
189+ [connection autorelease ];
190+ [self autorelease ];
191+ }
192+
193+ - (void )connection : (NSURLConnection *)connection didReceiveData : (NSData *)data
194+ {
195+ [responseData appendData: data];
196+ }
197+
198+ - (id ) init
199+ {
200+ if (self = [super init ]) {
201+ self.responseData = [NSMutableData data ];
202+ uploadIdx = 0 ;
203+ }
204+ return self;
205+ }
206+
207+ - (void ) dealloc
208+ {
209+ [successCallback release ];
210+ [failCallback release ];
211+ [responseData release ];
212+ [command release ];
213+ [super dealloc ];
214+ }
215+
216+
217+ @end ;
0 commit comments