图像发布到服务器与数据json不工作ios

时间:2013-10-07 10:30:51

标签: iphone ios xcode

我尝试使用以下代码发布带有数据的图片。数据正在上传,但图片未上传。

-(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);

}

2 个答案:

答案 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,它应该更容易传输大文件。请参阅NSURLSessionNSURLSessionUploadTask的文档。