Skip to content

Instantly share code, notes, and snippets.

@alexito4
Last active August 19, 2020 15:32
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save alexito4/59436b9ab0489b00fb137a8382f38ea5 to your computer and use it in GitHub Desktop.
Save alexito4/59436b9ab0489b00fb137a8382f38ea5 to your computer and use it in GitHub Desktop.
Rough sketch of SwiftUI RemoteImage using AlamofireImage
import SwiftUI
import Combine
import AlamofireImage
let imageDownloader = ImageDownloader(
configuration: ImageDownloader.defaultURLSessionConfiguration(),
downloadPrioritization: .fifo,
maximumActiveDownloads: 4,
imageCache: AutoPurgingImageCache()
)
extension ImageDownloader {
func image(for url: URL) -> AnyPublisher<UIImage?, Never> {
return Publishers.Future { subscriber in
let urlRequest = URLRequest(url: url)
imageDownloader.download(urlRequest) { response in
if let image = response.result.value {
subscriber(.success(image))
}
}
}
.eraseToAnyPublisher()
}
}
struct RemoteImage: View {
// let placeholder = UIImage(named: "placeholder.jpg")!
let url: URL
init(url: URL) {
print("RemoteImage created \(url)")
self.url = url
}
@State private var image: UIImage? = nil
var body: some View {
Group {
if image != nil {
Image(uiImage: image!)
} else {
Image(systemName: "person.crop.circle")
}
}
.bind(imageDownloader.image(for: url), to: $image)
}
}
//#if DEBUG
//struct RemoteImage_Previews : PreviewProvider {
// static var previews: some View {
// RemoteImage()
// }
//}
//#endif
@alexito4
Copy link
Author

alexito4 commented Jun 8, 2019

@patchthecode
Copy link

fails to build on this line

.bind(imageDownloader.image(for: url), to: $image)

error

Protocol type 'Any' cannot conform to 'View' because only concrete types can conform to protocols

@sergdort
Copy link

sergdort commented Jun 16, 2019

bind is a convenience extension that I've created. The complete implementation can be found here

extension View {
    func bind<P: Publisher, Value>(
        _ publisher: P,
        to state: Binding<Value>
    ) -> SubscriptionView<P, Self> where P.Failure == Never, P.Output == Value {
        return onReceive(publisher) { value in
            state.value = value
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment