Skip to content
This repository has been archived by the owner on Dec 15, 2024. It is now read-only.

Provide / document an API to download images, outside of a SwiftUI context #70

Open
alexd6631 opened this issue May 12, 2020 · 13 comments
Assignees
Labels
enhancement New feature or request

Comments

@alexd6631
Copy link

alexd6631 commented May 12, 2020

I am using URL Image in a Swift UI project, and I would like to reuse the downloading/caching logic of URL Image, but outside a SwiftUI hierarchy.

My specific use case is to create an attachment for a local notification, and it only accepts on-disk file URLs. Since these images are profile pictures and likely to be already in URLImage cache, it makes sense to reuse the cache.

Digging inside the code source, it appears it should be possible by using directly DownloadService, but :
1/ It is not clear if this API is public, or used internally for separting concerns and may be subject to evolution
2/ The API feel a bit low level, for instance it is not clear what fileIdentifier should be by default, or why a separated addHandler/load is necessary, so it maybe interesting to put a facade in URLImageService to make simple calls like :

URLImageService.load(url) { image, err in ... }

A way to get the local file path/URL, maybe as an additional parameter of the above closure, would be very helpful in my case.

@alexd6631 alexd6631 added the enhancement New feature or request label May 12, 2020
@Leinadzet
Copy link

This! +1

@Vercisor
Copy link

This would be awesome!

@dmytro-anokhin
Copy link
Owner

Hey, this is not trivial because data logic is tightly coupled with image decoding. But I'm working on next version of the package and it will allow download/use cached images without view part. I hope to share updates soon.

@Leinadzet
Copy link

Thx for the hard work!

@dmytro-anokhin
Copy link
Owner

Version 2.0 uses new structure that allows me to implement this feature. I will keep this issue updated.

@godefroydlb
Copy link

You all work is really nice.
I am stuck trying to implement image download outside a view using "URLImageService.shared.makeRemoteImage".
It would be very nice to have some working example of this use case

@dmytro-anokhin
Copy link
Owner

Hey, sure, you can write a helper function like this: https://gist.github.com/dmytro-anokhin/51aaeecb03a4e8249d7783cc5c60cb3b

@godefroydlb
Copy link

godefroydlb commented Jan 12, 2021 via email

@dmytro-anokhin
Copy link
Owner

Replied in the gist, not to create noise here.

@dmytro-anokhin
Copy link
Owner

Hey there, I added RemoteImagePublisher in 2.2.1 that allows to use Combine for downloading or retrieving images. The output is ImageInfo object. You can use it to get CGImage like this:

cancellable = URLImageService.shared.remoteImagePublisher(url)
            .tryMap { $0.cgImage }
            .sink(receiveCompletion: { _ in }, receiveValue: { image in
                print(image)
            })

Documentation coming soon. Cheers.

@dmytro-anokhin
Copy link
Owner

Hey,

I know this issue is long overdue, but I was struggling to come up with a nice API that won't overcomplicate the package. Finally, I think I got there 🙂

In 2.2.1 there is a new publisher added to the package: RemoteImagePublisher. It encapsulates all necessary operations to fetch an image. Because under the hood it uses the same objects as URLImage view it will behave in the same manner, use the same cache, and return cached image if available.

Here is documentation, and some examples how to use it: https://github.com/dmytro-anokhin/url-image#fetching-an-image

Please let me know if there is something else that I miss/you expect. Otherwise I will close this issue soon.

Cheers.

@filipkrayem
Copy link

filipkrayem commented Jun 9, 2021

Hi @dmytro-anokhin, the documentation seems to be outdated and the code samples do not work. Could you please update the documentation and the example?

For example, URLImageService does not have a shared property, and the exposed RemoteImagePublisher is the struct that accepts self as an argument, as opposed to the expected function. Is the RemoteImagePublisher struct even supposed to be public?

I've been able to access the remoteImagePublisher function through @Environment(\.urlImageService) var service: URLImageService, but that's not clearly specified and the code snippet implies you're supposed to use URLImageService and not the environment value.

Also, I think it's worth mentioning that the Just struct needs to be imported from Combine.

The code also never seems to get to the sink stage. I'm pretty new to Swift and never dealt with concurrency, so maybe I'm doing something wrong?

let cancellable = service.remoteImagePublisher(photoUrls.full, identifier: "image")
            .tryMap { $0.cgImage }
            .catch { _ in
                Just(nil)
            }
            .sink { image in
                print("sink") // never prints
                myCGImage = image
            }

Hope you're doing well. Thanks

@dmytro-anokhin
Copy link
Owner

Hey @FilipK999, thanks for bringing up. shared service is indeed gone (maybe I should resurrect it 🤔). This is because it is up to the app to setup the service that fits the purpose. While I'm updating the documentations, you can use ImageDownloader sample code here: https://github.com/dmytro-anokhin/url-image-demo. Hope this helps.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

6 participants