PHAsset + AFNetworking.无法将文件上传到真实设备上的服务器

Pro*_*ver 2 iphone objective-c ios afnetworking phasset

目前我正在使用以下代码将文件上传到服务器

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];
Run Code Online (Sandbox Code Playgroud)

/*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"]);

    }];
}
Run Code Online (Sandbox Code Playgroud)

这种方法适用于模拟器,但在真实设备上失败:空文件很可能由于无法从本地存储读取而上载到服务器.日志显示通知

注意:Sandbox:MyApp(213)拒绝文件读取数据/private/var/mobile/Media/DCIM/101APPLE/IMG_1570.PNG

我相信这个笔记意味着app无法通过指定的路径访问该文件.此外,我尝试了一种替代方法,通过附加NSData来上传文件,NSData是从请求PHAsset数据返回的.但是这种方法在大型媒体文件的情况下是不可用的.因为整个文件都被加载到内存中.

有什么想法吗?

Alf*_*sen 5

您不应该使用requestImageDataForAsset(_:options:resultHandler:)大文件.原因是你不想将整个媒体文件加载到内存中,你将很快耗尽内存,应用程序将崩溃.这通常意味着您不应将其用于大型图像或几乎任何视频.

根据我的经验,尝试直接从PHAsset资源URL上传将失败.Apple似乎没有授予我们从PHAsset源文件直接上传所需的权限.在这里查看论坛帖子.这是一种痛苦,因为如果我们想要上传视频,它会迫使我们使用大量的额外磁盘空间.

要获取您要上传的视频文件的本地文件网址,您需要使用以下任一方法:

requestExportSessionForVideo(_:options:exportPreset:resultHandler:)

要么

requestAVAssetForVideo(_:options:resultHandler:)

您将使用这些方法将视频文件的副本导出到您控制的磁盘上的位置.并从该文件上传.奖励功能:如有必要,这两种方法都将从iCloud下载文件.

查看VimeoUpload库,了解有关视频上传的所有内容的详细信息.免责声明:我是图书馆的作者之一.

即使您没有上传到Vimeo服务器,也可以使用VimeoUpload中包含的PHAssetExportSessionOperationExportOperation类来完成您想要做的事情.有关获取PHAsset的文件URL的详细信息,请参阅repo README .它还包括用于获取ALAsset的文件URL的工具.

如果您对使用PHAssetExportSessionOperation或不感兴趣ExportOperation,请查看他们的实现,了解如何使用Apple类的详细信息.