代码之家  ›  专栏  ›  技术社区  ›  zhiwei

URLCache(CS193P分配6)

  •  1
  • zhiwei  · 技术社区  · 6 年前

    我现在正在斯坦福iOS Swift作业6中,其中一项必需的任务是使用URLCache在本地磁盘上缓存映像。在谷歌搜索了几天之后,我仍然不知道如何使用它。如果有人能给我指点一位好的导游,那将很有帮助!

    在试图理解官方文档之后,我的代码现在是这样的。官方文件没有我可以参考的示例代码,这对我没有帮助:(

    let urlCache = URLCache.shared
    

    所需的任务是设置缓存并指定大小限制。我尝试初始化URLCache并在参数中传递大小。它可以工作,但存储和获取缓存似乎不起作用。如果每次启动应用程序(或视图控制器)时都初始化URLCache,它不会忽略之前创建和存储的缓存吗?

    我想这个代码没有问题吧?从缓存读取数据

    if let cachedURLResponse = urlCache.cachedResponse(for: URLRequest(url: url)) {
        if let fetchedImage = UIImage(data: cachedURLResponse.data) {
            image = fetchedImage
        }
    }
    

    我无法将数据写入缓存

    urlCache.storeCachedResponse(CachedURLResponse(response: URLResponse(), data: imageData), for: URLRequest(url: url))
    

    如何正确初始化URLResponse?我研究了init方法,它还要求url作为参数传入。由于url也位于URLRequest()中,因此发现此异常。我做错了吗?

    非常感谢您的建议!

    1 回复  |  直到 6 年前
        1
  •  1
  •   David Steppenbeck    6 年前

    您可以通过使用URLSession请求图像数据,然后使用其完成处理程序中可用的数据和响应来使用URLCache,例如:

    import UIKit
    
    class GalleryCollectionViewController: UICollectionViewController, UICollectionViewDragDelegate, UICollectionViewDropDelegate, UICollectionViewDelegateFlowLayout {
    
     // MARK: - Model
    
     var gallery: Gallery?
    
     // MARK: - Properties
    
     private var cache = URLCache.shared
     private var session = URLSession(configuration: .default)
    
     override func viewDidLoad() {
        super.viewDidLoad()
        cache = URLCache(memoryCapacity: 100, diskCapacity: 100, diskPath: nil) // replace capacities with your own values
     }
    
     override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "GalleryCell", for: indexPath)
        if let galleryCell = cell as? GalleryCollectionViewCell {
            galleryCell.image = nil
            galleryCell.imageView.isHidden = true
            if let url = gallery?.images[indexPath.item].url {
                let request = URLRequest(url: url.imageURL) // imageURL from Utilities.swift of Stanford iOS course
                if let cachedResponse = cache.cachedResponse(for: request), let image = UIImage(data: cachedResponse.data) {
                    galleryCell.image = image
                    galleryCell.imageView.isHidden = false
                } else {
                    DispatchQueue.global(qos: .userInitiated).async { [weak self, weak galleryCell] in
                        let task = self?.session.dataTask(with: request) { (urlData, urlResponse, urlError) in
                            DispatchQueue.main.async {
                                if urlError != nil { print("Data request failed with error \(urlError!)") }
                                if let data = urlData, let image = UIImage(data: data) {
                                    if let response = urlResponse {
                                        self?.cache.storeCachedResponse(CachedURLResponse(response: response, data: data), for: request)
                                    }
                                    galleryCell?.image = image
                                } else {
                                    galleryCell?.image = UIImage(named: "placeholder")
                                }
                                galleryCell?.imageView.isHidden = false
                            }
                        }
                        task?.resume()
                    }
                }
            }
        }
        return cell
     }
    }