Search code examples
iosswiftrx-swiftreactiverx-cocoa

Value of type * has no member 'rx'


I'm trying to make a small reactive wrapper for ImageDownloader from AlamofireImage:

import Foundation
import UIKit.UIImage
import AlamofireImage
import RxCocoa
import RxSwift


extension Reactive where Base: ImageDownloader {

    public func download(urlRequest: URLRequest, filter: ImageFilter?) -> Observable<UIImage> {

        return Observable.create { observer in

            self.base.download(urlRequest, filter: filter) { response in

                if let error = response.error {
                    observer.onError(error)
                } else if let image = response.value {
                    observer.onNext(image)
                }
            }
            return Disposables.create()
        }
    }
}

It compiles without a problem. But when I try to call rx.download on an instance of ImageDownloader I get an error saying that there is no 'rx' extension there:

Value of type 'ImageDownloader' has no member 'rx' error

Any guesses why this is happening?


Solution

  • You need to conform to ReactiveCompatible protocol first and then you can use 'rx' in your downloadRequest call

    import AlamofireImage
    import RxSwift
    
    extension ImageDownloader: ReactiveCompatible {}
    
    extension Reactive where Base: ImageDownloader {
    
        public func download(urlRequest: URLRequest, filter: ImageFilter?) -> Observable<UIImage> {
    
            return Observable.create { observer in
                let requestReceipt = ImageDownloader.default.download(urlRequest, filter: filter) { response in
                    if let error = response.error {
                        observer.onError(error)
                    } else if let image = response.value {
                        observer.onNext(image)
                        observer.onCompleted()
                    }
                }
                return Disposables.create {
                   requestReceipt?.request.cancel()
                }
            }
        }
    }
    

    now you can call ImageDownloader.default.rx.download(urlRequest:filter:) method like below

    let imageRequest = URLRequest.init(url: URL(string: "https://imageserver.com/image/myimage.png")!)
    let imageObservable: Observable<UIImage> = ImageDownloader.default.rx.download(urlRequest: imageRequest, filter: nil)