UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Cannot stop List from freezing when trying to load images

Forums > SwiftUI

In my app, I have a List which displays a view in each row, and these views try to download an image from the Internet. I am trying to stop the List from freezing while downloading the image. The app works great on a fast network, but I am having problems getting the download to happen in the background. I have tried using the .task(priority: .background) to load the image, but it does not work. I must not be understanding something, any help is appreciated. Here is my code for the view which needs to load the images. I have my downloading code in a shared object which the view calls. Not all of the items to display have the cover property so that it is why it is optional, and I display a default image if the cover is not present.

import SwiftUI
import CoreImage

struct CoverView: View {

    var cover: Int?
    var size: String
    var height: Double
    @State private var tempImage: UIImage?
    @State private var uiImage: UIImage?
    @State private var modifier1 = 0.62
    @State private var modifier2 = 1.0

    @EnvironmentObject var downLoader: BookDownloader

    var body: some View {

        Group {
            if cover != nil {

                if let uiImage = uiImage {
                    Image(uiImage: uiImage)
                        .resizable()
                        .frame(width: height * modifier1, height: height * modifier2)
                } else {
                    ProgressView()
                } 

            }
        }
        .onChange(of: tempImage, perform: { newValue in
            uiImage = tempImage
        })
        .task(priority: .background) {

            if let cover = cover {

                    if cover > 0 {

                            tempImage =  await downLoader.getUIImageForCover(cover: cover, size: size)

                    } else {
                        tempImage = UIImage(systemName: "x.circle")
                        modifier1 = 0.5
                        modifier2 = 0.5
                    }
            }
        }
    }
}

This is the networking code in the downLoader object:

func getUIImageForCover(cover: Int, size: String) async -> UIImage? {

            let urlString = getCoverImageURLString(cover: cover, size: size)

            return await getUIImageForURLString(url: urlString)

    }

  private func getUIImageForURLString(url: String) async -> UIImage? {

        do {

            guard let urlToDownload = URL(string: url) else {
                assert(true, "URL failed")
                return nil
            }

            let data = try Data(contentsOf: urlToDownload)

            // stores the data in the book struct so it can be saved into a BookData ultimately

            book?.coverImageData = data

            if let uiImage = UIImage(data: data) {
                return uiImage
            }

        } catch {
            print(error.localizedDescription)
        }

        return nil
    }

  private func getCoverImageURLString(cover: Int, size: String)  -> String {
        // checks to make sure the size string is of the right type

        assert(size == "S" || size == "M" || size == "L", "Wrong size entered into getCoverImageURLString")

        let urlString =  "https://covers.openlibrary.org/b/id/\(cover)-\(size).jpg"

        return urlString

    }

2      

Have you tried using AsyncImage?

2      

I have not tried that I will do so. For a larger question, is it better to download the image once and store locally, or is it better to download on demand which may impact performance. The images are relatively small but there are a lot of them.

2      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.