我正在尝试上传从照片库中获取的图像,从 iOS 到 PHP。
当我将它发送到服务器时,服务器输出文件的详细信息如下:
[userfile] => Array
(
[name] => 001file.jpg
[type] =>
[tmp_name] => /tmp/php5VSe1V
[error] => 0
[size] => 9530
)
但是,“类型”部分总是空的,我不知道为什么。当我更改多部分/表单数据时;对于 application/octet-stream,输出数组为 NULL。
有任何想法吗?提前致谢。
视图控制器.m
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
[self dismissViewControllerAnimated:YES completion:NULL];
fileURL = [info objectForKey:UIImagePickerControllerReferenceURL];
NSLog(@"fileurl %@",fileURL);
NSData * data = [NSData dataWithContentsOfURL:fileURL];
NSLog(@"bites %d",[data length]);
UIImage * originalImage = (UIImage *) [info objectForKey:
UIImagePickerControllerOriginalImage];
[imageView setImage:originalImage];
NSString * photoFile = [[NSString alloc]init];
ALAssetsLibrary *assetLibrary=[[ALAssetsLibrary alloc] init];
[assetLibrary assetForURL:fileURL resultBlock:^(ALAsset *asset) {
NSLog(@"asset %@",asset);
ALAssetRepresentation *rep = [asset defaultRepresentation];
Byte *buffer = (Byte*)malloc(rep.size);
NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:rep.size error:nil];
theImageData = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];//this is NSData may be what you want
NSLog(@"data bytesss a z%d",[theImageData length]);
//[data writeToFile:photoFile atomically:YES];//you can save image later
} failureBlock:^(NSError *err) {
NSLog(@"Error: %@",[err localizedDescription]);
}];
NSLog(@"data bytesss %d",[theImageData length]);
}
- (void)sendImage{
[[EPUploader alloc] initWithURL:[NSURL URLWithString:@"myurl.com/photoUploader.php"]
fileData:UIImageJPEGRepresentation(imageView.image,0.5)
delegate:self
doneSelector:@selector(onUploadDone:)
errorSelector:@selector(onUploadError:)];
}
EPUploader.m
#import "EPUploader.h"
#import <zlib.h>
static NSString * const BOUNDRY = @"0xKhTmLbOuNdArY";
static NSString * const FORM_FLE_INPUT = @"userfile";
#define ASSERT(x) NSAssert(x, @"NSASSERT ERROR")
@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
fileData: (NSData *)aFilePath // IN
delegate: (id)aDelegate // IN
doneSelector: (SEL)aDoneSelector // IN
errorSelector: (SEL)anErrorSelector // IN
{
if ((self = [super init])) {
NSLog(@"%@ databyte %d %@",aServerURL,[aFilePath length],aDelegate);
ASSERT(aServerURL);
ASSERT(aFilePath);
ASSERT(aDelegate);
ASSERT(aDoneSelector);
ASSERT(anErrorSelector);
serverURL = aServerURL;
fileData = aFilePath;
delegate = aDelegate;
doneSelector = aDoneSelector;
errorSelector = anErrorSelector;
[self upload];
}
return self;
}
/*
*-----------------------------------------------------------------------------
*
* -[Uploader dealloc] --
*
* Destructor.
*
* Results:
* None
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
- (void)dealloc
{
serverURL = nil;
fileData = nil;
delegate = nil;
doneSelector = NULL;
errorSelector = NULL;
}
/*
*-----------------------------------------------------------------------------
*
* -[Uploader filePath] --
*
* Gets the path of the file this object is uploading.
*
* Results:
* Path to the upload file.
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
- (NSData *)fileData
{
return fileData;
}
@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 = fileData;
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=\"001file.jpg\"\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);
[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]);
[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]
;
NSLog(@"%s: data: %s\n", __func__, [reply UTF8String]);
if ([reply hasPrefix:@"YES"]) {
uploadDidSucceed = YES;
}
}
@end