Загрузка файла с помощью NSURLSessionUploadTask на сервер PHP

У меня есть система загрузки видео в приложении для iOS, использующая NSURLSessionUploadTask. Видеофайл сохраняется в NSURL, поэтому я использую следующий код в моем методе загрузки:

request.HTTPMethod = @"POST";
[request addValue:@"file" forHTTPHeaderField:@"fileName"];

// Create upload task
NSURLSessionUploadTask *task = [session uploadTaskWithRequest:request fromFile:filePath completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    if(!error) {
        // handle success
    } else {
        // handle error
    }
}];

// Run the task
[task resume];

У меня есть PHP-сервер (использующий Laravel), работающий под nginx для обработки этой загрузки. Я тестировал его с помощью Postman, и он отлично принимает загрузки (ожидая файла под именем «файл»).

Когда я запускаю указанный выше код objc, сервер сообщает мне, что файл не загружен (массив $_FILES пуст).

Я пробовал с установкой заголовка «fileName» и без него, и я пробовал установить «Content-Type» на «multipart / form-data», но ничего из этого не работает.

Как я могу заставить NSURLSessionUploadTask правильно загружать эти файлы (с NSURL) на сервер?

В этом сообщении описывается аналогичная проблема: NSURLSessionUploadTask не передает файл в скрипт php


person GTF    schedule 30.09.2014    source источник
comment
Что в твоем файле? Имейте в виду, что PHP будет ожидать, что тело будет выглядеть как загрузка файла на основе формы, а uploadTaskWithRequest не делает ничего умного - я думаю, он просто отправляет ваш файл в виде основных данных.   -  person Matt Gibson    schedule 01.10.2014
comment
Решил это (вроде), просто используя AFNetworking, и обошел проблемы с аутентификацией, написав заголовки аутентификации вручную (кодировка base64 и т. Д.).   -  person GTF    schedule 02.10.2014


Ответы (1)


При использовании NSURLSessionUploadTask [uploadTaskWithRequest: fromFile:] файл отправляется в теле запроса как двоичный.

Чтобы сохранить этот файл в PHP, вы можете просто получить тело запроса и сохранить его в файл.

Очевидно, что лучше всего выполнить какую-то проверку формата файла.

Код цели-C:

// Define the Paths
NSURL *URL = [NSURL URLWithString:kDestinationURL];

// Create the Request
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:URL];
[request setHTTPMethod:@"POST"];

// Configure the NSURL Session
NSURLSessionConfiguration *config = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.upload"];
config.HTTPMaximumConnectionsPerHost = 1;
NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];

// Define the Upload task
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromFile:audioRecorder.url];

// Run it!
[uploadTask resume];

Код PHP:

<?php
    // File Path to save file
    $file = 'uploads/recording.m4v';

    // Get the Request body
    $request_body = @file_get_contents('php://input');

    // Get some information on the file
    $file_info = new finfo(FILEINFO_MIME);

    // Extract the mime type
    $mime_type = $file_info->buffer($request_body);

    // Logic to deal with the type returned
    switch($mime_type) 
    {
        case "video/mp4; charset=binary":

            // Write the request body to file
            file_put_contents($file, $request_body);

            break;

        default:
            // Handle wrong file type here
    }
?>

Я написал пример кода записи звука и загрузки его на сервер здесь: https://github.com/gingofthesouth/Audio-Recording-Playback-and-Upload

Надеюсь, это поможет.

person Ernest Cunningham    schedule 02.02.2015
comment
Я нашел способ обойти это, используя AFNetworking, поэтому не могу это проверить, но запомню для будущих справок, спасибо. - person GTF; 02.02.2015
comment
можем ли мы опубликовать параметр также в этом? потому что я пытаюсь опубликовать, но не добился успеха - person Mukesh; 30.06.2015