I am using Alamofire to upload assets (image/video) as multipart form data. It works fine for file sizes below 300MB (app). When I try to upload a file greater than 300MB, app crashes.
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
}
}
I also get the below message from Xcode
How would I support uploading huge sized videos using Alamofire?
Use Stream to upload instead of converting file to NSData which lead to memory problem and occur crash while uploading huge files. sample code
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
})
}
Alamofire Documentation
Uploading Data to a Server When sending relatively small amounts of data to a server using JSON or URL encoded parameters, the request() APIs are usually sufficient. If you need to send much larger amounts of data from Data in memory, a file URL, or an InputStream, then the upload() APIs are what you want to use.
Uploading Data
let data = Data("data".utf8) AF.upload(data, to: "https://httpbin.org/post").responseJSON { response in debugPrint(response) }
Uploading a File
let fileURL = Bundle.main.url(forResource: "video", withExtension: "mov") AF.upload(fileURL, to: "https://httpbin.org/post").responseJSON { response in debugPrint(response) }
Uploading Multipart Form Data
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) }
Upload Progress While your user is waiting for their upload to complete, sometimes it can be handy to show the progress of the upload to the user. Any UploadRequest can report both upload progress of the upload and download progress of the response data download using the uploadProgress and downloadProgress APIs.
let fileURL = Bundle.main.url(forResource: "video", withExtension: "mov") AF.upload(fileURL, to: "https://httpbin.org/post") .uploadProgress { progress in print("Upload Progress: \(progress.fractionCompleted)") } .downloadProgress { progress in print("Download Progress: \(progress.fractionCompleted)") } .responseJSON { response in debugPrint(response) }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With