swiftuiimageswift4nscache

How to put image to NSCache in Swift?


I make some code using swift 4 to load image from URL, but every time I add images to server, it took a lot of time to load it in colection view or table view. I want to try store it in NScache but i dont understand to do it. can anyone help me, I'm new in swift :(

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

Solution

  • You can use something like this:

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