Search code examples
iosswiftuitableviewalamofire

Download file with right extension


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()
}

Solution

  • 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.sstatic.net/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()