ios - iOS 中的大型 Base64 上传

标签 ios http upload base64

描述: 我需要在代表要上传的文件的 HTTP POST 参数中发送一个 base 64 编码的字符串。

当前方法:我正在使用 ASIFormDataRequest 并将我的文件编码为 base64 字符串,如下所示:

NSData *data = [[NSFileManager defaultManager] contentsAtPath:@"my path here"];
NSString *base64Data = [data encodeBase64ForData];

然而,当上传大文件时,应用程序会耗尽内存并死于可怕的死亡!

建议的解决方案:现在有人知道我会如何处理吗,比方说,从磁盘读取文件,将其转换为 block 中的 base64 字符串,并将转换后的 base64 字符串附加到 HTTP 请求中的参数?

有效地避免将整个文件读入内存的任何方式。

任何输入将不胜感激!

完整的http请求代码:

NSURL *url = [NSURL URLWithString:requestProgressURLString];
NSData *data = [[NSFileManager defaultManager] contentsAtPath:evidence.uri];
NSString *base64Data = [data encodeBase64ForData];
NSURL *fileURL = [[NSURL alloc] initWithString:evidence.uri];

request = [ASIFormDataRequest requestWithURL:url];

request.shouldAttemptPersistentConnection = false;
[request setShowAccurateProgress:YES];

[request setPostValue:accessToken forKey:@"AccessToken"];
[request setPostValue:[[fileURL path] lastPathComponent] forKey:@"Filename"];
[request setPostValue:evidence.name forKey:@"Title"];
[request setPostValue:base64Data forKey:@"FileData"]; //wants string value (base64 encoded)          
[request addRequestHeader:@"Content-Type" value:@"application/x-www-form-urlencoded"];
[request setTimeOutSeconds:60];
[request setUploadProgressDelegate:self];
[request setDownloadProgressDelegate:self];
[request setDelegate:self];
[request setDidFinishSelector:@selector(requestDone:)];
[request setDidFailSelector:@selector(requestWentWrong:)];

最佳答案

我会把这个问题分成两个:

<强>1。将大文件分 block 编码为 Base64
<强>2。上传该文件


<强>1。将大文件分 block 编码为 Base64:

找到一些将 NSData 实例编码为 Base64 的代码。然后使用一个 NSInputStream 以 block 的形式读取数据,对其进行编码并使用 NSOutputStream 写入一个临时文件。我找到了这个问题/答案:Is it possible to base64-encode a file in chunks?使 block 大小成为 3 的倍数,它应该可以工作。您可能希望将其移至后台线程。

重要提示:这将创建一个比原始文件大的临时文件。那一刻设备上必须有足够的空间。开始上传后,您可以将其删除。


<强>2。上传该文件

看来你已经完成了。您可以像示例中那样使用 ASIFormDataRequest。由于它制作了文件的私有(private)副本(它构建了多部分 POST 文件),因此您可以删除副本。

如果您想通过并行化这些步骤来优化它,您将需要找到另一种上传多部分文件的方法。

关于ios - iOS 中的大型 Base64 上传,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13198152/

相关文章:

ios - Swift 进度指示器图像 mask

javascript - 尝试从 Express 和 Node 应用程序返回 JSON 对象。获取一个空白对象

angular - 在 Angular 6 中添加 http header

php - PHP 中的 HTTP PUT 请求

Android Webview 相机上传无法旋转?网页 View 重新加载?安卓 5 和 6+

android - QML 中的多页应用程序

ios - 无需登录即可搜索 YouTube API

iphone - 获取连接到 LAN 的设备的 IP 地址/MAC 地址

javascript - 从纯javascript到prototypejs

php - "simple"显示上传进度的 PHP 脚本,不使用模块、包、flash