3

Problem with downloading files.

I'm trying to download a file form url and push it into open/share modal. But da data downloads as Data and if I try saving it to File app it saves a file called Data.

I just need to download and share the file with the original extension. Like file.extension.

Here's the code use. I used Alamofire pod here:

AF.download(url).responseData { response in
    if let preset = response.value {
        let shareArray = [preset]
        let activityViewController = UIActivityViewController(activityItems: shareArray , applicationActivities: nil)
                activityViewController.popoverPresentationController?.sourceView = self.view
        self.present(activityViewController, animated: true, completion: nil)
    }
}

Also tried this code but the app crashed:

if let url = URL(string: downloadURL!) {

    let task = URLSession.shared.downloadTask(with: url) { localURL, urlResponse, error in
        if let localURL = localURL {
            let shareArray = [localURL]
            let activityViewController = UIActivityViewController(activityItems: shareArray , applicationActivities: nil)
            activityViewController.popoverPresentationController?.sourceView = self.view
            self.present(activityViewController, animated: true, completion: nil)
        }
    }

    task.resume()
}
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
Cristian
  • 57
  • 1
  • 8

2 Answers2

2

The issue there is that you are trying to share the temporary file returned. It has a dynamic UTI (Unified Type Identifier). You need to get the url response suggested file name and rename the file.

import UIKit
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true

extension URL {
    var typeIdentifier: String? { (try? resourceValues(forKeys: [.typeIdentifierKey]))?.typeIdentifier }
}

let url = URL(string: "https://i.stack.imgur.com/varL9.jpg")!
URLSession.shared.downloadTask(with: url) { location, response, error in
    guard let location = location,
          let httpURLResponse = response as? HTTPURLResponse,
          httpURLResponse.statusCode == 200 else { return }
    let fileName = httpURLResponse.suggestedFilename ?? httpURLResponse.url?.lastPathComponent ?? url.lastPathComponent
    let destination = FileManager.default.temporaryDirectory.appendingPathComponent(fileName)
    do {
        if FileManager.default.fileExists(atPath: destination.path) {
            try FileManager.default.removeItem(at: destination)
        }
        print("location", location.typeIdentifier ?? "no UTI")  // location dyn.ah62d4rv4ge81k5pu
        try FileManager.default.moveItem(at: location, to: destination)
        print("destination", destination.typeIdentifier ?? "no UTI")   // destination public.jpeg
    } catch {
        print(error)
    }
}.resume()
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
1

To complete the answer from @leo Dabus, there is a need to modify the destination URL further and append the file extension you desire by using

FileManager.default.moveItem(at:to:)

https://developer.apple.com/documentation/foundation/filemanager/1414750-moveitem

        func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
         // create destination URL with the original pdf name
         print("fileDownload: urlSession")
         guard let url = downloadTask.originalRequest?.url else { return }
         print("fileDownload: urlSession \(url)")
         let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
         let destinationURL = documentsPath.appendingPathComponent(url.lastPathComponent)
         // delete original copy
         try? FileManager.default.removeItem(at: destinationURL)
         // append a new extension type
       let newURL = destinationURL.deletingPathExtension().appendingPathExtension("pdf")   
       // copy from temp to Document
       try? FileManager.default.moveItem(at: destinationURL, to: newURL)
         do {
             try FileManager.default.copyItem(at: location, to: newURL)
             myViewDocumentsmethod(PdfUrl:destinationURL)
             print("fileDownload: downloadLocation", destinationURL)
         } catch let error {
             print("fileDownload: error \(error.localizedDescription)")
         }
     
     }
Tony_Kara
  • 31
  • 8