【问题标题】:Download File Using Alamofire 4.0 (Swift 3)使用 Alamofire 4.0 (Swift 3) 下载文件
【发布时间】:2017-02-16 04:43:43
【问题描述】:

在旧版本的 Alamofire 中。这就是我下载文件的方式

    let destinationPath = Alamofire.Request.suggestedDownloadDestination( directory: .documentDirectory, domain: .userDomainMask);

    Alamofire.download(.GET, urlString, destination: destinationPath)
        .progress { bytesRead, totalBytesRead, totalBytesExpectedToRead in
//                print(totalBytesRead)
        }
        .response { request, response, _, error in

            let downloadedFilePath = destinationPath(URL(string: "")!, response!);

            NSUserDefaultsHelper.saveURL(downloadedFilePath, key: urlString);

            completion(downloadedFilePath, true);
    }

但现在在新版本中,我的代码完全无法使用,Alamofire库中也没有类似的功能。

有什么想法吗?

【问题讨论】:

  • 当我在 Google Download File Using Alamofire 4.0 (Swift 3) 上搜索时,我会得到一个指向 Alamofire 官方文档的链接,其中包含有关如何下载文件的 example。没用吗?

标签: ios swift swift3 alamofire alamofireimage


【解决方案1】:

我曾经使用这种说法:

let destination = DownloadRequest.suggestedDownloadDestination(for: .documentDirectory)

Alamofire.download(
    url,
    method: .get,
    parameters: parameters,
    encoding: JSONEncoding.default,
    headers: nil,
    to: destination).downloadProgress(closure: { (progress) in
        //progress closure
    }).response(completionHandler: { (DefaultDownloadResponse) in
        //here you able to access the DefaultDownloadResponse
        //result closure
    })

更多详情请阅读Alamofire docs about Migration to 4.0

【讨论】:

  • 响应中的代码块是 DefaultDownloadResponse,我在获取最终的 'downloadedFilePath' 时遇到问题
  • 实际下载的文件路径是destination + nameOfTheFile,不是吗?
  • 是的,但是如果您查看我的代码,文件名是由 Alamofire 自动生成的。这就是我使用destinationPath 函数获取完整路径的原因。
  • 我可能误会了。更新了答案。这是你要找的吗?
  • 文件下载后,谁能告诉如何使用目标 url 打开文件..
【解决方案2】:

Swift 4.0

 let destination: DownloadRequest.DownloadFileDestination = { _, _ in
            var documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
            documentsURL.appendPathComponent("file.csv")
            return (documentsURL, [.removePreviousFile])
        }

        Alamofire.download(url, to: destination).responseData { response in
            if let destinationUrl = response.destinationURL {
               print("destinationUrl \(destinationUrl.absoluteURL)")
            }
        }

【讨论】:

    【解决方案3】:

    Alamofire 4 中有几个增强功能。其中第一个是目的地关闭的可选性。现在,默认情况下,目标闭包为 nil,这意味着文件不会在文件系统上的任何位置移动,并且会返回临时 URL。

    这是默认执行:-

    Alamofire.download(urlString).responseData { response in
        print("Temporary URL: \(response.temporaryURL)")
    }
    

    这是我用 Alamofire 4.0 下载文件的代码,它返回文件的目标 URL:-

    let destination: DownloadRequest.DownloadFileDestination = { _, _ in
            var documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
            documentsURL.appendPathComponent("duck.png")
            return (documentsURL, [.removePreviousFile])
        }
    
        Alamofire.download(url, to: destination).responseData { response in
        if let destinationUrl = response.destinationURL ? {
            completionHandler(destinationUrl)
        }
    }
    

    【讨论】:

    • 为什么使用documentsURL, [.removePreviousFile]
    【解决方案4】:

    使用 Alamofire 4.0 Swift 4.x 下载 mp3 文件

    由于几乎所有示例似乎都与下载图像或 JSON 文件有关,因此我花了几个小时才找到正确的解决方案。
    我会在这里分享它,希望它可以帮助其他人节省一些时间。

    func startDownload(audioUrl:String) -> Void {
        let fileUrl = self.getSaveFileUrl(fileName: audioUrl)
        let destination: DownloadRequest.DownloadFileDestination = { _, _ in
            return (fileUrl, [.removePreviousFile, .createIntermediateDirectories])
        }
    
        Alamofire.download(audioUrl, to:destination)
            .downloadProgress { (progress) in
                self.progressLabel.text = (String)(progress.fractionCompleted)
            }
            .responseData { (data) in
                self.progressLabel.text = "Completed!"
        }
    }
    
    func getSaveFileUrl(fileName: String) -> URL {
        let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
        let nameUrl = URL(string: fileName)
        let fileURL = documentsURL.appendingPathComponent((nameUrl?.lastPathComponent)!)
        NSLog(fileURL.absoluteString)
        return fileURL;
    }
    

    【讨论】:

      【解决方案5】:

      对于最新版本,它应该是这样的:

      let destination: DownloadRequest.Destination = { _, _ in
              let documentsURL = FileManager.default.urls(for: .picturesDirectory, in: .userDomainMask)[0]
                  let fileURL = documentsURL.appendingPathComponent("image.png")
      
                  return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
          }
      
          AF.download("https://httpbin.org/image/png", to: destination).response { response in
              debugPrint(response)
      
              if response.error == nil, let imagePath = response.fileURL?.path {
                  let image = UIImage(contentsOfFile: imagePath)
              }
          }
      

      【讨论】:

        【解决方案6】:

        Swift 3 Alamofire (4.4.0):

        .plist add key "App Transport Security Settings->Allow Arbitrary Loads->Yes" 如果你复制粘贴下面的代码:

        import Alamofire
        
            let destination = DownloadRequest.suggestedDownloadDestination()
        
            Alamofire.download("http://zmp3-mp3-lossless-te-zmp3-bdhcm-1.zadn.vn/151e407bb43f5d61042e/1223048424027738068?key=f-zMo3GZKlhVibnvGMsMuQ&expires=1495726053&filename=See%20You%20Again%20-%20Wiz%20Khalifa%20Charlie%20Puth%20(NhacPro.net).flac", to: destination).downloadProgress(queue: DispatchQueue.global(qos: .utility)) { (progress) in
                print("Progress: \(progress.fractionCompleted)")
            } .validate().responseData { ( response ) in
                print(response.destinationURL!.lastPathComponent)
            }
        

        【讨论】:

          【解决方案7】:

          使用此代码下载文件

               let fileManager = FileManager.default
               let directoryURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
          
              Alamofire.request(\(downloadUrl)).downloadProgress(closure : { (progress) in
                  print(progress.fractionCompleted)
          
              }).responseData{ (response) in
                  print(response)
                  print(response.result.value!)
                  print(response.result.description)
                     let randomString = NSUUID().uuidString
                  if let data = response.result.value {
          
                      let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
                      let videoURL = documentsURL.appendingPathComponent("\(randomString)")
                      do {
                          try data.write(to: videoURL)
          
                      } catch {
                          print("Something went wrong!")
                      }
          
                  }
              }
          

          【讨论】:

          • 嗨。我下载成功但找不到我的视频在哪里,你能帮忙吗?
          • @famfamfam 您可以在文档目录中找到该文件
          • 嗨。这是我的文件网址:'file:///Users/thehe/Library/Developer/CoreSimulator/Devices/01F3C177-1B6A-4CB4-AABE-45EB0D57A3C1/data/Containers/Data/Application/DEA4544E-54A9-4104-9A7A- CAF5B9D172B3/Documents/CiviX_HistoryVideo_19-1-2019_7h59m28s.mp4' ,然后我得到的错误是'文件“CiviX_HistoryVideo_19-1-2019_7h59m28s.mp4”无法保存在文件夹“Documents”中。'
          • @famfamfam 请查看进度,如果是100%则保存到文档目录中
          猜你喜欢
          • 2017-04-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-02-09
          • 2017-11-15
          • 1970-01-01
          • 2017-12-16
          相关资源
          最近更新 更多