Alamofire上传大文件

时间:2016-11-03 09:42:20

标签: ios swift alamofire multipartform-data

我正在使用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获得以下消息

enter image description here

我如何支持使用Alamofire上传大尺寸视频?

2 个答案:

答案 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)

Alamofire Documentation

将数据上传到服务器 当使用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)
    }