使用 AFNetworking 上传视频会导致内存问题

Uploading video using AFNetworking causes memory issue

我知道以前有人问过这个问题,但我无法从那些帖子中找出正确的方法。所以这是我上传导致内存问题的视频文件的代码:

    AFHTTPSessionManager *operationManager = [AFHTTPSessionManager manager];
    operationManager.responseSerializer=[AFJSONResponseSerializer serializer];
    operationManager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];
    //[operationManager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [operationManager.operationQueue cancelAllOperations];
    if([requestName isEqualToString:addComment_Url] && [dict valueForKey:@"image_Data"] != nil && [dict valueForKey:@"mime_type"] != nil){
    }


    [operationManager.requestSerializer setValue:authValue forHTTPHeaderField:@"Authorization"];
    [operationManager POST:url parameters:dict constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {

        SAAppDelegate *appDelegate = [SAAppDelegate getDelegate];

        if([requestName isEqualToString:addComment_Url] && appDelegate.imageData !=nil){

           // [formData appendPartWithFormData:self.imageData name:@"myFile"];
            [formData appendPartWithFileData:appDelegate.imageData name:@"myFile" fileName:appDelegate.fileName mimeType:appDelegate.mime];
        }

        if([requestName isEqualToString:addNewPost_Url] && appDelegate.imageData !=nil){
            [formData appendPartWithFileData:appDelegate.imageData name:@"myFile" fileName:appDelegate.fileName mimeType:appDelegate.mime];
        }

        if([requestName isEqualToString:send_message_Url] && appDelegate.imageData !=nil){
            [formData appendPartWithFileData:appDelegate.imageData name:@"myFile" fileName:appDelegate.fileName mimeType:appDelegate.mime];
        }

    } progress:^(NSProgress * _Nonnull uploadProgress) {

    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        arrayParsedJson =  (NSMutableArray * )responseObject;

        [self.delegate dataReceivedFromService:arrayParsedJson withRequestName:requestName];
       //
        //[hud hideAnimated:YES];

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {

    }];

谁能给我解释一下这是怎么回事?

尝试使用图像参数和视频参数,如果只想传递视频参数,则将图像参数设置为 nil,图像参数也相同

-(void)callWebserviceToUploadImageWithParams:(NSMutableDictionary *)_params imgParams:(NSMutableDictionary *)_imgParams videoParms:(NSMutableDictionary *)_videoParams action:(NSString *)_action success:(void (^)(id))_success failure:(void (^)(NSError *))_failure

{
    if ([[AFNetworkReachabilityManager sharedManager] isReachable]) {
        NSString *urlString = [BASE_URL stringByAppendingString:_action];
        NSLog(@"URL : %@",urlString);
        NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc] init];
        [urlRequest setURL:[NSURL URLWithString:urlString]];
        [urlRequest setHTTPMethod:@"POST"];
        NSString *boundary = @"---------------------------14737809831466499882746641449";
        NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
        [urlRequest addValue:contentType forHTTPHeaderField: @"Content-Type"];
       // [urlRequest setValue:contentType forHTTPHeaderField:@"Content-type: application/json"]
        NSMutableData *body = [NSMutableData data];
        [_params enumerateKeysAndObjectsUsingBlock: ^(NSString *key, NSString *object, BOOL *stop) {
            [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
            [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",key] dataUsingEncoding:NSUTF8StringEncoding]];
            [body appendData:[[NSString stringWithFormat:@"%@",object] dataUsingEncoding:NSUTF8StringEncoding]];
        }];
        [_imgParams enumerateKeysAndObjectsUsingBlock: ^(NSString *key, NSData *object, BOOL *stop) {
            if ([object isKindOfClass:[NSData class]]) {
                if (object.length > 0) {
                    [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
                    NSLog(@"Timestamp:%@",TimeStamp);
                    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@.jpg\"\r\n",key,TimeStamp] dataUsingEncoding:NSUTF8StringEncoding]];
                    [body appendData:[[NSString stringWithFormat:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
                    [body appendData:[NSData dataWithData:object]];
                }

            }
        }];
        [_videoParams enumerateKeysAndObjectsUsingBlock: ^(NSString *key, NSData *object, BOOL *stop) {
            if (object.length > 0) {
                [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
                NSLog(@"Timestamp:%@",TimeStamp);
                [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@.mp4\"\r\n",key,TimeStamp] dataUsingEncoding:NSUTF8StringEncoding]];
                [body appendData:[[NSString stringWithFormat:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
                [body appendData:[NSData dataWithData:object]];
            }
        }];
        [body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [urlRequest setHTTPBody:body];
        AFHTTPSessionManager* manager = [AFHTTPSessionManager manager];
        manager.responseSerializer.acceptableContentTypes = nil;
        NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:urlRequest completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
            if (error) {
                NSLog(@"Error: %@", error);
                if( _failure )
                {
                    _failure( error) ;
                }
            } else {
                if( _success )
                {
                    _success( responseObject ) ;
                }
            }
        }];
        [dataTask resume];
    }
    else
    {
        [Utility showInterNetConnectionMessage];
        NSError *error;
        if( _failure )
        {
            _failure( error) ;
        }
    }
}
@end

使用这个

 -(void)callWebserviceForgetupdateprofiledata
{
    NSMutableDictionary *params = [[NSMutableDictionary alloc]init];
    [params setValue:@"1" forKey:@"device_type"];
    [params setValue:@"31" forKey:@"event_id"];
    [params setValue:@"96374F7F-562E-48BE-B25A-ECF0E92880D8" forKey:@"device_id"];
    [params setValue:@"32179d59d001a6c22ea8c73bd7ea9f598b93c1131bc4e6a7757438fc313689a8;" forKey:@"device_token"];
    [params setValue:@"live_videos" forKey:@"upload_type"];
    [params setValue:@"4" forKey:@"user_id"];
    NSMutableDictionary *imgParam=[[NSMutableDictionary alloc] init];
    [imgParam setValue:UIImageJPEGRepresentation([UIImage imageNamed:@"image.png"], 0) forKey:@"video_thumb"];

    NSMutableDictionary *Videoparams=[[NSMutableDictionary alloc] init];

    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"2" ofType:@"mp4"];

    NSError *error = nil;
    NSData *data = [NSData dataWithContentsOfFile:filePath options:nil error:&error];
    if(data == nil && error!=nil) {
        NSLog(@"%@",error);
    }
    [Videoparams setValue:data forKey:@"event_video"];


    void ( ^successed )( id _responseObject ) = ^( id _responseObject )

    {
        [SVProgressHUD dismiss];


        if ([[_responseObject valueForKey:@"status_code"]intValue] == 200) {
           NSLog(@"%@",_responseObject);
        }

    } ;

    void ( ^failure )( NSError* _error ) = ^( NSError* _error ) {
        [SVProgressHUD showErrorWithStatus:@"Failed"];
    } ;
    [[WebServiceHendler sharedManager]callWebserviceToUploadImageWithParams:params imgParams:imgParam videoParms:Videoparams action:@"user_upload_media.php" success:successed failure:failure];
}

在我看来,你应该使用方法

- (AFHTTPRequestOperation *)POST:(NSString *)URLString
                      parameters:(id)parameters
       constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block
                         success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
                         failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;

输入是 URLString,不是 NSData。 AFNetworking 可以为您处理数据问题。这是我在上传太大视频时应用程序崩溃后的经历。希望这对您有所帮助。

我的项目代码供大家参考

- (void)uploadFileWithPath:(NSString *)filePath fileName:(NSString*)fileName mimeType:(NSString*)mimeType parameters:(NSDictionary *)parameters progressBlock:(void (^)(CGFloat progress))progressBlock completed:(void (^)(NSString *fileURL, NCBServiceError *error))completed {
    if ([[parameters objectForKey:@"type"] isEqualToString:@"mp4"]) {
        if (![NCBUtil isGoodString:_videoWriteAPIURL]) {
            _videoWriteAPIURL = [[NCBSystemInfo sharedInstance].fileAPIURLDict objectForKey:@"swrite_addr"];
        }
    }
    void (^blk)(void) = [^{
        AFHTTPRequestOperation *operation =
        [[self fileClientWithURL:([[parameters objectForKey:@"type"] isEqualToString:@"mp4"] ? _videoWriteAPIURL : fileAPIURL)
   andSelectedLocalUserProfileId:nil] POST:@"file"
         parameters:parameters
         constructingBodyWithBlock:
         ^(id<AFMultipartFormData> formData) {
             NSError *error;
             [formData appendPartWithFileURL:[NSURL fileURLWithPath:filePath] name:@"UploadFile" fileName:fileName mimeType:mimeType error:&error];
         }
         success:
         ^(AFHTTPRequestOperation *operation, id responseObject) {
             NSString *fileURL = nil;

             NCBServiceError *serviceError = [NCBServiceError makeServiceErrorIfNeededWithOperation:operation
                                                                                     responseObject:responseObject];

             if(!serviceError) {
                 NSDictionary *dict = [responseObject objectForKey:JsonResponseKeyResult];
                 fileURL = [dict objectForKey:@"file_url"];
             }
             if (completed) {
                 completed(fileURL, serviceError);
             }
         }
         failure:
         ^(AFHTTPRequestOperation *operation, NSError *error) {
             NCBServiceError *serviceError = [NCBServiceError makeServiceErrorIfNeededWithOperation:operation
                                                                                        withNSError:error];
             if (completed) {
                 completed(nil, serviceError);
             }
         }];

        if(progressBlock) {
            [operation setUploadProgressBlock:
             ^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
                 CGFloat progress = ((CGFloat)totalBytesWritten) / totalBytesExpectedToWrite;
                 progressBlock(progress);
             }];
        }
    } copy];

    if ([NCBSystemInfo sharedInstance].fileAPIURLDict == nil) {
        [self getFileAPIURLCompleted:^(NSDictionary *newFileAPIURLDict, NCBServiceError *error) {
            if (!error) {
                fileAPIURL = [newFileAPIURLDict objectForKey:@"write_addr"];
                _videoWriteAPIURL = [newFileAPIURLDict objectForKey:@"swrite_addr"];
                blk();
            } else {
                completed(nil, error);
            }
        }];
    } else {
        if ([NCBUtil isGoodString:[[NCBSystemInfo sharedInstance].fileAPIURLDict objectForKey:@"write_addr"]]) {
            fileAPIURL = [[NCBSystemInfo sharedInstance].fileAPIURLDict objectForKey:@"write_addr"];
            _videoWriteAPIURL = [[NCBSystemInfo sharedInstance].fileAPIURLDict objectForKey:@"swrite_addr"];
            blk();
        } else {
            [self getFileAPIURLCompleted:^(NSDictionary *newFileAPIURLDict, NCBServiceError *error) {
                if (!error) {
                    fileAPIURL = [newFileAPIURLDict objectForKey:@"write_addr"];
                    _videoWriteAPIURL = [newFileAPIURLDict objectForKey:@"swrite_addr"];
                    blk();
                } else {
                    completed(nil, error);
                }
            }];
        }
    }
}