Home > Blockchain >  Does showing system image(SF symbols) use a networking call in Swift?
Does showing system image(SF symbols) use a networking call in Swift?

Time:10-19

I'm creating an application in ios where I load images from an api using a UITableView and UITableViewCell.

Since the UITableView reuses cells, old images were appearing when I scroll fast. In order to prevent this, I set a default image using a system image(SF symbols).

I also use a cache to store urls to images.

Everything works as it should but now I think of it I'm sending a network request to retrieve that systemImage each time which seems incredibly inefficient since I was using a cache in order to reduce the total network calls in the first place.

Is there way around this or is this a tradeoff I must make?

Code is below.

        //use default image from SF symbols
        let defaulticon = UIImage(systemName: "photo")?.withTintColor(.gray, renderingMode: .alwaysOriginal)
        DispatchQueue.main.async {
            cell.mealImage.image = defaulticon
        }
        
        
        guard cell.meal?.strMealThumb != nil else {
            print("Category Image doesn't exist")
            return
        }
        
        
        //use cache
        if let imageData = model.imagecache.object(forKey: cell.meal!.strMealThumb as NSString) {
            print("using cache")
            DispatchQueue.main.async {
                cell.mealImage.image = imageData
            }
            
        }
        
        else {
            let url = URL(string: cell.meal!.strMealThumb)
            
            let session = URLSession.shared.dataTask(with: url!) { data, response, error in
                
                if error == nil && data != nil {
                    
                    let image = UIImage(data: data!)
                    //self.model.imagecache[cell.meal!.strMealThumb] = image
                    self.model.imagecache.setObject(image!, forKey: cell.meal!.strMealThumb as NSString)
                    DispatchQueue.main.async {
                        cell.mealImage.image = image
                    }
            
                }
            }
            
            session.resume()
            
        }
        

    }

CodePudding user response:

Override prepareForReuse method in UITableViewCell and add code in this function to clean up unrequited data that could persist from previous usage of the cell. In your example assign the default image in this function to produce better result.

CodePudding user response:

You asked:

I set a default image using a system image(SF symbols).

...

Everything works as it should but now I think of it I'm sending a network request to retrieve that systemImage each time which seems incredibly inefficient since I was using a cache in order to reduce the total network calls in the first place.

No, UIImage(systemName:) does not make a network request. And it caches the image, itself, as the documentation says:

This method checks the system caches for an image with the specified name and returns the variant of that image that is best suited for the main screen. If a matching image object is not already in the cache, this method creates the image from the specified system symbol image. The system may purge cached image data at any time to free up memory. Purging occurs only for images that are in the cache but are not currently being used.

FWIW, you can empirically verify that this does not perform a network request disconnecting from the network and trying to use it. You will see it works fine, even when disconnected.


FWIW, there is a very small performance gain (less than a millisecond?) by keeping a reference to that tinted system image and reusing it, rather than fetching the cached system image and re-tinting it. But the performance improvement is negligible.

  • Related