我正在使用Alamofire将资产(图片/视频)上传为多部分表单数据。它适用于300MB(app)以下的文件大小。当我尝试上传大于300MB的文件时,应用程序崩溃了。
if let video = self.avPlayerItem?.asset as? AVURLAsset {
if let assetData = NSData(contentsOfURL: video.URL) {
multipartFormData.appendBodyPart(data: assetData, name: "file", fileName: "video", mimeType: "video/mp4") // Execution stops here
}
}
我也从Xcode获得以下消息
我如何支持使用Alamofire上传大尺寸视频?
答案 0 :(得分:5)
使用Stream上传而不是将文件转换为NSData,这会导致内存问题,并在上传大文件时发生崩溃。 示例代码
if let imageUrl = info[UIImagePickerControllerReferenceURL] as? NSURL{
let assetLibrary = ALAssetsLibrary()
assetLibrary.assetForURL(imageUrl , resultBlock: { (asset: ALAsset!) -> Void in
if let actualAsset = asset as ALAsset? {
let assetRep: ALAssetRepresentation = actualAsset.defaultRepresentation()
let size = assetRep.size()
let stream = NSInputStream(URL: assetRep.url())
Alamofire.upload(
.POST,
"SERVER_URL",
headers: [:],
multipartFormData: { multipartFormData in
multipartFormData.appendBodyPart(stream: stream!, length: UInt64(size), name: "fileparameter", fileName: "fileName", mimeType: "video/mp4")
},
encodingCompletion: { encodingResult in
switch encodingResult {
case .Success(let upload, _, _):
upload.progress { bytesWritten, totalBytesWritten, totalBytesExpectedToWrite in
dispatch_async(dispatch_get_main_queue()) {
let percent = (Float(totalBytesWritten) / Float(totalBytesExpectedToWrite))
print(percent)
}
}
upload.validate()
upload.responseJSON { response in
print(response);
}
case .Failure(let encodingError):
print(encodingError)
let error = NSError(domain: "", code: 404, userInfo: [NSLocalizedDescriptionKey: "Image Uploading Failed. Please try again."])
let result = Result<AnyObject, NSError>.Failure(error)
let response = Response(request: nil, response: nil, data: nil, result: result)
print(response);
}
}
)
}
}, failureBlock: { (error) -> Void in
})
}
答案 1 :(得分:1)
将数据上传到服务器 当使用JSON或URL编码的参数向服务器发送相对少量的数据时,request()API通常就足够了。如果您需要从内存中的数据,文件URL或InputStream中发送大量数据,那么您将要使用upload()API。
上传数据
$publicKey = (Get-Content .\keys\id_rsa.pub); $publicKey = $publicKey.Trim(); $parametersObject = @{"sshPublicKey" = $publicKey }
上传文件
let data = Data("data".utf8) AF.upload(data, to: "https://httpbin.org/post").responseJSON { response in debugPrint(response) }
上传多部分表单数据
let fileURL = Bundle.main.url(forResource: "video", withExtension: "mov") AF.upload(fileURL, to: "https://httpbin.org/post").responseJSON { response in debugPrint(response) }
上传进度当您的用户正在等待上传到 完成,有时可以方便地显示上传进度 给用户。任何UploadRequest都可以报告 使用上传和下载响应数据的进度 uploadProgress和downloadProgress API。
AF.upload(multipartFormData: { multipartFormData in multipartFormData.append(Data("one".utf8), withName: "one") multipartFormData.append(Data("two".utf8), withName: "two") }, to: "https://httpbin.org/post") .responseJSON { response in debugPrint(response) }