lorenzofiamingo / swiftui-cached-async-image

CachedAsyncImage is the simplest way to add cache to your AsyncImage.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

No macOS Support

caoimhebyrne opened this issue · comments

When trying to use this dependency under macOS, the project fails to build.
image

Checkout the new release. Can you tell me if it works, I don't have the possibility to test on macOS 12, thanks!

Yeah sure

I'm experiencing some weird behaviour in a List. When the view is first initialised, it will load fine. After I scroll down a few elements, a few of them seem to disappear and get stuck in an endless loading state. (my internet is bad however, so this 'endless loading' could just be it ignoring the cache for some reason)

This issue does not seem to appear on iOS.

Screen.Recording.2021-10-30.at.10.57.15.mov

Sometimes, it shows the image initially, but then decides to go into that loading state for all of them after scrolling a small bit
image

That being said, it appears to work perfectly outside of lists.
image

Very strange that iOS and macOS behave differently, the only thing that comes to mind is that URLCache.shared has maybe different sizes between iOS and macOS. Try using a custom URLCache (remembering this discussion):

CachedAsyncImage(url: logoURL, urlCache: .imageCache)
// URLCache+imageCache.swift

extension URLCache {
    
    static let imageCache = URLCache(memoryCapacity: 512*1000*1000, diskCapacity: 10*1000*1000*1000)
}

Can I see the code you are using for the List?

Sure, here @lorenzofiamingo:
image
image

Also Track please :)

@lorenzofiamingo Track.swift:

class Track: ObservableObject, Equatable, Identifiable {
    static func == (lhs: Track, rhs: Track) -> Bool {
        return lhs.name == rhs.name && lhs.artist == rhs.artist && lhs.albumArt == rhs.albumArt && lhs.playing == rhs.playing
    }

    @Published var name: String
    @Published var artist: String
    @Published var albumArt: URL?
    @Published var playing: Bool

    init(name: String, artist: String, albumArt: URL?, playing: Bool) {
        self.name = name
        self.artist = artist
        self.albumArt = albumArt
        self.playing = playing
    }
}

The problem could be in the way you have implemented Identifiable, the task is linked to the view and the view is linked to the list by the ID of the tracks, so it could happen that multiple tasks are launched with the same ID and in this way they are overwritten before being completed.

Try adding to Task this: "var id: UUID { .init() }" and see if it works.

In any case, I recommend that you make Track a struct. In SwiftUI the best practice is to make your models value-type. What manages them (ViewModels) instead classes or actors.

Alright, I'll try that now

It doesn't seem to resolve the problem. I can't make Track a struct since I am inheriting ObservableObject.

image

After a bit of refactoring, it appears to be working now

However, when my list updates, it appears to break again. I need to look into this further, it's probably my problem.

Alright, I have solved the problem. Thank you.

@cbyrneee What was the problem?

@lorenzofiamingo my view was being updated too many times, presumably causing the URLCache / URLSession to get backlogged

commented

@cbyrneee how you fix URLSession?