PHAsset + AFNetworking. Невозможно загрузить файлы на сервер на реальном устройстве

В настоящее время я использую следующий код для загрузки файлов на сервер

NSURLRequest *urlRequest =  [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:[[entity uploadUrl]absoluteString] parameters:entity.params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {

    // Get file url 
    [UploadModel getAassetUrl:entity.asset resultHandler:^(NSURL *fileUrl) {

    NSError *fileappenderror;
    // Append
                [formData appendPartWithFileURL:fileUrl name:@"data" error:&fileappenderror];

                if (fileappenderror) {
                  [Sys MyLog: [fileappenderror localizedDescription] ];
                }
            }];

        } error:&urlRequestError];

/ * getAassetUrl * /

+(void)getAassetUrl: (PHAsset*)mPhasset resultHandler:(void(^)(NSURL *imageUrl))dataResponse{

    PHImageRequestOptions * requestOption = [[PHImageRequestOptions alloc] init];
    requestOption.synchronous = YES;
    requestOption.deliveryMode = PHImageRequestOptionsDeliveryModeFastFormat;

        [[PHImageManager defaultManager] requestImageDataForAsset:mPhasset options:requestOption resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {

        dataResponse([info objectForKey:@"PHImageFileURLKey"]);

    }];
}

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

Примечание: песочница: MyApp (213) deny file-read-data /private/var/mobile/Media/DCIM/101APPLE/IMG_1570.PNG

Я считаю, что это примечание означает, что приложение не может получить доступ к файлу по указанному пути. Также я попробовал альтернативный подход к загрузке файла, добавив NSData, который возвращается из данных запроса PHAsset. но этот подход неприменим в случае больших медиафайлов. поскольку весь файл загружается в память.

Есть предположения?


person ProblemSlover    schedule 06.10.2015    source источник


Ответы (2)


Объект NSData, возвращаемый requestImageDataForAsset, отображается в памяти, поэтому весь файл не загружается в память. Таким образом, этот метод будет без проблем с изображениями.

Для видео вы должны использовать соответствующие методы requestExportSessionForVideo или requestAVAssetForVideo. Если вы можете ограничить цель развертывания iOS 9, вам также следует взглянуть на методы PHAssetResourceManager

person holtmann    schedule 06.10.2015

Не используйте requestImageDataForAsset(_:options:resultHandler:) для больших файлов. Причина в том, что вы не хотите загружать весь медиафайл в память, у вас быстро закончится память, и приложение выйдет из строя. Обычно это означает, что вы не должны использовать его для больших изображений или практически любого видео.

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

Чтобы получить URL-адрес локального файла для видеофайла, который вы собираетесь загрузить, вы захотите использовать либо:

requestExportSessionForVideo(_:options:exportPreset:resultHandler:)

or

requestAVAssetForVideo(_:options:resultHandler:)

Вы будете использовать эти методы для экспорта копии видеофайла в место на диске, которое вы контролируете. И загрузите из этого файла. Бонусная функция: оба этих метода при необходимости загрузят файл из iCloud.

Ознакомьтесь с библиотекой VimeoUpload для получения подробной информации обо всем, что связано с загрузкой видео. Отказ от ответственности: я один из авторов библиотеки.

Даже если вы не загружаете на серверы Vimeo, вы можете использовать классы PHAssetExportSessionOperation и ExportOperation, включенные в VimeoUpload, чтобы делайте именно то, что вы хотите делать. См. README репозитория для получения подробной информации о о получении URL-адреса файла для PHAsset. Он также включает инструменты для получения URL-адреса файла для ALAsset < / а>.

Если вас не интересует использование PHAssetExportSessionOperation или ExportOperation, ознакомьтесь с их реализациями, чтобы узнать, как использовать классы Apple под капотом.

person Alfie Hanssen    schedule 16.03.2016