2013-11-17 2 views
2

У меня возникли проблемы с получением некоторого кода, который я приобрел, мой опыт работы с php/html в лучшем случае ограничен, поэтому я надеюсь, что не слишком много нуба, спрашивая об этом.Загрузка изображения на веб-сервер с помощью xcode и php

Проблема, с которой я сталкиваюсь, не может загрузить небольшое изображение на веб-сервер. Я играл со следующим за последние 4-5 часов, это почти 2 утра здесь, в Великобритании и единственный прогресс я сделал было изменение

[NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary]; 

в

[NSString stringWithFormat:@"enctype=\"multipart/form-data\"; boundary=%@",boundary]; 

Это получает мой Сервер, чтобы перестать давать внутреннюю ошибку каждый раз, когда я что-то посылаю.

код ниже, он находится на нескольких страницах этого сайта, и я не могу найти оригинального автора, чтобы отдать кредит. В настоящее время я получаю пустой массив, когда у меня есть print_r($_FILES); в принимающем php-файле.

Любая помощь, которая когда-либо была бы оценена по весу, заблаговременно.

NSString *urlString = @"http://mysite/upload_image.php"; 

UIImage * img = [UIImage imageNamed:@"mypic.png"]; 
NSData *imageData = UIImageJPEGRepresentation(img, 90); 

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init] ; 
[request setURL:[NSURL URLWithString:urlString]]; 
[request setHTTPMethod:@"POST"]; 

NSString *boundary = @"---------------------------14737809831466499882746641449"; 
NSString *contentType = [NSString stringWithFormat:@"enctype=\"multipart/form-data\"; boundary=%@",boundary]; 
[request addValue:contentType forHTTPHeaderField: @"Content-Type"]; 


NSMutableData *body = [NSMutableData data]; 
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]]; 
[body appendData:[@"Content-Disposition: attachment; name=\"image\"; filename=\"davesfile.jpg\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; 
[body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; 
[body appendData:[NSData dataWithData:imageData]]; 
[body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]]; 
[request setHTTPBody:body]; 

NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; 
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding]; 

NSLog(@"%@",returnString); 

ответ

7

Пар реакции:

  1. Если вы используете AFNetworking, процесс создания такого рода запросы проще, получить вас из сорняков построения данной просьбе себя:

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 
    manager.responseSerializer = [AFHTTPResponseSerializer serializer]; 
    [manager POST:[url absoluteString] parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) { 
        [formData appendPartWithFileData:imageData name:fieldName fileName:[imagePath lastPathComponent] mimeType:[self mimeTypeForPath:imagePath]]; 
    } success:^(AFHTTPRequestOperation *operation, id responseObject) { 
        NSString *string = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]; 
        NSLog(@"Success: %@", string); 
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
        NSLog(@"Error: %@", error); 
    }]; 
    
  2. Кстати, я обычно использую MobileCoreServices.framework для получения типа mime на основе расширения, а не жесткого его кодирования:

    - (NSString *)mimeTypeForPath:(NSString *)path 
    { 
        // get a mime type for an extension using MobileCoreServices.framework 
    
        CFStringRef extension = (__bridge CFStringRef)[path pathExtension]; 
        CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, extension, NULL); 
        assert(UTI != NULL); 
    
        NSString *mimetype = CFBridgingRelease(UTTypeCopyPreferredTagWithClass(UTI, kUTTagClassMIMEType)); 
        assert(mimetype != NULL); 
    
        CFRelease(UTI); 
    
        return mimetype; 
    } 
    
  3. Я заметил, что вы извлечения изображения в UIImage, а затем с помощью UIImageJPEGRepresentation получить NSData. Сделайте это, если хотите или хотите, но я обычно предпочитаю отправлять необработанные данные, непосредственно минуя обратный путь через UIImage, что может привести к деградации изображения и потере метаданных. Вместо этого, вы можете захотеть, чтобы захватить NSData непосредственно:

    NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"mypic" ofType:@"png"]; // note, I'm going back to bundle, not grabbing `UIImage` from imageview 
    NSData *imageData = [NSData dataWithContentsOfFile:imagePath]; 
    

    Если вы действительно должны сделать туда и обратно через UIImage, то вы можете использовать imageWithContentsOfFile вместо imageNamed, так как последний будет кэшировать изображения без необходимости.

  4. Если вы решили создать запрос самостоятельно, это рутина, которую я использовал в прошлом:

    - (void)uploadFileAtPath:(NSString *)imagePath 
           forField:(NSString *)fieldName 
            URL:(NSURL*)url 
           parameters:(NSDictionary *)parameters 
    { 
        NSString *filename = [imagePath lastPathComponent]; 
        NSData *imageData = [NSData dataWithContentsOfFile:imagePath]; 
    
        NSMutableData *httpBody = [NSMutableData data]; 
        NSString *boundary = [self generateBoundaryString]; 
        NSString *mimetype = [self mimeTypeForPath:imagePath]; 
    
        // configure the request 
    
        NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url]; 
        [request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData]; 
        [request setHTTPShouldHandleCookies:NO]; 
        [request setTimeoutInterval:30]; 
        [request setHTTPMethod:@"POST"]; 
    
        // set content type 
    
        NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary]; 
        [request setValue:contentType forHTTPHeaderField: @"Content-Type"]; 
    
        // add params (all params are strings) 
    
        [parameters enumerateKeysAndObjectsUsingBlock:^(NSString *parameterKey, NSString *parameterValue, BOOL *stop) { 
         [httpBody appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; 
         [httpBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", parameterKey] dataUsingEncoding:NSUTF8StringEncoding]]; 
         [httpBody appendData:[[NSString stringWithFormat:@"%@\r\n", parameterValue] dataUsingEncoding:NSUTF8StringEncoding]]; 
        }]; 
    
        // add image data 
    
        if (imageData) { 
         [httpBody appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; 
         [httpBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", fieldName, filename] dataUsingEncoding:NSUTF8StringEncoding]]; 
         [httpBody appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", mimetype] dataUsingEncoding:NSUTF8StringEncoding]]; 
         [httpBody appendData:imageData]; 
         [httpBody appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; 
        } 
    
        [httpBody appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; 
    
        // setting the body of the post to the reqeust 
    
        [request setHTTPBody:httpBody]; 
    
        [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 
         if (connectionError) 
         { 
          NSLog(@"sendAsynchronousRequest error=%@", connectionError); 
          return; 
         } 
    
         NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
         NSLog(@"Success: %@", string); 
        }]; 
    } 
    

    Очевидно, что если вы не используете parameters (которые вы дон Кажется, что-то не получается), вы можете просто передать nil для этого параметра. Но ключ в том, что он поддерживает дополнительные параметры, если вам это нужно. Я также использую асинхронные сетевые запросы, потому что никогда не следует выдавать синхронные сетевые запросы в основной очереди.

    При этом используется метод generateBoundaryString из примера SimpleURLConnections от Apple:

    - (NSString *)generateBoundaryString 
    { 
        // generate boundary string 
        // 
        // adapted from http://developer.apple.com/library/ios/#samplecode/SimpleURLConnections 
        // 
        // Note in iOS 6 and later, you can just: 
        // 
        // return [NSString stringWithFormat:@"Boundary-%@", [[NSUUID UUID] UUIDString]]; 
    
        CFUUIDRef uuid; 
        NSString *uuidStr; 
    
        uuid = CFUUIDCreate(NULL); 
        assert(uuid != NULL); 
    
        uuidStr = CFBridgingRelease(CFUUIDCreateString(NULL, uuid)); 
        assert(uuidStr != NULL); 
    
        CFRelease(uuid); 
    
        return [NSString stringWithFormat:@"Boundary-%@", uuidStr]; 
    } 
    
  5. Если вы хотите, я модернизирован код, смоделированный на некоторых из кода выше:

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url]; 
    [request setHTTPMethod:@"POST"]; 
    
    NSString *boundary = @"---------------------------14737809831466499882746641449"; 
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary]; 
    [request addValue:contentType forHTTPHeaderField: @"Content-Type"]; 
    
    NSMutableData *body = [NSMutableData data]; 
    [body appendData:[[NSString stringWithFormat:@"--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]]; 
    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", fieldName, [imagePath lastPathComponent]] dataUsingEncoding:NSUTF8StringEncoding]]; 
    [body appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", [self mimeTypeForPath:imagePath]] dataUsingEncoding:NSUTF8StringEncoding]]; 
    [body appendData:[NSData dataWithData:imageData]]; 
    [body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]]; 
    [request setHTTPBody:body]; 
    
    NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; 
    NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding]; 
    
    NSLog(@"%@",returnString); 
    
  6. Лично я 'Предлагайте изменить свой PHP-код для генерации ответа JSON (так как это будет проще для вашего приложения).

Кстати, я протестировал выше с моим PHP-кодом. Если у вас все еще есть проблемы, я бы предложил поделиться с вами и PHP-кодом, поскольку построение хорошо сформированного запроса тесно связано с тем, что требует PHP-код.

+1

Вы понятия не имеете, какая именно помощь. Большое вам спасибо за быстрый и всеобъемлющий ответ. Несколько моментов, касающихся ваших комментариев; 1. Я никогда не использовал AFNetworking, приложение, которое я разрабатываю, в основном запускает json-данные на сервер и с сервера, и до сих пор это было довольно просто, его только сейчас, когда изображение связано с тем, что я застрял, я буду конечно, посмотрите, когда проект закончился. 2. Спасибо за подсказку по типу MIME, я буду использовать это в будущем –

+1

3. Не беспокойтесь о асинхронной стороне вещей, одна из моих самых больших ненависти - это невосприимчивые приложения, поэтому я всегда их использую, я буду Положите это, как только вещь будет работать, КОТОРАЯ НЕТ! Спасибо Еще раз, если бы я был где-то рядом с Нью-Йорком, я бы купил тебе выпить :) –

+2

@Rob, отличный ответ. Только то, что я искал. – manderson

Смежные вопросы