xcode — загрузка изображения с параметрами формы на веб-сервер

#xcode #http-post #multipartform-data #nsmutableurlrequest

#xcode — код #http-сообщение #составная форма-данные #nsmutableurlrequest запрос

Вопрос:

Я пытаюсь загрузить изображение с 3 параметрами из формы на веб-сервер, но безуспешно.

Мой код таков:

 -(IBAction)uploadPhoto:(id)sender{


        NSString *urlString = @"https://urlwebservice";
        NSURL *url = [NSURL URLWithString:urlString];

        NSString *serverName = @"user";
        NSString *serverPassword = @"password";

        // create a plaintext string in the format username:password
        NSString *authStr = [NSString stringWithFormat:@"%@:%@", serverName, serverPassword];

        NSData *authData = [authStr dataUsingEncoding:NSUTF8StringEncoding];
        NSString *authValue = [NSString stringWithFormat:@"Basic %@", [Base64 encode:authData ]];

        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL: url
                                                               cachePolicy: NSURLRequestUseProtocolCachePolicy
                                                           timeoutInterval: 10];
        [request setHTTPMethod:@"POST"];
        [request setValue:authValue  forHTTPHeaderField:@"Authorization"];


        // body
        NSMutableData *postBody = [NSMutableData data];
        NSString *stringBoundary = @"0xKhTmLbOuNdArY---This_Is_ThE_BoUnDaRyy---pqo";
        NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",stringBoundary];
        [request addValue:contentType forHTTPHeaderField: @"Content-Type"];

        //image
        [postBody appendData:[[NSString stringWithFormat:@"--%@rn", stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [postBody appendData:[@"Content-Disposition: form-data; name="file"; filename="item.jpg"rn" dataUsingEncoding:NSUTF8StringEncoding]];
        [postBody appendData:[@"Content-Type: image/jpgrn" dataUsingEncoding:NSUTF8StringEncoding]];
        [postBody appendData:[@"Content-Transfer-Encoding: binaryrnrn" dataUsingEncoding:NSUTF8StringEncoding]];

        // get the image data from main bundle directly into NSData object
        NSData *imgData = UIImageJPEGRepresentation(photo, 0.2);
        // add it to body
        [postBody appendData:imgData];
        [postBody appendData:[@"rn" dataUsingEncoding:NSUTF8StringEncoding]];
        NSLog(@"message added");
        // final boundary
        [postBody appendData:[[NSString stringWithFormat:@"--%@--rn", stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];

        //PARAMETERS body
        NSString *nombre = @"parameter_name" ;
        NSString *valoracion = @"2";
        NSString *precio = @"12" ;

        //nombre
        [postBody appendData:[[NSString stringWithFormat:@"--%@rn", stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [postBody appendData:[@"Content-Disposition: form-data; name="nombre"rnrn" dataUsingEncoding:NSUTF8StringEncoding]];
        [postBody appendData:[nombre dataUsingEncoding:NSUTF8StringEncoding]];
        [postBody appendData:[@"rn" dataUsingEncoding:NSUTF8StringEncoding]];

        //VAL
        [postBody appendData:[[NSString stringWithFormat:@"--%@rn", stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [postBody appendData:[@"Content-Disposition: form-data; name="nombre"rnrn" dataUsingEncoding:NSUTF8StringEncoding]];
        [postBody appendData:[valoracion dataUsingEncoding:NSUTF8StringEncoding]];
        [postBody appendData:[@"rn" dataUsingEncoding:NSUTF8StringEncoding]];

        //PRECIO
        [postBody appendData:[[NSString stringWithFormat:@"--%@rn", stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [postBody appendData:[@"Content-Disposition: form-data; name="nombre"rnrn" dataUsingEncoding:NSUTF8StringEncoding]];
        [postBody appendData:[precio dataUsingEncoding:NSUTF8StringEncoding]];
        [postBody appendData:[@"rn" dataUsingEncoding:NSUTF8StringEncoding]];


        // setting the body of the post to the request
        [request setHTTPBody:postBody];

        NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
        NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
        NSLog(@"RETURN from  method:   %@",returnString);


}
 

Эквивалентный java-клиентский метод с успешным ответом является:

   try {
                FormDataMultiPart form = new FormDataMultiPart().field("file", new File("c:\1943.jpg"), MediaType.MULTIPART_FORM_DATA_TYPE)
                        .field("nombre", "parameter_name")
                        .field("valoracion", "4")
                        .field("precio", "13,45 €")


                WebResource webResource = Client.create().resource("https://webservice");
                webResource.header("Authorization", "Basic "   Base64.encodeBase64String(StringUtils.getBytesUtf8("user:password")));
                webResource.type(MediaType.MULTIPART_FORM_DATA)
                           .accept(MediaType.TEXT_PLAIN)
                           .post(form);

            }
 

Кто-нибудь знает, в чем может быть моя ошибка в коде objective-c?

Заранее спасибо

Ответ №1:

На первый взгляд я вижу: вы не отправляете «Длину содержимого» данных Post.

Это мой рабочий код для отправки изображения с параметрами на сервер:

 NSMutableURLRequest *myPost = [NSMutableURLRequest requestWithURL:myUrl];
[myPost setHTTPMethod:@"POST"];

NSString *stringBoundary = @"0xKhTmLbOuNdArY";
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",stringBoundary];
[myPost addValue:contentType forHTTPHeaderField: @"Content-Type"];

NSMutableData *postBody = [NSMutableData data];
[postBody appendData:[[NSString stringWithFormat:@"--%@rn",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];


for (NSString * key in postDict) {
    [postBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name="%@"rnrn",[key dataUsingEncoding:NSUTF8StringEncoding]] dataUsingEncoding:NSUTF8StringEncoding]];
    [postBody appendData:[postDict[key] dataUsingEncoding:NSUTF8StringEncoding]];
    [postBody appendData:[[NSString stringWithFormat:@"rn--%@rn",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
}
if(imageData!=nil){
    [postBody appendData:[@"Content-Disposition: form-data; name="AVATAR_FILE"; filename="test.png"rn" dataUsingEncoding:NSUTF8StringEncoding]];
    [postBody appendData:[@"Content-Type: application/octet-streamrnrn" dataUsingEncoding:NSUTF8StringEncoding]];
    [postBody appendData:imageData];
    [postBody appendData:[[NSString stringWithFormat:@"rn--%@--rn",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
}
[myPost setHTTPBody:postBody];
NSString *tmp = [NSString stringWithFormat:@"%d",[postBody length]];
[myPost setValue:tmp forHTTPHeaderField:@"Content-Length"];
[[NSURLConnection alloc] initWithRequest:myPost delegate:self];
 

Но я рекомендую воспользоваться библиотекой https://github.com/AFNetworking/AFNetworking — это намного проще и удобнее