10
10
import Combine
11
11
import SwiftUI
12
12
13
- public struct RemoteImage < ErrorView: View , ImageView: View , LoadingView: View > : View {
13
+ /// A custom Image view for remote images with support for a loading and error state.
14
+ public struct RemoteImage < ErrorView: View , ImageView: View , LoadingView: View , Service: RemoteImageService > : View {
14
15
private let type : RemoteImageType
15
16
private let errorView : ( Error ) -> ErrorView
16
17
private let imageView : ( Image ) -> ImageView
17
18
private let loadingView : ( ) -> LoadingView
18
19
19
- @ObservedObject private var service = RemoteImageServiceFactory . makeRemoteImageService ( )
20
+ @ObservedObject private var service : Service
20
21
21
22
public var body : some View {
22
23
switch service. state {
@@ -33,11 +34,42 @@ public struct RemoteImage<ErrorView: View, ImageView: View, LoadingView: View>:
33
34
}
34
35
}
35
36
36
- public init ( type: RemoteImageType , @ViewBuilder errorView: @escaping ( Error ) -> ErrorView , @ViewBuilder imageView: @escaping ( Image ) -> ImageView , @ViewBuilder loadingView: @escaping ( ) -> LoadingView ) {
37
+ /// Initializes the view with the given values, especially with a custom `RemoteImageService`.
38
+ ///
39
+ /// - Parameters:
40
+ /// - type: Specifies the source type of the remote image. Choose between `.url` or `.phAsset`.
41
+ /// - service: An object conforming to the `RemoteImageService` protocol. Responsible for fetching the image and managing the state.
42
+ /// - errorView: A view builder used to create the view displayed in the error state.
43
+ /// - imageView: A view builder used to create the `Image` displayed in the image state.
44
+ /// - loadingView: A view builder used to create the view displayed in the loading state.
45
+ public init ( type: RemoteImageType , service: Service , @ViewBuilder errorView: @escaping ( Error ) -> ErrorView , @ViewBuilder imageView: @escaping ( Image ) -> ImageView , @ViewBuilder loadingView: @escaping ( ) -> LoadingView ) {
37
46
self . type = type
38
47
self . errorView = errorView
39
48
self . imageView = imageView
40
49
self . loadingView = loadingView
50
+ _service = ObservedObject ( wrappedValue: service)
51
+
52
+ service. fetchImage ( ofType: type)
53
+ }
54
+ }
55
+
56
+ extension RemoteImage where Service == DefaultRemoteImageService {
57
+ /// Initializes the view with the given values. Uses the built-in `DefaultRemoteImageService`.
58
+ ///
59
+ /// - Parameters:
60
+ /// - type: Specifies the source type of the remote image. Choose between `.url` or `.phAsset`.
61
+ /// - remoteImageURLDataPublisher: An object conforming to the `RemoteImageURLDataPublisher` protocol, by default `URLSession.shared` is used.
62
+ /// - errorView: A view builder used to create the view displayed in the error state.
63
+ /// - imageView: A view builder used to create the `Image` displayed in the image state.
64
+ /// - loadingView: A view builder used to create the view displayed in the loading state.
65
+ public init ( type: RemoteImageType , remoteImageURLDataPublisher: RemoteImageURLDataPublisher = URLSession . shared, @ViewBuilder errorView: @escaping ( Error ) -> ErrorView , @ViewBuilder imageView: @escaping ( Image ) -> ImageView , @ViewBuilder loadingView: @escaping ( ) -> LoadingView ) {
66
+ self . type = type
67
+ self . errorView = errorView
68
+ self . imageView = imageView
69
+ self . loadingView = loadingView
70
+
71
+ let service = DefaultRemoteImageServiceFactory . makeDefaultRemoteImageService ( remoteImageURLDataPublisher: remoteImageURLDataPublisher)
72
+ _service = ObservedObject ( wrappedValue: service)
41
73
42
74
service. fetchImage ( ofType: type)
43
75
}
0 commit comments