SDWebImage / SDWebImageSwiftUI

SwiftUI Image loading and Animation framework powered by SDWebImage
https://sdwebimage.github.io/SDWebImageSwiftUI
MIT License
2.08k stars 214 forks source link

How to use Firebase Storage with SDWebImageSwiftUI #270

Open Xenolion opened 11 months ago

Xenolion commented 11 months ago

All my efforts to use firebase storage reference with SDWebImageSwiftUI do not work. import SwiftUI import FirebaseStorage import SDWebImage import SDWebImageSwiftUI import FirebaseStorageUI

I have imported all these but it does not work.

WebImage(url: imageReference)

How do I make this work?

dreampiggy commented 11 months ago

Emmmm...

You can use the category on FirebaseStorage to create URL from FIRStorageReference ?

Xenolion commented 11 months ago

I am talking about import FirebaseStorageUI. I wanted to go for the option to load an Image directly from Reference like how its done in SDWebImage(the version without swuftui). @dreampiggy

dreampiggy commented 11 months ago

You can check that FirebaseUI implementation (open-sourced), it create a special NSURL by wrapping the FIRStorageReference (which is the unit of FirebaseStorage)

So, I guess if you can create that special NSURL and feed into WebImage, it will get the same effect.

I have no demo code here, any usable demo ?

dreampiggy commented 11 months ago

The magic happens here: https://github.com/firebase/FirebaseUI-iOS/blob/master/FirebaseStorageUI/Sources/NSURL%2BFirebaseStorage.m

So, if in Swift you can call to create this sd_URLWithStorageReference:, then it will work

dreampiggy commented 11 months ago

This sd_URLWithStorageReference: is public API, so it can be called from Swift side: https://github.com/firebase/FirebaseUI-iOS/blob/master/FirebaseStorageUI/Sources/Public/FirebaseStorageUI/NSURL%2BFirebaseStorage.h

dreampiggy commented 11 months ago

To say, this ugly design can be changed in SDWebImage 6.0. We can load a thing which is not NSURL * but something conforms to protocol, so that it can generalize the usage like this :(

public protocol SDImageResource : NSObjectProtocol {
    public var url: URL { get }
    public var cacheKey: String { get }
}

public struct WebImage {
    public init(_ resource: SDImageResource)
}
Xenolion commented 11 months ago

Do I don't understand should I create an exact copy of that? I am using SwiftUI copying the method does not work as well.

Xenolion commented 11 months ago

I dont think I understand. Look it still gives an error

WebImage(url: sd_URLWithStorageReference(imageReference))

Xenolion commented 11 months ago

The code above still throws Cannot find 'sd_URLWithStorageReference' in scope @dreampiggy

Xenolion commented 11 months ago

I have got to try this if it works in this case: func toUrl(_ reference: StorageReference) -> URL? { let url = NSURL.sd_URL(withStorageReference: reference) as URL? print("URL is : \(String(describing: url))") return url }

Xenolion commented 11 months ago

Even the method above throws an error: Task <5B5CBD27-B0DC-4D9B-A50B-1A3354CEE9DF>.<2> finished with error [-1002] Error Domain=NSURLErrorDomain Code=-1002 "unsupported URL" UserInfo={NSLocalizedDescription=unsupported URL, NSErrorFailingURLStringKey=gs://comcha-posts/uzXc4oMdKQ5pKI3MTX87/8higbpn7elJpru3KOKlB/wlB9wr4nIhPcxaqK8zWM.png, NSErrorFailingURLKey=gs://bucket-posts/uzXc4oMdKQ5pKI3MTX87/8higbpn7elJpru3KOKlB/wlB9wr4nIhPcxaqK8zWM.png, _NSURLErrorRelatedURLSessionTaskErrorKey=( "LocalDataTask <5B5CBD27-B0DC-4D9B-A50B-1A3354CEE9DF>.<2>" ), _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <5B5CBD27-B0DC-4D9B-A50B-1A3354CEE9DF>.<2>, NSUnderlyingError=0x2835d9f80 {Error Domain=kCFErrorDomainCFNetwork Code=-1002 "(null)"}}

dreampiggy commented 11 months ago

Even the method above throws an error: Task <5B5CBD27-B0DC-4D9B-A50B-1A3354CEE9DF>.<2> finished with error [-1002] Error Domain=NSURLErrorDomain Code=-1002 "unsupported URL" UserInfo={NSLocalizedDescription=unsupported URL, NSErrorFailingURLStringKey=gs://comcha-posts/uzXc4oMdKQ5pKI3MTX87/8higbpn7elJpru3KOKlB/wlB9wr4nIhPcxaqK8zWM.png, NSErrorFailingURLKey=gs://bucket-posts/uzXc4oMdKQ5pKI3MTX87/8higbpn7elJpru3KOKlB/wlB9wr4nIhPcxaqK8zWM.png, _NSURLErrorRelatedURLSessionTaskErrorKey=( "LocalDataTask <5B5CBD27-B0DC-4D9B-A50B-1A3354CEE9DF>.<2>" ), _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <5B5CBD27-B0DC-4D9B-A50B-1A3354CEE9DF>.<2>, NSUnderlyingError=0x2835d9f80 {Error Domain=kCFErrorDomainCFNetwork Code=-1002 "(null)"}}

I think that you don't setup the FirebaseStorageUI correcly. Seems you use that special wrapper NSURL and use URLSession to load that, but it's not a HTTP URL so URLSession will fail.

Which actually, should use FirebaseStorage's Loader instead, which means, the custom loader feature from SDWebImage: https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#custom-loader-50

API: https://sdwebimage.github.io/documentation/sdwebimage/sdwebimagecontextoption/imageloader

dreampiggy commented 11 months ago

Give me an example ? So I can test it as well.

From the docs, maybe you need something like:

WebImage(url: CreateURLFromFirebaseStoragreReference(),
  options: 0,
  context: [.imageLoader: StorageImageLoader.shared])

See the readme in FirebaseStorageUI, you can also setup the global loaders manger like this, so you don't need speciay .context param each time you need. It will support both HTTP URL or FirebaseStorage URL :

let loader1 = SDWebImageDownloader.shared
let loader2 = StorageImageLoader.shared
SDImageLoadersManager.shared.loaders = [loader1, loader2]

// Assign loader to manager
let manager = SDWebImageManager(cache: SDImageCache.shared, loader: SDImageLoadersManager.shared)
// Start use

// If you want to assign loader to default manager, use `defaultImageLoader` class property before shared manager initialized
SDWebImageManager.defaultImageLoader = SDImageLoadersManager.shared