Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 相位集+;AFN网络上传多个视频_Ios_Objective C_Iphone_Afnetworking_Phasset - Fatal编程技术网

Ios 相位集+;AFN网络上传多个视频

Ios 相位集+;AFN网络上传多个视频,ios,objective-c,iphone,afnetworking,phasset,Ios,Objective C,Iphone,Afnetworking,Phasset,目前我正在使用以下代码上传视频: NSURLRequest *urlRequest = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:[[entity uploadUrl]absoluteString] parameters:entity.params constructingBodyWithBlock:^(id<AFMultipartFormData>

目前我正在使用以下代码上传视频:

  NSURLRequest *urlRequest =  [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:[[entity uploadUrl]absoluteString] parameters:entity.params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
    [UploadModel getAssetData:entity.asset resultHandler:^(NSData *filedata) {
          NSString *mimeType =[FileHelper mimeTypeForFileAtUrl:entity.fileUrl];
        //  NSError *fileappenderror;

        [formData appendPartWithFileData:filedata name:@"data" fileName: entity.filename mimeType:mimeType];

    }];

} error:&urlRequestError];
这种方法的问题在于,每当上传大型/多个视频文件时,应用程序的内存就会耗尽。我想这是由于请求NSDATA(aka
filedata
)上传文件(参见上面的方法)。我已尝试使用方法请求文件路径
appendPartWithFileURL
intead of
appendPartWithFileData
它在模拟器上工作。并在实际设备上失败,错误为无法按指定的路径读取文件。我已经在这里描述了这个问题

=======================================

更新:我修改了我的代码,以测试在新iPhone 6s+上通过本地路径上传文件的方法,如下所示

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

        NSString *mimeType =[FileHelper mimeTypeForFileAtUrl:entity.fileUrl];
        NSError *fileappenderror;

        [formData appendPartWithFileURL:entity.fileUrl name:@"data" fileName:entity.filename mimeType:mimeType error:&fileappenderror];

        if (fileappenderror) {
            [Sys MyLog:  [NSString stringWithFormat:@"Failed to  append: %@", [fileappenderror localizedDescription] ] ];
        }

    } error:&urlRequestError];
下面是用于从PHAsset获取本地文件路径的代码

if (mPhasset.mediaType == PHAssetMediaTypeImage) {

    PHContentEditingInputRequestOptions * options = [[PHContentEditingInputRequestOptions alloc]init];
    options.canHandleAdjustmentData = ^BOOL(PHAdjustmentData *adjustmeta){
        return YES;
    };

    [mPhasset requestContentEditingInputWithOptions:options completionHandler:^(PHContentEditingInput * _Nullable contentEditingInput, NSDictionary * _Nonnull info) {

        dataResponse(contentEditingInput.fullSizeImageURL);

    }];
}else if(mPhasset.mediaType == PHAssetMediaTypeVideo){
    PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
    options.version = PHVideoRequestOptionsVersionOriginal;

    [[PHImageManager defaultManager] requestAVAssetForVideo:mPhasset options:options resultHandler:^(AVAsset *asset, AVAudioMix *audioMix, NSDictionary *info) {
        if ([asset isKindOfClass:[AVURLAsset class]]) {
            NSURL *localVideoUrl = [(AVURLAsset *)asset URL];
            dataResponse(localVideoUrl);

        }



    }];
}

因此问题仍然是一样的-上传到服务器的文件是空的

为每个视频创建NSData可能是不好的,因为视频(或任何其他文件)可能比设备的RAM大得多, 我建议以“文件”而不是“数据”的形式上传,如果你附加文件,它会一块一块地从磁盘发送数据,不会试图一次读取整个文件,请尝试使用

- (BOOL)appendPartWithFileURL:(NSURL *)fileURL
                     name:(NSString *)name
                    error:(NSError * __autoreleasing *)error
也看看

在你的情况下,像这样使用它

  NSURLRequest *urlRequest =  [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:[[entity uploadUrl]absoluteString] parameters:entity.params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
  [formData appendPartWithFileURL:entity.fileUrl name:entity.filename error:&fileappenderror];
  if(fileappenderror) {
    NSLog(@"%@",fileappenderror);
  }
} error:&urlRequestError];
NSURLRequest*urlRequest=[[AFHTTPRequestSerializer]multipartFormRequestWithMethod:@“POST”URLString:[[entity uploadUrl]absoluteString]参数:entity.params constructingBodyWithBlock:^(id formData){
[formData appendPartWithFileURL:entity.fileUrl名称:entity.filename错误:&fileappenderror];
如果(fileappenderror){
NSLog(@“%@”,fileappenderror);
}
}错误:&urlRequestError];

以上建议的解决方案仅部分正确(之前我自己也发现过)。由于系统不允许读取沙盒之外的文件,因此文件路径无法访问(读/写)文件,只能复制。在iOS 9及以上版本中,Photos Framework提供API(无法通过NSFileManager完成,只能使用Photos Framework API)将文件复制到应用程序的沙盒目录中。这是我在挖掘文档和头文件后使用的代码

首先,将文件复制到app sandbox目录

// Assuming PHAsset has only one resource file. 
        PHAssetResource * resource = [[PHAssetResource assetResourcesForAsset:myPhasset] firstObject];

    +(void)writeResourceToTmp: (PHAssetResource*)resource pathCallback: (void(^)(NSURL*localUrl))pathCallback {
      // Get Asset Resource. Take first resource object. since it's only the one image.
        NSString *filename = resource.originalFilename;
        NSString *pathToWrite = [NSTemporaryDirectory() stringByAppendingString:filename];
        NSURL *localpath = [NSURL fileURLWithPath:pathToWrite];
        PHAssetResourceRequestOptions *options = [PHAssetResourceRequestOptions new];
        options.networkAccessAllowed = YES;
        [[PHAssetResourceManager defaultManager] writeDataForAssetResource:resource toFile:localpath options:options completionHandler:^(NSError * _Nullable error) {
            if (error) {
                [Sys MyLog: [NSString stringWithFormat:@"Failed to write a resource: %@",[error localizedDescription]]];
            }

            pathCallback(localpath);
        }];

   } // Write Resource into Tmp
上传任务本身

      NSURLRequest *urlRequest =  [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" 
            URLString:[[entity uploadUrl]absoluteString] parameters:entity.params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
         // Assuming PHAsset has only one resource file. 

        PHAssetResource * resource = [[PHAssetResource assetResourcesForAsset:myPhasset] firstObject];

        [FileHelper writeResourceToTmp:resource pathCallback:^(NSURL *localUrl)
               {
 [formData appendPartWithFileURL: localUrl name:@"data" fileName:entity.filename mimeType:mimeType error:&fileappenderror];

       }]; // writeResourceToTmp

    }// End Url Request

    AFHTTPRequestOperation * operation = [[AFHTTPRequestOperation alloc ] initWithRequest:urlRequest];
    //.....
    // Further steps are described in the AFNetworking Docs
NSURLRequest*urlRequest=[[AFHTTPRequestSerializer]multipartFormRequestWithMethod:@“POST”
URLString:[[entity uploadUrl]absoluteString]参数:entity.params constructingBodyWithBlock:^(id formData){
//假设PHAsset只有一个资源文件。
PHAssetResource*resource=[[PhasSetResourceAssetResourcesForasSet:myPhasset]firstObject];
[FileHelper writeResourceToTmp:资源路径回调:^(NSURL*localUrl)
{
[formData appendPartWithFileURL:localUrl名称:@“数据”文件名:entity.fileName mimeType:mimeType错误:&fileappenderror];
}];//writeResourceToTmp
}//结束Url请求
AFHTTPRequestOperation*operation=[[AFHTTPRequestOperation alloc]initWithRequest:urlRequest];
//.....
//进一步的步骤在AFD文档中描述
此上载方法有一个明显的缺点。如果设备进入“睡眠模式”,您将陷入困境。因此,这里推荐的上载方法是使用方法。
uploadTaskWithRequest:fromFile:progress:completionHandler
AFURLSessionManager中。

对于iOS 9以下的版本。如果是图像,您可以从
PHAsset
中获取
NSDATA
,如我的问题代码所示。然后将其上载。或者在上载之前先将其写入应用程序沙盒存储。对于大文件,此方法不可用。或者,您可能希望使用图像/视频选择器导出文件as
ALAsset
ALAsset
提供了api,允许您从存储中读取文件。但您必须在上载之前将其写入沙盒存储。

请参阅我对您的其他问题的回答。由于主题已链接,因此此处似乎相关

在这个回答中,我描述了根据我的经验,苹果公司不允许我们直接访问与PHAsset或ALAsset相关的视频源文件

为了访问视频文件并上传它们,您必须首先使用.或使用iOS9+API创建副本

您不应该使用任何将数据加载到内存中的方法,因为这样会很快遇到OOM异常。而且,使用上面所述的
requestAVAssetForVideo(u2;:options:resultHandler:)
方法可能不是一个好主意,因为您有时会得到AVComposition而不是AVAsset(而且您无法直接从AVComposition获得NSURL)

您可能也不想使用任何利用
AFHTTPRequestOperation
或相关API的上载方法,因为它们基于不推荐的NSURLConnection API,而不是更现代的API。NSURLSession将允许您在后台进程中进行长时间运行的视频上载,允许您的用户离开app并确信上传将无论如何完成


在我最初的回答中,我提到了。它是一个处理视频文件上传到Vimeo的库,但它的核心可以重新调整用途,以处理并发的背景视频文件上传到任何目的地。完全披露:我是该库的作者之一。

您是在主线程中上传还是创建了一个单独的线程?@Muzammil Hi。它是在n主线程..因为它是通过第三方库完成的。我不确定这是否重要。感谢您的输入:)我们如何发送实时照片和slo运动视频。这些是2个或更多文件的组合。所以它们有多个文件url,嗨。正如我在问题中所述。我无法通过本地文件url完成(在相位设置的情况下)在装置上。b
// Assuming PHAsset has only one resource file. 
        PHAssetResource * resource = [[PHAssetResource assetResourcesForAsset:myPhasset] firstObject];

    +(void)writeResourceToTmp: (PHAssetResource*)resource pathCallback: (void(^)(NSURL*localUrl))pathCallback {
      // Get Asset Resource. Take first resource object. since it's only the one image.
        NSString *filename = resource.originalFilename;
        NSString *pathToWrite = [NSTemporaryDirectory() stringByAppendingString:filename];
        NSURL *localpath = [NSURL fileURLWithPath:pathToWrite];
        PHAssetResourceRequestOptions *options = [PHAssetResourceRequestOptions new];
        options.networkAccessAllowed = YES;
        [[PHAssetResourceManager defaultManager] writeDataForAssetResource:resource toFile:localpath options:options completionHandler:^(NSError * _Nullable error) {
            if (error) {
                [Sys MyLog: [NSString stringWithFormat:@"Failed to write a resource: %@",[error localizedDescription]]];
            }

            pathCallback(localpath);
        }];

   } // Write Resource into Tmp
      NSURLRequest *urlRequest =  [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" 
            URLString:[[entity uploadUrl]absoluteString] parameters:entity.params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
         // Assuming PHAsset has only one resource file. 

        PHAssetResource * resource = [[PHAssetResource assetResourcesForAsset:myPhasset] firstObject];

        [FileHelper writeResourceToTmp:resource pathCallback:^(NSURL *localUrl)
               {
 [formData appendPartWithFileURL: localUrl name:@"data" fileName:entity.filename mimeType:mimeType error:&fileappenderror];

       }]; // writeResourceToTmp

    }// End Url Request

    AFHTTPRequestOperation * operation = [[AFHTTPRequestOperation alloc ] initWithRequest:urlRequest];
    //.....
    // Further steps are described in the AFNetworking Docs