如何在Swift的NSCache中放置图像?

时间:2019-05-07 14:14:36

标签: swift uiimage nscache

我使用Swift 4编写了一些代码来从URL加载图像。但是,每次将图像添加到服务器时,都需要花费大量时间才能将其加载到集合视图或表视图中。我想尝试将其存储在NSCache中,但是我不知道该怎么做。

@objc func loadPosts() {

    let url = URL(string: "http://someURL/Url.php")!

    var request = URLRequest(url: url)
    request.httpMethod = "POST"

    let body = "phomepost=\(homepost)"

    request.httpBody = body.data(using: String.Encoding.utf8)

    URLSession.shared.dataTask(with: request) { data, response, error in
        DispatchQueue.main.async(execute:  {
            if error == nil {
                do{
                    let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary

                    self.comments.removeAll(keepingCapacity: false)
                    self.images.removeAll(keepingCapacity: false)
                    self.collectionView?.reloadData()

                    guard let parseJSON = json else {
                        print("Error While Parsing")
                        return
                    }

                    guard let posts = parseJSON["posts"] as? [AnyObject] else {
                        print("Error while parseJSONing")

                        return
                    }
                    self.comments = posts.reversed()

                    for i in 0 ..< self.comments.count {
                        let path = self.comments[i]["path"] as? String

                        if !path!.isEmpty {
                            let url = NSURL(string: path!)!
                            let imageData = try? Data(contentsOf: url as URL)
                            let image = UIImage(data: imageData! as Data)!
                            self.images.append(image)

                        } else {
                            let image = UIImage()
                            self.images.append(image)
                        }
                    }
                    self.collectionView?.reloadData()
                    //print(posts.count)
                } catch {
                    print(error)
                }
            }else{
                print(error)
            }
        })
    }.resume()
}

2 个答案:

答案 0 :(得分:0)

您可以使用以下内容:

private let cache = NSCache<NSString, NSData>()
.....
func downloadImage(url: String, handler: @escaping(Data?, Error?) -> Void){
            let cacheID = NSString(string: url)

            if let cachedData = cache.object(forKey: cacheID) {
                handler((cachedData as Data), nil)
            }else{
                if let url = URL(string: url) {
                    let session = URLSession(configuration: urlSessionConfig)
                    var request = URLRequest(url: url)
                    request.cachePolicy = .returnCacheDataElseLoad
                    request.httpMethod = "get"
                    session.dataTask(with: request) { (data, response, error) in
                        if let _data = data {
                            self.cache.setObject(_data as NSData, forKey: cacheID)
                            handler(_data, nil)
                        }else{
                            handler(nil, error)
                        }
                        }.resume()
                } else {
                    // NetworkError is a custom error
                    handler(nil, NetworkError.invalidURL)
                }
            }
        }
    }

答案 1 :(得分:0)

这将在使用图像集加载时添加一个小的动画。

let imageCache = NSCache<AnyObject, AnyObject>()
extension UIImageView {

    func loadImageFromUrl(urlString: String)  {

        let loader1 = UIImage(named: "loaderImage1.png")
        let loader2 = UIImage(named: "loaderImage2.png")
        let loader3 = UIImage(named: "loaderImage3.png")
        let imageArray = [loader1, loader2, loader3]
        let animatedImage = UIImage.animatedImage(with: imageArray as! [UIImage], duration: 1.7)

        if let imageFromCache = imageCache.object(forKey: urlString as AnyObject) as? UIImage{
            self.image = imageFromCache
            return
        } else {
            self.image = animatedImage
            Alamofire.request(urlString, method: .get).response { (responseData) in
                       if let data = responseData.data {
                           DispatchQueue.main.async {
                               if let imageToCache = UIImage(data: data){
                                   imageCache.setObject(imageToCache, forKey: urlString as AnyObject)
                                   self.image = imageToCache
                               }
                           }
                       }
                   } //alamofire
        }
    }

}