現成的代碼, 如果不想壓縮,可以去掉zlib
.h檔案
@interface EPUploader : NSObject {<br />NSURL *serverURL;<br />NSString *filePath;<br />id delegate;<br />SEL doneSelector;<br />SEL errorSelector;<br />BOOL uploadDidSucceed;<br />}<br />- (id)initWithURL: (NSURL *)serverURL<br />filePath: (NSString *)filePath<br />delegate: (id)delegate<br />doneSelector: (SEL)doneSelector<br />errorSelector: (SEL)errorSelector;<br />- (NSString *)filePath;<br />@end<br />
.m檔案 (比較長啊)
#import "EPUploader.h"<br />static NSString * const BOUNDRY = @"0xKhTmLbOuNdArY";<br />static NSString * const FORM_FLE_INPUT = @"uploaded";<br />#define ASSERT(x) NSAssert(x, @"")<br />@interface EPUploader (Private)<br />- (void)upload;<br />- (NSURLRequest *)postRequestWithURL: (NSURL *)url<br /> boundry: (NSString *)boundry<br />data: (NSData *)data;<br />- (NSData *)compress: (NSData *)data;<br />- (void)uploadSucceeded: (BOOL)success;<br />- (void)connectionDidFinishLoading:(NSURLConnection *)connection;<br />@end<br />@implementation EPUploader<br />/*<br /> *-----------------------------------------------------------------------------<br /> *<br /> * -[Uploader initWithURL:filePath:delegate:doneSelector:errorSelector:] --<br /> *<br /> * Initializer. Kicks off the upload. Note that upload will happen on a<br /> * separate thread.<br /> *<br /> * Results:<br /> * An instance of Uploader.<br /> *<br /> * Side effects:<br /> * None<br /> *<br /> *-----------------------------------------------------------------------------<br /> */<br />- (id)initWithURL: (NSURL *)aServerURL // IN<br /> filePath: (NSString *)aFilePath // IN<br /> delegate: (id)aDelegate // IN<br /> doneSelector: (SEL)aDoneSelector// IN<br />errorSelector: (SEL)anErrorSelector // IN<br />{<br />if ((self = [super init])) {<br />ASSERT(aServerURL);<br />ASSERT(aFilePath);<br />ASSERT(aDelegate);<br />ASSERT(aDoneSelector);<br />ASSERT(anErrorSelector);<br />serverURL = [aServerURL retain];<br />filePath = [aFilePath retain];<br />delegate = [aDelegate retain];<br />doneSelector = aDoneSelector;<br />errorSelector = anErrorSelector;<br />[self upload];<br />}<br />return self;<br />}<br />/*<br /> *-----------------------------------------------------------------------------<br /> *<br /> * -[Uploader dealloc] --<br /> *<br /> * Destructor.<br /> *<br /> * Results:<br /> * None<br /> *<br /> * Side effects:<br /> * None<br /> *<br /> *-----------------------------------------------------------------------------<br /> */<br />- (void)dealloc<br />{<br />[serverURL release];<br />serverURL = nil;<br />[filePath release];<br />filePath = nil;<br />[delegate release];<br />delegate = nil;<br />doneSelector = NULL;<br />errorSelector = NULL;<br />[super dealloc];<br />}<br />/*<br /> *-----------------------------------------------------------------------------<br /> *<br /> * -[Uploader filePath] --<br /> *<br /> * Gets the path of the file this object is uploading.<br /> *<br /> * Results:<br /> * Path to the upload file.<br /> *<br /> * Side effects:<br /> * None<br /> *<br /> *-----------------------------------------------------------------------------<br /> */<br />- (NSString *)filePath<br />{<br />return filePath;<br />}<br />@end // Uploader<br />@implementation EPUploader (Private)<br />/*<br /> *-----------------------------------------------------------------------------<br /> *<br /> * -[Uploader(Private) upload] --<br /> *<br /> * Uploads the given file. The file is compressed before beign uploaded.<br /> * The data is uploaded using an HTTP POST command.<br /> *<br /> * Results:<br /> * None<br /> *<br /> * Side effects:<br /> * None<br /> *<br /> *-----------------------------------------------------------------------------<br /> */<br />- (void)upload<br />{<br />NSData *data = [NSData dataWithContentsOfFile:filePath];<br />ASSERT(data);<br />if (!data) {<br />[self uploadSucceeded:NO];<br />return;<br />}<br />if ([data length] == 0) {<br />// There's no data, treat this the same as no file.<br />[self uploadSucceeded:YES];<br />return;<br />}<br />// NSData *compressedData = [self compress:data];<br />// ASSERT(compressedData && [compressedData length] != 0);<br />// if (!compressedData || [compressedData length] == 0) {<br />// [self uploadSucceeded:NO];<br />// return;<br />// }<br />NSURLRequest *urlRequest = [self postRequestWithURL:serverURL<br />boundry:BOUNDRY<br /> data:data];<br />if (!urlRequest) {<br />[self uploadSucceeded:NO];<br />return;<br />}<br />NSURLConnection * connection =<br />[[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];<br />if (!connection) {<br />[self uploadSucceeded:NO];<br />}<br />// Now wait for the URL connection to call us back.<br />}<br />/*<br /> *-----------------------------------------------------------------------------<br /> *<br /> * -[Uploader(Private) postRequestWithURL:boundry:data:] --<br /> *<br /> * Creates a HTML POST request.<br /> *<br /> * Results:<br /> * The HTML POST request.<br /> *<br /> * Side effects:<br /> * None<br /> *<br /> *-----------------------------------------------------------------------------<br /> */<br />- (NSURLRequest *)postRequestWithURL: (NSURL *)url// IN<br /> boundry: (NSString *)boundry // IN<br />data: (NSData *)data // IN<br />{<br />// from http://www.cocoadev.com/index.pl?HTTPFileUpload<br />NSMutableURLRequest *urlRequest =<br />[NSMutableURLRequest requestWithURL:url];<br />[urlRequest setHTTPMethod:@"POST"];<br />[urlRequest setValue:<br /> [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundry]<br /> forHTTPHeaderField:@"Content-Type"];<br />NSMutableData *postData =<br />[NSMutableData dataWithCapacity:[data length] + 512];<br />[postData appendData:<br /> [[NSString stringWithFormat:@"--%@/r/n", boundry] dataUsingEncoding:NSUTF8StringEncoding]];<br />[postData appendData:<br /> [[NSString stringWithFormat:<br /> @"Content-Disposition: form-data; name=/"%@/"; filename=/"file.bin/"/r/n/r/n", FORM_FLE_INPUT]<br /> dataUsingEncoding:NSUTF8StringEncoding]];<br />[postData appendData:data];<br />[postData appendData:<br /> [[NSString stringWithFormat:@"/r/n--%@--/r/n", boundry] dataUsingEncoding:NSUTF8StringEncoding]];<br />[urlRequest setHTTPBody:postData];<br />return urlRequest;<br />}<br />/*<br /> *-----------------------------------------------------------------------------<br /> *<br /> * -[Uploader(Private) compress:] --<br /> *<br /> * Uses zlib to compress the given data.<br /> *<br /> * Results:<br /> * The compressed data as a NSData object.<br /> *<br /> * Side effects:<br /> * None<br /> *<br /> *-----------------------------------------------------------------------------<br /> */<br />- (NSData *)compress: (NSData *)data // IN<br />{<br />if (!data || [data length] == 0)<br />return nil;<br />// zlib compress doc says destSize must be 1% + 12 bytes greater than source.<br />uLong destSize = [data length] * 1.001 + 12;<br />NSMutableData *destData = [NSMutableData dataWithLength:destSize];<br />int error = compress([destData mutableBytes],<br /> &destSize,<br /> [data bytes],<br /> [data length]);<br />if (error != Z_OK) {<br />NSLog(@"%s: self:0x%p, zlib error on compress:%d/n",__func__, self, error);<br />return nil;<br />}<br />[destData setLength:destSize];<br />return destData;<br />}<br />/*<br /> *-----------------------------------------------------------------------------<br /> *<br /> * -[Uploader(Private) uploadSucceeded:] --<br /> *<br /> * Used to notify the delegate that the upload did or did not succeed.<br /> *<br /> * Results:<br /> * None<br /> *<br /> * Side effects:<br /> * None<br /> *<br /> *-----------------------------------------------------------------------------<br /> */<br />- (void)uploadSucceeded: (BOOL)success // IN<br />{<br />[delegate performSelector:success ? doneSelector : errorSelector<br /> withObject:self];<br />}<br />/*<br /> *-----------------------------------------------------------------------------<br /> *<br /> * -[Uploader(Private) connectionDidFinishLoading:] --<br /> *<br /> * Called when the upload is complete. We judge the success of the upload<br /> * based on the reply we get from the server.<br /> *<br /> * Results:<br /> * None<br /> *<br /> * Side effects:<br /> * None<br /> *<br /> *-----------------------------------------------------------------------------<br /> */<br />- (void)connectionDidFinishLoading:(NSURLConnection *)connection // IN<br />{<br />NSLog(@"%s: self:0x%p/n", __func__, self);<br />[connection release];<br />[self uploadSucceeded:uploadDidSucceed];<br />}<br />/*<br /> *-----------------------------------------------------------------------------<br /> *<br /> * -[Uploader(Private) connection:didFailWithError:] --<br /> *<br /> * Called when the upload failed (probably due to a lack of network<br /> * connection).<br /> *<br /> * Results:<br /> * None<br /> *<br /> * Side effects:<br /> * None<br /> *<br /> *-----------------------------------------------------------------------------<br /> */<br />- (void)connection:(NSURLConnection *)connection // IN<br /> didFailWithError:(NSError *)error // IN<br />{<br />NSLog(@"%s: self:0x%p, connection error:%s/n",<br />__func__, self, [[error description] UTF8String]);<br />[connection release];<br />[self uploadSucceeded:NO];<br />}<br />/*<br /> *-----------------------------------------------------------------------------<br /> *<br /> * -[Uploader(Private) connection:didReceiveResponse:] --<br /> *<br /> * Called as we get responses from the server.<br /> *<br /> * Results:<br /> * None<br /> *<br /> * Side effects:<br /> * None<br /> *<br /> *-----------------------------------------------------------------------------<br /> */<br />-(void) connection:(NSURLConnection *)connection // IN<br /> didReceiveResponse:(NSURLResponse *)response // IN<br />{<br />NSLog(@"%s: self:0x%p/n", __func__, self);<br />}<br />/*<br /> *-----------------------------------------------------------------------------<br /> *<br /> * -[Uploader(Private) connection:didReceiveData:] --<br /> *<br /> * Called when we have data from the server. We expect the server to reply<br /> * with a "YES" if the upload succeeded or "NO" if it did not.<br /> *<br /> * Results:<br /> * None<br /> *<br /> * Side effects:<br /> * None<br /> *<br /> *-----------------------------------------------------------------------------<br /> */<br />- (void)connection:(NSURLConnection *)connection // IN<br />didReceiveData:(NSData *)data// IN<br />{<br />NSLog(@"%s: self:0x%p/n", __func__, self);<br />NSString *reply = [[[NSString alloc] initWithData:data<br /> encoding:NSUTF8StringEncoding]<br /> autorelease];<br />NSLog(@"%s: data: %s/n", __func__, [reply UTF8String]);<br />if ([reply hasPrefix:@"YES"]) {<br />uploadDidSucceed = YES;<br />}<br />}<br />@end
使用檔案:
[[EPUploader alloc] initWithURL:[NSURL URLWithString:@"http://yourserver.com/uploadDB.php"]<br />filePath:@"path/to/some/file"<br />delegate:self<br />doneSelector:@selector(onUploadDone:)<br />errorSelector:@selector(onUploadError:)];<br />
轉載自:
FLYBLOG
[
http://www.flyblog.info
]