Uploading video using AFNetworking causes memory issue

白昼怎懂夜的黑 提交于 2019-12-11 01:49:22

问题


I know this question has been asked before but I can't figure out the correct way from those posts. So here is my code to upload a video file that causes memory issues:

    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) {

    }];

Can anyone explain me what's wrong here?


回答1:


In my opinion, you should use method

- (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;

Input is URLString, not NSData. AFNetworking can handle data issue for you. This is my experience after my application crashed when upload too large video. Hope this helpful.

My project code for your reference

- (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);
                }
            }];
        }
    }
}



回答2:


Try this With image parameter and video parameter, If you want to pass only video parameter then make image parameter as nil and same for image parameter

-(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

for using this

 -(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];
}


来源:https://stackoverflow.com/questions/40084703/uploading-video-using-afnetworking-causes-memory-issue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!