ios - ios swift将视频从url下载到手机图库
问题描述
我正在使用 URLSessionDownloadTask 将视频从 url 下载到我的手机图库,我如何设置下载的视频文件的目标路径,我需要它出现在我的手机视频文件夹中。
var downloadTask: URLSessionDownloadTask!
var backgroundSession: URLSession!
if let theUrl = url {
downloadTask = backgroundSession.downloadTask(with: theUrl)
downloadTask.resume()
}
extension DownloadVideoViewController : URLSessionDownloadDelegate {
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
if self.downloadTask != nil {
self.displyAlertWithAction(title: "Complete", message: "Download finished")
}
}
func urlSession(_ session: URLSession,downloadTask: URLSessionDownloadTask,didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64)
{
print("\nDownload started ....Total is \(Float(totalBytesExpectedToWrite)/(1024*1024)) Mb")
print("\nWritten \(totalBytesWritten) bytes")
progressView.setProgress(Float(totalBytesWritten)/Float(totalBytesExpectedToWrite), animated: true)
}
func urlSession(_ session: URLSession,task: URLSessionTask,didCompleteWithError error: Error?)
{
if (error != nil) {
print(error!.localizedDescription)
}else{
if downloadTask != nil {
print("The task finished transferring data successfully")
downloadTask = nil
progressView.setProgress(0.0, animated: true)
}
}
}
}
解决方案
您可以像下面的代码示例一样设置目标路径。
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
let url = downloadTask.response?.url?.lastPathComponent
if (url?.hasSuffix(".mp4"))! // for check video download
{
SVProgressHUD.dismiss() // dismiss the HUD
guard let documentsDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
if !FileManager.default.fileExists(atPath: documentsDirectoryURL.appendingPathComponent((downloadTask.response?.url?.lastPathComponent)!).path) { // the video already exist in path
// create a deatination url with the server response suggested file name
let destinationURL = documentsDirectoryURL.appendingPathComponent(downloadTask.response?.suggestedFilename ?? ((downloadTask.response?.url)?.lastPathComponent)!)
do {
try FileManager.default.moveItem(at: location, to: destinationURL)
PHPhotoLibrary.requestAuthorization({(authorizationStatus: PHAuthorizationStatus) -> Void in
var identifier = ""
// check if user authorized access photos for your app
if authorizationStatus == .authorized {
PHPhotoLibrary.shared().performChanges({
let createassetrequest = PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: destinationURL)
let assetplaceholder = createassetrequest?.placeholderForCreatedAsset
let albumchange = PHAssetCollectionChangeRequest(for: self.assetcol.assetCollection)
albumchange?.addAssets([assetplaceholder as Any] as NSArray)
identifier = (assetplaceholder?.localIdentifier)!
print(identifier)
})
{ completed, error in
if completed {
DispatchQueue.main.async {
print("Video saved") // successfully saved video in your gallery
}
} else {
print(error as Any)
}
}
}
})
} catch { print(error) }
}
else // video not already exist in this destination path.
{
SVProgressHUD.dismiss()
let destinationURL = documentsDirectoryURL.appendingPathComponent(downloadTask.response?.suggestedFilename ?? ((downloadTask.response?.url)?.lastPathComponent)!)
do {
try FileManager.default.removeItem(at: destinationURL)
try FileManager.default.moveItem(at: location , to: destinationURL)
PHPhotoLibrary.requestAuthorization({ (authorizationStatus: PHAuthorizationStatus) -> Void in
var identifier = ""
// check if user authorized access photos for your app
if authorizationStatus == .authorized {
PHPhotoLibrary.shared().performChanges({
let createassetrequest = PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: destinationURL)
let assetplaceholder = createassetrequest?.placeholderForCreatedAsset
let albumchange = PHAssetCollectionChangeRequest(for: self.assetcol.assetCollection)
albumchange?.addAssets([assetplaceholder as Any] as NSArray)
identifier = (assetplaceholder?.localIdentifier)!
print(identifier)
}) { completed, error in
if completed {
DispatchQueue.main.async {
print("Video saved") // saved video successfully.
}
} else {
print(error as Any)
}
}
}
})
} catch { print(error) }
}
}
else // something like image if not video
{
}
}
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
DispatchQueue.main.async {
let progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
SVProgressHUD.showProgress(progress, status: "Downloading")
}
}
}
我希望它会帮助你。
推荐阅读
- windows - 为什么 certutil 返回自签名错误?
- dart - 在 lib 目录之外导入 dart 文件
- javascript - 带有附加表单元素的 jQuery 验证
- c# - 循环静态只读字段定义的奇怪行为
- c# - IIS 上应用程序的 ASP.NET Core 结构
- c# - TeamCity - NUnit Console Runner 在使用 Kentico Fakes 时未找到所有单元测试
- java - 如何对列表的每个对象进行并发调用?
- asp.net-mvc - 有没有办法缩短基于数据注释的模型验证?
- mongodb - Mongoose findOne() 是否和 MongoDB 的 findOne() 一样低效?
- hazelcast - Hazelcast 流聚合和其他计算在节点或客户端上执行