我正在编写一个 iPhone 应用程序,它可以拍一张照片,然后上传到服务器上。如何使用 Cocoa 将照片上传到服务器?我想我在某个地方用过 NSUrl。
谢谢!
创建一个 NSULRequest,然后使用 NSULConnection 将其发送到服务器。
标题:
@interface EPUploader : NSObject { NSURL *serverURL; NSString *filePath; id delegate; SEL doneSelector; SEL errorSelector; BOOL uploadDidSucceed; } - (id)initWithURL: (NSURL *)serverURL filePath: (NSString *)filePath delegate: (id)delegate doneSelector: (SEL)doneSelector errorSelector: (SEL)errorSelector; - (NSString *)filePath; @end
主要内容:
#import "EPUploader.h" #import <zlib.h> static NSString * const BOUNDRY = @"0xKhTmLbOuNdArY"; static NSString * const FORM_FLE_INPUT = @"uploaded"; #define ASSERT(x) NSAssert(x, @"") @interface EPUploader (Private) - (void)upload; - (NSURLRequest *)postRequestWithURL: (NSURL *)url boundry: (NSString *)boundry data: (NSData *)data; - (NSData *)compress: (NSData *)data; - (void)uploadSucceeded: (BOOL)success; - (void)connectionDidFinishLoading:(NSURLConnection *)connection; @end @implementation EPUploader /* *----------------------------------------------------------------------------- * * -[Uploader initWithURL:filePath:delegate:doneSelector:errorSelector:] -- * * Initializer. Kicks off the upload. Note that upload will happen on a * separate thread. * * Results: * An instance of Uploader. * * Side effects: * None * *----------------------------------------------------------------------------- */ - (id)initWithURL: (NSURL *)aServerURL // IN filePath: (NSString *)aFilePath // IN delegate: (id)aDelegate // IN doneSelector: (SEL)aDoneSelector // IN errorSelector: (SEL)anErrorSelector // IN { if ((self = [super init])) { ASSERT(aServerURL); ASSERT(aFilePath); ASSERT(aDelegate); ASSERT(aDoneSelector); ASSERT(anErrorSelector); serverURL = [aServerURL retain]; filePath = [aFilePath retain]; delegate = [aDelegate retain]; doneSelector = aDoneSelector; errorSelector = anErrorSelector; [self upload]; } return self; } /* *----------------------------------------------------------------------------- * * -[Uploader dealloc] -- * * Destructor. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ - (void)dealloc { [serverURL release]; serverURL = nil; [filePath release]; filePath = nil; [delegate release]; delegate = nil; doneSelector = NULL; errorSelector = NULL; [super dealloc]; } /* *----------------------------------------------------------------------------- * * -[Uploader filePath] -- * * Gets the path of the file this object is uploading. * * Results: * Path to the upload file. * * Side effects: * None * *----------------------------------------------------------------------------- */ - (NSString *)filePath { return filePath; } @end // Uploader @implementation EPUploader (Private) /* *----------------------------------------------------------------------------- * * -[Uploader(Private) upload] -- * * Uploads the given file. The file is compressed before beign uploaded. * The data is uploaded using an HTTP POST command. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ - (void)upload { NSData *data = [NSData dataWithContentsOfFile:filePath]; ASSERT(data); if (!data) { [self uploadSucceeded:NO]; return; } if ([data length] == 0) { // There's no data, treat this the same as no file. [self uploadSucceeded:YES]; return; } // NSData *compressedData = [self compress:data]; // ASSERT(compressedData && [compressedData length] != 0); // if (!compressedData || [compressedData length] == 0) { // [self uploadSucceeded:NO]; // return; // } NSURLRequest *urlRequest = [self postRequestWithURL:serverURL boundry:BOUNDRY data:data]; if (!urlRequest) { [self uploadSucceeded:NO]; return; } NSURLConnection * connection = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self]; if (!connection) { [self uploadSucceeded:NO]; } // Now wait for the URL connection to call us back. } /* *----------------------------------------------------------------------------- * * -[Uploader(Private) postRequestWithURL:boundry:data:] -- * * Creates a HTML POST request. * * Results: * The HTML POST request. * * Side effects: * None * *----------------------------------------------------------------------------- */ - (NSURLRequest *)postRequestWithURL: (NSURL *)url // IN boundry: (NSString *)boundry // IN data: (NSData *)data // IN { // from http://www.cocoadev.com/index.pl?HTTPFileUpload NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url]; [urlRequest setHTTPMethod:@"POST"]; [urlRequest setValue: [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundry] forHTTPHeaderField:@"Content-Type"]; NSMutableData *postData = [NSMutableData dataWithCapacity:[data length] + 512]; [postData appendData: [[NSString stringWithFormat:@"--%@\r\n", boundry] dataUsingEncoding:NSUTF8StringEncoding]]; [postData appendData: [[NSString stringWithFormat: @"Content-Disposition: form-data; name=\"%@\"; filename=\"file.bin\"\r\n\r\n", FORM_FLE_INPUT] dataUsingEncoding:NSUTF8StringEncoding]]; [postData appendData:data]; [postData appendData: [[NSString stringWithFormat:@"\r\n--%@--\r\n", boundry] dataUsingEncoding:NSUTF8StringEncoding]]; [urlRequest setHTTPBody:postData]; return urlRequest; } /* *----------------------------------------------------------------------------- * * -[Uploader(Private) compress:] -- * * Uses zlib to compress the given data. * * Results: * The compressed data as a NSData object. * * Side effects: * None * *----------------------------------------------------------------------------- */ - (NSData *)compress: (NSData *)data // IN { if (!data || [data length] == 0) return nil; // zlib compress doc says destSize must be 1% + 12 bytes greater than source. uLong destSize = [data length] * 1.001 + 12; NSMutableData *destData = [NSMutableData dataWithLength:destSize]; int error = compress([destData mutableBytes], &destSize, [data bytes], [data length]); if (error != Z_OK) { NSLog(@"%s: self:0x%p, zlib error on compress:%d\n",__func__, self, error); return nil; } [destData setLength:destSize]; return destData; } /* *----------------------------------------------------------------------------- * * -[Uploader(Private) uploadSucceeded:] -- * * Used to notify the delegate that the upload did or did not succeed. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ - (void)uploadSucceeded: (BOOL)success // IN { [delegate performSelector:success ? doneSelector : errorSelector withObject:self]; } /* *----------------------------------------------------------------------------- * * -[Uploader(Private) connectionDidFinishLoading:] -- * * Called when the upload is complete. We judge the success of the upload * based on the reply we get from the server. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ - (void)connectionDidFinishLoading:(NSURLConnection *)connection // IN { NSLog(@"%s: self:0x%p\n", __func__, self); [connection release]; [self uploadSucceeded:uploadDidSucceed]; } /* *----------------------------------------------------------------------------- * * -[Uploader(Private) connection:didFailWithError:] -- * * Called when the upload failed (probably due to a lack of network * connection). * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ - (void)connection:(NSURLConnection *)connection // IN didFailWithError:(NSError *)error // IN { NSLog(@"%s: self:0x%p, connection error:%s\n", __func__, self, [[error description] UTF8String]); [connection release]; [self uploadSucceeded:NO]; } /* *----------------------------------------------------------------------------- * * -[Uploader(Private) connection:didReceiveResponse:] -- * * Called as we get responses from the server. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ -(void) connection:(NSURLConnection *)connection // IN didReceiveResponse:(NSURLResponse *)response // IN { NSLog(@"%s: self:0x%p\n", __func__, self); } /* *----------------------------------------------------------------------------- * * -[Uploader(Private) connection:didReceiveData:] -- * * Called when we have data from the server. We expect the server to reply * with a "YES" if the upload succeeded or "NO" if it did not. * * Results: * None * * Side effects: * None * *----------------------------------------------------------------------------- */ - (void)connection:(NSURLConnection *)connection // IN didReceiveData:(NSData *)data // IN { NSLog(@"%s: self:0x%p\n", __func__, self); NSString *reply = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]; NSLog(@"%s: data: %s\n", __func__, [reply UTF8String]); if ([reply hasPrefix:@"YES"]) { uploadDidSucceed = YES; } } @end
用法:
[[EPUploader alloc] initWithURL:[NSURL URLWithString:@"http://yourserver.com/uploadDB.php"] filePath:@"path/to/some/file" delegate:self doneSelector:@selector(onUploadDone:) errorSelector:@selector(onUploadError:)];
看起来 320库支持将图像 POSTing 到 HTTP 服务器。
参见 TTURLRequest.m
它以 Apache 2.0许可证发布。
希望下面的代码片段对您有用。我已经使用了 NSDateFormatter 和 NSDate 来获得每次映像的唯一名称。
注意: 'ImageUploadURL'是带有基本 URL 的字符串 # Definition,您需要将其替换为服务器 URL。
'ImageUploadURL'
//图像名称的日期格式..。
NSDateFormatter *format = [[NSDateFormatter alloc] init]; [format setDateFormat:@"yyyyMMddHHmmss"]; NSDate *now = [[NSDate alloc] init]; NSString *imageName = [NSString stringWithFormat:@"Image_%@", [format stringFromDate:now]]; [now release]; [format release]; NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease]; [request setURL:[NSURL URLWithString:ImageUploadURL]]; [request setHTTPMethod:@"POST"]; /* Set Header and content type of your request. */ NSString *boundary = [NSString stringWithString:@"---------------------------Boundary Line---------------------------"]; NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary]; [request addValue:contentType forHTTPHeaderField: @"Content-Type"]; /* now lets create the body of the request. */ NSMutableData *body = [NSMutableData data]; [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"userfile\"; filename=\"%@.jpg\"\r\n", imageName] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithString:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[NSData dataWithData:UIImageJPEGRepresentation(image, 90)]]; [body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithFormat:@"geotag=%@&", [self _currentLocationMetadata]] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]]; // set body with request. [request setHTTPBody:body]; [request addValue:[NSString stringWithFormat:@"%d", [body length]] forHTTPHeaderField:@"Content-Length"]; // now lets make the connection to the web [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
- (void) uploadImage :(NSString *) strRequest { if([appdel checkNetwork]==TRUE) { NSString *urlString =[NSString stringWithFormat:@"Enter Url........."]; NSLog(@"Upload %@",urlString); // setting up the request object now isUploadImage=TRUE; totalsize=[[strRequest dataUsingEncoding:NSUTF8StringEncoding]length]; NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease]; [request setURL:[NSURL URLWithString:urlString]]; [request setHTTPMethod:@"POST"]; NSString *boundary = [NSString stringWithString:@"_1_19330907_1317415362628"]; NSString *contentType = [NSString stringWithFormat:@"multipart/mixed; boundary=%@",boundary]; [request setValue:contentType forHTTPHeaderField: @"Content-Type"]; [request setValue:@"text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" forHTTPHeaderField:@"Accept"]; [request setValue:@"2667" forHTTPHeaderField:@"Content-Length"]; /* now lets create the body of the post */ NSMutableData *body = [NSMutableData data]; [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithString:@"Content-Type: application/json\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; //[body appendData:[NSData dataWithData:imageData]]; [body appendData:[strRequest dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]]; // setting the body of the post to the reqeust [request setHTTPBody:body]; theConnection=[[NSURLConnection alloc] initWithRequest:request delegate:self]; if (theConnection) webData = [[NSMutableData data] retain]; else NSLog(@"No Connection"); } }
如果你想上传多张图片,那么 这个小样是一个不错的选择。