首页 > 解决方案 > 使用 URLSession 从 url 下载 jpg 图像

问题描述

我正在尝试从 swift 中的 url 下载图像。这是我正在尝试下载的图像url,我希望它能够将其下载到应用程序文档目录中的 On my iPhone > testExampleApplication,但是当我单击该按钮时,没有下载任何内容。这是我的代码:

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

第 2 次打印中的 Content-type 为 image/jpeg,错误打印为 nil。

我在下载代码中做错了吗?

标签: iosswiftswiftuiurlsession

解决方案


ObservableObject一般来说,在 a而不是View本身中执行这样的异步任务是一个好主意。

你已经在下载了——你现在需要做的就是保存数据:

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

如果你在模拟器中运行它,你可以看到控制台的输出以及目录的位置。如果你在 Finder 中打开它,你会看到你的图像已经保存在那里。

请注意,要在 Files 应用程序中查看目录和文件,您需要确保UIFileSharingEnabledYESInfo.plist


推荐阅读