NukeUI icon indicating copy to clipboard operation
NukeUI copied to clipboard

Randomly, image does not load

Open IssaMansour opened this issue 2 years ago • 12 comments

While loading a list of images, sometimes, randomly, the image does not load. If you restart, after few times, it works.

Console logs: Task <72B7A449-92F7-41E1-AB00-5A2D634E541B>.<9> finished with error [303] Error Domain=kCFErrorDomainCFNetwork Code=303 "(null)" UserInfo={_NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <72B7A449-92F7-41E1-AB00-5A2D634E541B>.<9>, _kCFStreamErrorDomainKey=4, NSErrorPeerAddressKey=<CFData 0x60000086caf0 [0x1da82daf0]>{length = 16, capacity = 16, bytes = 0x100201bbd15e5a010000000000000000}, _kCFStreamErrorCodeKey=-2201, _NSURLErrorRelatedURLSessionTaskErrorKey=( "LocalDataTask <72B7A449-92F7-41E1-AB00-5A2D634E541B>.<9>" )}

Used with: LazyImage(source: imageUrl, resizingMode: .aspectFit) .frame(maxWidth: .infinity, maxHeight: .infinity) .aspectRatio(contentMode: .fit)

Any idea?

IssaMansour avatar Jan 29 '22 00:01 IssaMansour

Hey, is that with the latest version? Do you know how to repro?

kean avatar Feb 04 '22 04:02 kean

Hey, is that with the latest version? Do you know how to repro?

Hey, just saw the new 0.8.0 version. I was using 0.7.0. I'll try it and will let you know after my tests.

IssaMansour avatar Feb 04 '22 04:02 IssaMansour

Hi Alexander, same here. I'm using 0.8.0 for now but previously I faced up with this issue in 0.6.4 The link im using is https://firebasestorage.googleapis.com:443/v0/b/credo-30c8f.appspot.com/o/profiles%2Fi6hgdoeqZHRkjxkmuQ6abGVxqFs2.jpg?alt=media&token=948a7719-1094-4a95-9ba4-8c426c46dd9e

Screenshot 2022-02-04 at 05 35 16

Sunspension avatar Feb 04 '22 10:02 Sunspension

I have been seeing this as well with 0.8.0. I think it has only been happening since the macOS 12.2 or 12.3 update though.

drewdeponte avatar Mar 29 '22 04:03 drewdeponte

Reproducing on macOS 12.4, latest Nuke/NukeUI

aehlke avatar Jul 05 '22 02:07 aehlke

I'm not sure if these are the same errors.

In the original issue, the error code is kCFErrorDomainCFNetwork Code=303 which says "The HTTP server response couldn’t be parsed". It might be related to HTTP range requests that are enabled by default. I suggest trying to disable it. Maybe the server doesn't work well with chucked requests.

For this URL https://firebasestorage.googleapis.com:443/v0/b/credo-30c8f.appspot.com/o/profiles%2Fi6hgdoeqZHRkjxkmuQ6abGVxqFs2.jpg?alt=media&token=948a7719-1094-4a95-9ba4-8c426c46dd9e, I can't reproduce the issue.

kean avatar Jul 05 '22 12:07 kean

I dug into this and found a work around and believe I know why this behavior is happening in Lists on macOS. It is because the behavior of SwiftUI and the fact that the onAppear, onDisappear life-cycle methods seem to no longer be called at the same point as they used to on macOS since 12.2 or 12.3. Anyways, the following is a description from my commit where I worked around this issue. I hope it helps.

Fix avatars not loading issue

Fix the avatars not loading issue when scrolling in the main view. I did this so that people wouldn't have to deal with this issue anymore as avatars are super valuable to quickly be able to scan and see users.

After digging in I discovered that that the onAppear, onDisappear life-cycle methods weren't getting called as I expected and this was causing problems because the loading of the avatars was tied to the onAppear of the view. So to resolve this I moved the creation of the Nuke FetchImage objects out into an AvatarFetchImageManager which handles the creation of FetchImage objects and triggering the loading as well as cacheing the FetchImage objects based on URL so that we can reuse the same FetchImage object everywhere for the same avatar url. Once I had the AvatarFetchImageManager then I was able to modify all the avatar views to accept a fetchImage as an observable object so that if it changed states it would trigger a rebuild of the view while leaving ownership of the object outside of the view. This has seemed to resolve the problem and also improve performance thanks to the caching as it is no longer creating a new FetchImage instance everytime the view is created.

drewdeponte avatar Jul 05 '22 14:07 drewdeponte

Thank you for finding and sharing that! I've had to switch to Kingfisher (CachedAsyncImage was also buggy on macOS)

aehlke avatar Jul 05 '22 15:07 aehlke

Great, I'll create a sample and try to reproduce it. Thanks for the tip about the onAppear callbacks.

P.S. It's pretty hard to create reusable components in SwiftUI that work reliably on all platforms.

kean avatar Jul 05 '22 19:07 kean

Yeah, I am not sure actually with SwiftUI what the best way to address this particular issue is. It seems like if the onAppear event doesn't fire as it used to anymore then we can't really use that.

My workaround was to just avoid that all together. It seems like without that event the only option that exists is to have the state driven from outside of the reusable component unless I am missing something.

drewdeponte avatar Jul 06 '22 14:07 drewdeponte

I made a small sample with a List and can't reproduce it on macOS 12.4. Maybe there is something else in your view hierarchy that causes it.

kean avatar Jul 10 '22 19:07 kean

I am not sure what your example looks like but I had a list of views each of which had the following as a child view.

struct AvatarView: SwiftUI.View {
    let avatarURL: URL?

    LazyImage(source: avatarURL)
                    .aspectRatio(contentMode: .fill)
                    .clipShape(Circle())
                    .frame(width: 45, height: 45)
                    .padding(.trailing, 8)
}

I was then using this in the parenting view as follows.

        return HStack(alignment: .top, spacing: 0) {
            AvatarView(avatarURL: pullRequestViewModel.pullRequest.avatarUrl)
            ...

Hopefully that helps a bit.

drewdeponte avatar Jul 11 '22 14:07 drewdeponte