是否有可能在不快速调用 API 的情况下从互联网获取图像?
Posted
技术标签:
【中文标题】是否有可能在不快速调用 API 的情况下从互联网获取图像?【英文标题】:Is there a possibility to get the image from internet without calling API in swift? 【发布时间】:2021-11-04 02:17:01 【问题描述】:从第一次调用 api强>。并且必须从嵌套在 json 对象中的链接中获取图像(从获得的数据中解析)。我是否需要创建一个单独的方法,该方法将再次使用 json 的嵌套链接调用 api 或者是否有任何速记(框架工作)方法可以做到这一点。喜欢,
let image = UIImage(data: imageData) // 框架中的默认方法 let image = UIImage(contentsOfFile : fileLocation) // 框架中的默认方法let image = UIImage(url: URL) // 期待这样的方法
我期待一种类似上述的方法,它可以直接从 url 获取图像,而无需重复调用 api 从嵌套链接中获取图像。有没有可能,这样我就可以避免多次api调用并最小化线程?
【问题讨论】:
将 URL 保存在内存中,在该特定图像数据上再次使用URLSession
,然后对其调用 UIImage(data: imageData)
。或者使用 SDWebImage、Alamofire+Image、KingFisher...
avoid multiple api calls and minimise threads
- 使用推荐的方法时,您是否发现线程数有问题?
【参考方案1】:
自从引入 Combine 框架以来,嵌套网络调用变得非常舒适。
这是jsonplaceholder
API 的示例。代码首先加载包含 id
和 url
的 JSON,然后在此 URL 加载图像
import Combine
struct Photo : Decodable, Identifiable
let id : Int
let url : URL
var storage : AnyCancellable?
let baseURL = URL(string: "https://jsonplaceholder.typicode.com/photos/1")!
storage = URLSession.shared.dataTaskPublisher(for: baseURL)
.map(\.data)
.decode(type: Photo.self, decoder: JSONDecoder())
.map(\.url)
.flatMap url in
URLSession.shared.dataTaskPublisher(for: url)
.map(\.data)
.replaceError(with: Data())
.eraseToAnyPublisher()
.receive(on: DispatchQueue.main)
.sink result in
print(result)
receiveValue: imageData in
print("Image successfully loaded containing", imageData)
let image = UIImage(data: imageData)
【讨论】:
【参考方案2】:您也可以在不调用 api 的情况下显示来自 url 的图像。要实现这一点,您需要将 url 转换为 Data
let imageURL = "https://picsum.photos/200/300"
let imageData = Data(contentsOf: URL(string: imageURL)!)
let finalImage = UIImage(data: imageData)
extension UIImageView
func load(imageURL: URL)
DispatchQueue.global().async [weak self] in
let imageData = Data(contentsOf: imageURL)
let finalImage = UIImage(data: imageData)
DispatchQueue.main.async
//set your image here in main thread
请尝试一下,看看它是否适合你
【讨论】:
强烈建议您不要与Data(contentsOf:)
同步加载数据。别。它阻塞线程并导致糟糕的用户体验。
是的,我同意,我不欣赏这种方法,但根据问题,我只想表明这是可以实现的
我已经更新了我的答案,请您建议这种方法可以同步加载图像吗?
它仍然阻塞线程,不是主线程而是公共全局线程。使用 URLSession 异步加载数据——无论是使用传统的完成处理程序还是使用现代的组合发布者——是最先进的。
严格来说,URLSession
和 Data(contentsOf
都执行一种 API 调用。使用 Combine,您可以以一种同步的外观但异步的性能链接多个调用。以上是关于是否有可能在不快速调用 API 的情况下从互联网获取图像?的主要内容,如果未能解决你的问题,请参考以下文章
在不打开应用程序的情况下从 Firebase 更新应用程序数据
如何在不知道匹配返回的 json 数据中的所有值的情况下从 .Net 核心中的 Web api 调用创建模型?
如何在不使用 curl 和 guzzle 的情况下从控制器 Laravel 调用 API,因为它不起作用 [关闭]
如何在不传递委托的情况下从 RootViewController 调用 AppDelegate 方法?