如何使用 iPhone 将照片上传到服务器?

我正在编写一个 iPhone 应用程序,它可以拍一张照片,然后上传到服务器上。如何使用 Cocoa 将照片上传到服务器?我想我在某个地方用过 NSUrl。

谢谢!

80940 次浏览

创建一个 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。

//图像名称的日期格式..。

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");
}


}

如果你想上传多张图片,那么 这个小样是一个不错的选择。