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) запрещает чтение данных файла /private/var/mobile/Media/DCIM/101APPLE/IMG_1570.PNG

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

Какие-нибудь мысли?

2 ответа

Решение

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

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

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

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

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

requestExportSessionForVideo(_:options:exportPreset:resultHandler:)

или же

requestAVAssetForVideo(_:options:resultHandler:)

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

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

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

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

Другие вопросы по тегам