Home > Software design >  Downloading jpg image from url with URLSession
Downloading jpg image from url with URLSession

Time:10-13

I'm trying to download an image from a url in swift. This is the image url I'm trying to download, and I'm expecting it to download it to On my iPhone > testExampleApplication in the application's documents directory, but when I click the button, nothing downloads. Here's my code:

Button("Download logo image") {
      let imageUrlStr = "https://media.wired.com/photos/5f2d7c2191d87e6680b80936/16:9/w_2400,h_1350,c_limit/Science_climatedesk_453801484.jpg".addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
      let task = URLSession.shared.dataTask(with: URLRequest(url: URL(string: imageUrlStr)!), completionHandler: {(data, response, error) -> Void in
        print("download details 1: \(data)")
        print("download details 2: \(response)")
        print("download details 3: \(error)")
      })
      // Start the download.
      task.resume()
}

The Content-type in the 2nd print is image/jpeg and the error print is nil.

Am I doing something wrong in my downloading code?

CodePudding user response:

In general, it's a good idea to do asynchronous tasks like this in a ObservableObject rather than the View itself.

You're already doing the downloading -- all you need to do now is save the data:

class Downloader : ObservableObject {
    func downloadImage() {
        let imageUrlStr = "https://media.wired.com/photos/5f2d7c2191d87e6680b80936/16:9/w_2400,h_1350,c_limit/Science_climatedesk_453801484.jpg".addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
              let task = URLSession.shared.dataTask(with: URLRequest(url: URL(string: imageUrlStr)!), completionHandler: {(data, response, error) -> Void in
                
                  guard let data = data else {
                      print("No image data")
                      return
                  }
                  
                  do {
                      try data.write(to: self.getDocumentsDirectory().appendingPathComponent("image.jpg"))
                      print("Image saved to: ",self.getDocumentsDirectory())
                  } catch {
                      print(error)
                  }
                  
              })
              // Start the download.
              task.resume()
    }
    
    private func getDocumentsDirectory() -> URL {
        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        return paths[0]
    }
}

struct ContentView : View {
    @StateObject private var downloader = Downloader()
    
    var body : some View {
        Button("Download") {
            downloader.downloadImage()
        }
    }
}

If you run this in the simulator, you can see the output to the console with the location of the directory. If you open that in Finder, you'll see your image has been saved there.

Note that to see the directory and file in the Files app, you'll need to make sure that you've set UIFileSharingEnabled to YES in your Info.plist

CodePudding user response:

Firstly import Kingfisher as-

pod 'Kingfisher'

Then import it in your class as -

import Kingfisher

After that add a temporary UIImageView

let imgView = UIImageView()
imgView.kf.setImage(with: yourImageURL)

if let finalImage = imgView.image {
    // finalImage is your image
}
  • Related