我正在尝试从用户设备上传大约50MB但不大于100MB的音频文件到PHP服务器。只要文件很小就没有问题,但是这些较大的文件会导致应用程序因错误而崩溃:“由于内存问题而终止”。是否需要实施像AlamoFire这样的框架来解决这个问题,或者我在文档中遗漏了哪些内容?
谢谢, 这是我的代码:
- (void)initWithWebRequests:(NSMutableURLRequest *)URLRequest inBlock:(ResponseBlock)resBlock
{
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
__block id responseObjects = nil;
NSLog(@"URL Request:%@",URLRequest);
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:URLRequest
completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
NSString *responseString = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
if (data.length > 0)
{
id allValues = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
if([(NSDictionary *)allValues count] <= 0)
responseString = @"Not Available";
responseObjects = allValues;
}
else if(error != nil)
{
responseString = @"Fail";
}
else if(data.length == 0)
{
responseString = @"Not Available";
}
dispatch_sync(dispatch_get_main_queue(), ^{
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
if (error) {
resBlock(error, responseObjects, responseString);
}
else {
resBlock(error, responseObjects, responseString);
}
}];
});
}];
[task resume];
});
}];
[operation setQueuePriority:NSOperationQueuePriorityNormal];
[self.operationQueue addOperation:operation];
}
答案 0 :(得分:1)
使用uploadTaskWithRequest:fromFile:completionHandler:
代替dataTaskWithRequest
并在fromFile
参数中提供请求正文,而不是将其添加到请求中。这可以防止同时将整个文件加载到内存中。
理论上,您可以进行基于流的上传以避免内存影响,但考虑到您所谈论的文件大小,我假设您最终想要考虑使用后台NSURLSession
。对于后台上传请求,您确实希望使用基于文件的上传,而不是基于流的方法。
在回答您的框架问题时,像Alamofire这样的库(或者,更合适的是,您使用的是Objective-C,AFNetworking,来自同一作者的Objective-C网络库)有助于创建复杂的请求,所以你可能会考虑这一点,但它与你在这里的内存问题无关。
答案 1 :(得分:0)
尝试此AFNetworking代码导入#import“AFHTTPSessionManager.h”此文件
[SVProgressHUD showWithStatus:@"Loading..."];
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:URL parameters:postParams constructingBodyWithBlock:^(id<AFMultipartFormData> formData)
{
[formData appendPartWithFileData:imageData name:@"Key" fileName:@"image" mimeType:@"image/jpeg"];
} error:nil];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSURLSessionUploadTask *uploadTask;
uploadTask = [manager
uploadTaskWithStreamedRequest:request
progress:^(NSProgress * _Nonnull uploadProgress)
{
NSLog(@"%@",uploadProgress);
}
completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error)
{
if (error)
{
[SVProgressHUD dismiss];
}
else
{
[SVProgressHUD dismiss];
}
}];
[uploadTask resume];