Swiftui 使用Combine framwork时在何处设置图像缓存
学习如何在YouTube中使用本机NSCache缓存图像 下面是运行良好的示例代码。在从Swiftui 使用Combine framwork时在何处设置图像缓存,swiftui,combine,image-caching,Swiftui,Combine,Image Caching,学习如何在YouTube中使用本机NSCache缓存图像 下面是运行良好的示例代码。在从URLSession.shared.dataTask返回数据后,我可以看到它在getimagefromsresponse方法中将图像设置到缓存中。这是使用@escaping完成处理程序的老方法 import Foundation import SwiftUI class UrlImageModel: ObservableObject { @Published var image: UIImage?
URLSession.shared.dataTask
返回数据后,我可以看到它在getimagefromsresponse
方法中将图像设置到缓存中。这是使用@escaping完成处理程序的老方法
import Foundation
import SwiftUI
class UrlImageModel: ObservableObject {
@Published var image: UIImage?
var urlString: String?
var imageCache = ImageCache.getImageCache()
init(urlString: String?) {
self.urlString = urlString
loadImage()
}
func loadImage() {
if loadImageFromCache() {
print("Cache hit")
return
}
print("Cache miss, loading from url")
loadImageFromUrl()
}
func loadImageFromCache() -> Bool {
guard let urlString = urlString else {
return false
}
guard let cacheImage = imageCache.get(forKey: urlString) else {
return false
}
image = cacheImage
return true
}
func loadImageFromUrl() {
guard let urlString = urlString else {
return
}
let url = URL(string: urlString)!
let task = URLSession.shared.dataTask(with: url, completionHandler: getImageFromResponse(data:response:error:))
task.resume()
}
func getImageFromResponse(data: Data?, response: URLResponse?, error: Error?) {
guard error == nil else {
print("Error: \(error!)")
return
}
guard let data = data else {
print("No data found")
return
}
DispatchQueue.main.async {
guard let loadedImage = UIImage(data: data) else {
return
}
self.imageCache.set(forKey: self.urlString!, image: loadedImage)
self.image = loadedImage
}
}
}
class ImageCache {
var cache = NSCache<NSString, UIImage>()
func get(forKey: String) -> UIImage? {
return cache.object(forKey: NSString(string: forKey))
}
func set(forKey: String, image: UIImage) {
cache.setObject(image, forKey: NSString(string: forKey))
}
}
extension ImageCache {
private static var imageCache = ImageCache()
static func getImageCache() -> ImageCache {
return imageCache
}
}
///更新,我找到了怎么做。添加CombinehandleEvents
方法,并在receiveOutput闭包中设置图像缓存,以解决此问题。顺便说一句,有更多的参数,处理上游出版商和下游接收器。对我来说,这需要更多的实践才能在Combine中使用这种新的网络方式
修复了代码,我还在图像缓存部分添加了一个下标
import Foundation
import SwiftUI
import Combine
class UrlImageModel: ObservableObject {
@Published var image: UIImage?
private var url: URL?
private var cancellable: AnyCancellable?
private var imageCache = ImageCache.getImageCache()
init(url: URL?) {
self.url = url
loadImage()
}
func loadImage() {
if loadImageFromCache() {
print("Cache hit")
return
}
print("Cache missing, loading from url")
loadImageFromUrl()
}
func loadImageFromCache() -> Bool {
guard let url = url else {
return false
}
guard let cacheImage = imageCache[url] else {
return false
}
image = cacheImage
return true
}
func loadImageFromUrl() {
guard let url = url else {
return
}
cancellable = URLSession.shared.dataTaskPublisher(for: url)
.map { UIImage(data: $0.data) }
.replaceError(with: nil)
// set image into cache!
.handleEvents(receiveOutput: { [unowned self] image in
guard let image = image else {return}
self.imageCache[url] = image
})
.receive(on: DispatchQueue.main)
.assign(to: \.image, on: self)
}
}
class ImageCache {
var cache = NSCache<NSURL, UIImage>()
subscript(_ key: URL) -> UIImage? {
get { cache.object(forKey: key as NSURL) }
set { newValue == nil ? cache.removeObject(forKey: key as NSURL) : cache.setObject(newValue!, forKey: key as NSURL) }
}
}
extension ImageCache {
private static var imageCache = ImageCache()
static func getImageCache() -> ImageCache {
return imageCache
}
}
<代码>导入基础
导入快捷键
进口联合收割机
类UrlImageModel:ObservableObject{
@已发布的var图像:UIImage?
私有变量url:url?
私有var可取消:任何可取消?
private var imageCache=imageCache.getImageCache()
初始化(url:url?){
self.url=url
loadImage()
}
func loadImage(){
如果loadImageFromCache(){
打印(“缓存命中”)
返回
}
打印(“缓存丢失,从url加载”)
loadImageFromUrl()
}
func loadImageFromCache()->Bool{
guard let url=url else{
返回错误
}
guard let cacheImage=imageCache[url]else{
返回错误
}
image=cacheImage
返回真值
}
func loadImageFromUrl(){
guard let url=url else{
返回
}
Cancelable=URLSession.shared.dataTaskPublisher(for:url)
.map{UIImage(数据:$0.data)}
.replaceError(带:nil)
//将图像设置为缓存!
.handleEvents(接收输出:{[unowned self]图像在
guard let image=image else{return}
self.imageCache[url]=图像
})
.receive(在:DispatchQueue.main上)
.assign(到:\.image,在:self上)
}
}
类ImageCache{
var cache=NSCache()
下标(ukey:URL)->UIImage{
获取{cache.object(forKey:key作为NSURL)}
set{newValue==nil?cache.removeObject(forKey:key作为NSURL):cache.setObject(newValue!,forKey:key作为NSURL)}
}
}
扩展映像缓存{
私有静态变量imageCache=imageCache()
静态函数getImageCache()->ImageCache{
返回图像缓存
}
}
import Foundation
import SwiftUI
import Combine
class UrlImageModel: ObservableObject {
@Published var image: UIImage?
private var url: URL?
private var cancellable: AnyCancellable?
private var imageCache = ImageCache.getImageCache()
init(url: URL?) {
self.url = url
loadImage()
}
func loadImage() {
if loadImageFromCache() {
print("Cache hit")
return
}
print("Cache missing, loading from url")
loadImageFromUrl()
}
func loadImageFromCache() -> Bool {
guard let url = url else {
return false
}
guard let cacheImage = imageCache[url] else {
return false
}
image = cacheImage
return true
}
func loadImageFromUrl() {
guard let url = url else {
return
}
cancellable = URLSession.shared.dataTaskPublisher(for: url)
.map { UIImage(data: $0.data) }
.replaceError(with: nil)
// set image into cache!
.handleEvents(receiveOutput: { [unowned self] image in
guard let image = image else {return}
self.imageCache[url] = image
})
.receive(on: DispatchQueue.main)
.assign(to: \.image, on: self)
}
}
class ImageCache {
var cache = NSCache<NSURL, UIImage>()
subscript(_ key: URL) -> UIImage? {
get { cache.object(forKey: key as NSURL) }
set { newValue == nil ? cache.removeObject(forKey: key as NSURL) : cache.setObject(newValue!, forKey: key as NSURL) }
}
}
extension ImageCache {
private static var imageCache = ImageCache()
static func getImageCache() -> ImageCache {
return imageCache
}
}