我尝试使用以下代码发布带有数据的图片。数据正在上传,但图片未上传。
-(void)imageUpload
{
name=@"Har9233";
userId=@"2969";
cityId=@"1";
mobile=@"9888329329";
mobileVerify=@"no ";
gender=@"1";
//NSString *imageData=@"12";
NSData *imageData = UIImageJPEGRepresentation(imageView.image, 1.0);
NSMutableDictionary* _params = [[NSMutableDictionary alloc] init];
[_params setObject:userId forKey:@"userId"];
[_params setObject:name forKey:@"profileDisplayName"];
[_params setObject:gender forKey:@"gender"];
[_params setObject:cityId forKey:@"cityId"];
[_params setObject:mobile forKey:@"mobile"];
[_params setObject:mobileVerify forKey:@"isMobileVerified"];
NSString *boundary = @"ghkyre–nhjfhdj-74f5f-gfg5-gggff";
NSString* FileParamConstant =@"image";
//
NSURL* requestURL = [NSURL URLWithString:@"myurl"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[request setHTTPShouldHandleCookies:NO];
[request setTimeoutInterval:30];
[request setHTTPMethod:@"POST"];
// set Content-Type in HTTP header
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
[request setValue:contentType forHTTPHeaderField: @"Content-Type"];
// post body
NSMutableData *body = [NSMutableData data];
// add params (all params are strings)
for (NSString *param in _params) {
[body appendData:[[NSString stringWithFormat:@"--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", param] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"%@\r\n", [_params objectForKey:param]] dataUsingEncoding:NSUTF8StringEncoding]];
}
// add image data
if (imageData)
{
NSLog(@"2");
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"harryimg1.png\"\r\n",FileParamConstant] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Type: image/jpeg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:imageData]];
[body appendData:[[NSString stringWithFormat:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
}
// [body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
// setting the body of the post to the reqeust
[request setHTTPBody:body];
// set the content-length
NSString *postLength = [NSString stringWithFormat:@"%d", [body length]];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
// set URL
[request setURL:requestURL];
NSURLResponse *response;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:Nil];
NSDictionary *jsonResponseData = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:nil];
NSLog(@"DATA=%@",jsonResponseData);
}
答案 0 :(得分:-1)
我遇到了同样的问题,并且使用的代码与您的代码非常相似。试试这个,它确实有效,这就是我正在使用的:
- (NSString *)randomStringWithLength:(int)length
{
NSString *letters = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
NSMutableString *randomString = [NSMutableString stringWithCapacity:length];
for (int i = 0; i < length; i++) {
[randomString appendFormat: @"%C", [letters characterAtIndex: arc4random() % [letters length]]];
}
return randomString;
}
-(BOOL)uploadImageFile:(NSString *)filename
{
NSMutableURLRequest *request= [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:@"yourUrl"]];
[request setHTTPMethod:@"PUT"];
NSString *boundary = [self randomStringWithLength:14];
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
[request addValue:contentType forHTTPHeaderField: @"Content-Type"];
NSMutableData *postbody = [NSMutableData data];
NSData *data = [NSData dataWithContentsOfFile:filename];
[postbody appendData:[NSData dataWithData:data]];
[request setHTTPBody:postbody];
NSURLResponse *urlResponse = nil;
NSError *requestError = nil;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&requestError];
if (((NSHTTPURLResponse *)urlResponse).statusCode != 201) {
NSLog(@"Unable to upload file: %@, response data: %@, response code: %i, request error: %@", [filename lastPathComponent], [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding], ((NSHTTPURLResponse *)urlResponse).statusCode, requestError);
return NO;
}
NSLog(@"Uploading File Successful");
return YES;
}
答案 1 :(得分:-3)
为了更准确地呈现我的评论:
您的代码看起来几乎正确,但有一些问题:
首先,“边界定界符”必须以CRLF开头。而且,从概念上讲,这个前面的CRLF属于“边界定界符。
其次,参数的“Content-Type”标题不会受到影响。
因此,我建议从
更改以下内容// add params (all params are strings)
for (NSString *param in _params) {
[body appendData:[[NSString stringWithFormat:@"--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", param] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"%@\r\n", [_params objectForKey:param]] dataUsingEncoding:NSUTF8StringEncoding]];
}
到
// add params (all params are strings)
for (NSString *param in _params) {
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n", param] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendBytes:"Content-Type: text/plain; charset=utf-8\r\n" length:41];
// (other headers if any)
// close headers with CRLF:
[body appendBytes:"\r\n" length:2];
// param value:
[body appendData:[[NSString stringWithFormat:@"%@", [_params objectForKey:param]] dataUsingEncoding:NSUTF8StringEncoding]];
}
第四,你不应该将CRLF附加到二进制数据! 当输出包含二进制数据的部分时,请按照以上几行进行操作:如您所见,在将参数值写入正文部分后没有关闭CRLF。
因此:
if (imageData)
{
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"harryimg1.png\"\r\n",FileParamConstant] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Type: image/jpeg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:imageData]];
}
此外,您省略了“close-boundary-delimiter:
”在最后一部分之后,添加以下内容:
[body appendData:[[NSString stringWithFormat:@"\r\n--%@--", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
不需要最后一个CRLF,但也不会受到伤害。
补充说明:
在发送大数据时,不建议使用NSURLConnection
方便的类方法sendSynchronousRequest:您最好实现NSURLConnection委托,它允许您在出现问题时取消请求,并提供更多控制。
此外,此方法使用NSData
作为multipart / form-data消息的请求主体。这要求while体必须适合记忆。这可能会导致内存问题。一种更健壮的方法会将输入流用作请求体,但这种实现要复杂得多(实际上要多得多)。
iOS 7有一个新的API,它应该更容易传输大文件。请参阅NSURLSession
和NSURLSessionUploadTask
的文档。