diff --git a/Examples/Demo/Demo/ImageProvidersView.swift b/Examples/Demo/Demo/ImageProvidersView.swift index e3547614..80f5ee26 100644 --- a/Examples/Demo/Demo/ImageProvidersView.swift +++ b/Examples/Demo/Demo/ImageProvidersView.swift @@ -1,6 +1,8 @@ import MarkdownUI import SDWebImageSwiftUI import SwiftUI +import ImageProviders +import NetworkImageProvider struct ImageProvidersView: View { private let content = """ diff --git a/Examples/Demo/Demo/ImagesView.swift b/Examples/Demo/Demo/ImagesView.swift index 3b8fab36..9d690aa0 100644 --- a/Examples/Demo/Demo/ImagesView.swift +++ b/Examples/Demo/Demo/ImagesView.swift @@ -1,5 +1,7 @@ import MarkdownUI import SwiftUI +import ImageProviders +import NetworkImageProvider struct ImagesView: View { private let content = """ diff --git a/Examples/Demo/Demo/LazyLoadingView.swift b/Examples/Demo/Demo/LazyLoadingView.swift index c234d59f..c3324ddc 100644 --- a/Examples/Demo/Demo/LazyLoadingView.swift +++ b/Examples/Demo/Demo/LazyLoadingView.swift @@ -1,3 +1,4 @@ +import ImageProviders import MarkdownUI import SwiftUI diff --git a/Package.swift b/Package.swift index 5fb61bc9..b39af529 100644 --- a/Package.swift +++ b/Package.swift @@ -15,6 +15,14 @@ let package = Package( .library( name: "MarkdownUI", targets: ["MarkdownUI"] + ), + .library( + name: "ImageProviders", + targets: ["ImageProviders"] + ), + .library( + name: "NetworkImageProvider", + targets: ["NetworkImageProvider"] ) ], dependencies: [ @@ -26,9 +34,21 @@ let package = Package( .target( name: "MarkdownUI", dependencies: [ + "ImageProviders", + "NetworkImageProvider", .product(name: "cmark-gfm", package: "swift-cmark"), .product(name: "cmark-gfm-extensions", package: "swift-cmark"), - .product(name: "NetworkImage", package: "NetworkImage"), + ] + ), + .target( + name: "ImageProviders", + dependencies: [] + ), + .target( + name: "NetworkImageProvider", + dependencies: [ + "ImageProviders", + .product(name: "NetworkImage", package: "NetworkImage") ] ), .testTarget( diff --git a/Sources/MarkdownUI/Extensibility/AssetImageProvider.swift b/Sources/ImageProviders/AssetImageProvider.swift similarity index 100% rename from Sources/MarkdownUI/Extensibility/AssetImageProvider.swift rename to Sources/ImageProviders/AssetImageProvider.swift diff --git a/Sources/MarkdownUI/Extensibility/AssetInlineImageProvider.swift b/Sources/ImageProviders/AssetInlineImageProvider.swift similarity index 100% rename from Sources/MarkdownUI/Extensibility/AssetInlineImageProvider.swift rename to Sources/ImageProviders/AssetInlineImageProvider.swift diff --git a/Sources/MarkdownUI/Extensibility/ImageProvider.swift b/Sources/ImageProviders/ImageProvider.swift similarity index 87% rename from Sources/MarkdownUI/Extensibility/ImageProvider.swift rename to Sources/ImageProviders/ImageProvider.swift index 937319b2..d64e61c1 100644 --- a/Sources/MarkdownUI/Extensibility/ImageProvider.swift +++ b/Sources/ImageProviders/ImageProvider.swift @@ -26,16 +26,16 @@ public protocol ImageProvider { @ViewBuilder func makeImage(url: URL?) -> Body } -struct AnyImageProvider: ImageProvider { +public struct AnyImageProvider: ImageProvider { private let _makeImage: (URL?) -> AnyView - init(_ imageProvider: I) { + public init(_ imageProvider: I) { self._makeImage = { AnyView(imageProvider.makeImage(url: $0)) } } - func makeImage(url: URL?) -> some View { + public func makeImage(url: URL?) -> some View { self._makeImage(url) } -} +} diff --git a/Sources/ImageProviders/InlineImageProvider.swift b/Sources/ImageProviders/InlineImageProvider.swift new file mode 100644 index 00000000..020fdf8b --- /dev/null +++ b/Sources/ImageProviders/InlineImageProvider.swift @@ -0,0 +1,14 @@ +import SwiftUI + +/// A type that provides an image for an inline image in a Markdown view. +/// +/// To configure the current inline image provider for a view hierarchy, +/// use the `markdownInlineImageProvider(_:)` modifier. +public protocol InlineImageProvider { + /// Returns an image for the given URL and label. + /// + /// - Parameters: + /// - url: The URL of the image to load. + /// - label: The accessibility label for the image. + func image(with url: URL, label: String) async throws -> Image +} diff --git a/Sources/MarkdownUI/Utility/ResizeToFit.swift b/Sources/ImageProviders/Utils/ResizeToFit.swift similarity index 92% rename from Sources/MarkdownUI/Utility/ResizeToFit.swift rename to Sources/ImageProviders/Utils/ResizeToFit.swift index 4029ce06..122be052 100644 --- a/Sources/MarkdownUI/Utility/ResizeToFit.swift +++ b/Sources/ImageProviders/Utils/ResizeToFit.swift @@ -1,15 +1,15 @@ import SwiftUI -struct ResizeToFit: View where Content: View { +public struct ResizeToFit: View where Content: View { private let idealSize: CGSize private let content: Content - init(idealSize: CGSize, @ViewBuilder content: () -> Content) { + public init(idealSize: CGSize, @ViewBuilder content: () -> Content) { self.idealSize = idealSize self.content = content() } - var body: some View { + public var body: some View { if #available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, *) { ResizeToFit2 { self.content } } else { diff --git a/Sources/MarkdownUI/Extensibility/InlineImageProvider.swift b/Sources/MarkdownUI/Extensibility/InlineImageProvider.swift deleted file mode 100644 index 06bd9e1c..00000000 --- a/Sources/MarkdownUI/Extensibility/InlineImageProvider.swift +++ /dev/null @@ -1,16 +0,0 @@ -import SwiftUI - -/// A type that loads images that are displayed within a line of text. -/// -/// To configure the current inline image provider for a view hierarchy, -/// use the `markdownInlineImageProvider(_:)` modifier. -public protocol InlineImageProvider { - /// Returns an image for the given URL. - /// - /// ``Markdown`` views call this method to load images within a line of text. - /// - /// - Parameters: - /// - url: The URL of the image to display. - /// - label: The accessibility label associated with the image. - func image(with url: URL, label: String) async throws -> Image -} diff --git a/Sources/MarkdownUI/Utility/Deprecations.swift b/Sources/MarkdownUI/Utility/Deprecations.swift index 7a60dffa..55928644 100644 --- a/Sources/MarkdownUI/Utility/Deprecations.swift +++ b/Sources/MarkdownUI/Utility/Deprecations.swift @@ -1,21 +1,5 @@ import SwiftUI -// MARK: - Deprecated after 2.1.0: - -extension DefaultImageProvider { - @available(*, deprecated, message: "Use the 'default' static property") - public init(urlSession: URLSession = .shared) { - self.init() - } -} - -extension DefaultInlineImageProvider { - @available(*, deprecated, message: "Use the 'default' static property") - public init(urlSession: URLSession = .shared) { - self.init() - } -} - // MARK: - Deprecated after 2.0.2: extension BlockStyle where Configuration == BlockConfiguration { diff --git a/Sources/MarkdownUI/Views/Environment/Environment+ImageProvider.swift b/Sources/MarkdownUI/Views/Environment/Environment+ImageProvider.swift index 909f1e4f..d60f218c 100644 --- a/Sources/MarkdownUI/Views/Environment/Environment+ImageProvider.swift +++ b/Sources/MarkdownUI/Views/Environment/Environment+ImageProvider.swift @@ -1,4 +1,6 @@ import SwiftUI +import ImageProviders +import NetworkImageProvider extension View { /// Sets the image provider for the Markdown images in a view hierarchy. diff --git a/Sources/MarkdownUI/Views/Environment/Environment+InlineImageProvider.swift b/Sources/MarkdownUI/Views/Environment/Environment+InlineImageProvider.swift index fa1b5918..c75b48d2 100644 --- a/Sources/MarkdownUI/Views/Environment/Environment+InlineImageProvider.swift +++ b/Sources/MarkdownUI/Views/Environment/Environment+InlineImageProvider.swift @@ -1,4 +1,5 @@ import SwiftUI +import ImageProviders extension View { /// Sets the inline image provider for the Markdown inline images in a view hierarchy. diff --git a/Sources/MarkdownUI/Views/Inlines/ImageView.swift b/Sources/MarkdownUI/Views/Inlines/ImageView.swift index 90f97e0a..f24eec06 100644 --- a/Sources/MarkdownUI/Views/Inlines/ImageView.swift +++ b/Sources/MarkdownUI/Views/Inlines/ImageView.swift @@ -1,4 +1,5 @@ import SwiftUI +import ImageProviders struct ImageView: View { @Environment(\.theme.image) private var image diff --git a/Sources/MarkdownUI/Views/Inlines/InlineText.swift b/Sources/MarkdownUI/Views/Inlines/InlineText.swift index 9da39404..a68d5c27 100644 --- a/Sources/MarkdownUI/Views/Inlines/InlineText.swift +++ b/Sources/MarkdownUI/Views/Inlines/InlineText.swift @@ -1,4 +1,5 @@ import SwiftUI +import ImageProviders struct InlineText: View { @Environment(\.inlineImageProvider) private var inlineImageProvider diff --git a/Sources/MarkdownUI/Extensibility/DefaultImageProvider.swift b/Sources/NetworkImageProvider/DefaultImageProvider.swift similarity index 77% rename from Sources/MarkdownUI/Extensibility/DefaultImageProvider.swift rename to Sources/NetworkImageProvider/DefaultImageProvider.swift index cce0c086..bbe3261b 100644 --- a/Sources/MarkdownUI/Extensibility/DefaultImageProvider.swift +++ b/Sources/NetworkImageProvider/DefaultImageProvider.swift @@ -1,5 +1,6 @@ import NetworkImage import SwiftUI +import ImageProviders /// The default image provider, which loads images from the network. public struct DefaultImageProvider: ImageProvider { @@ -26,3 +27,12 @@ extension ImageProvider where Self == DefaultImageProvider { .init() } } + +// MARK: - Deprecated after 2.1.0: + +extension DefaultImageProvider { + @available(*, deprecated, message: "Use the 'default' static property") + public init(urlSession: URLSession = .shared) { + self.init() + } +} diff --git a/Sources/MarkdownUI/Extensibility/DefaultInlineImageProvider.swift b/Sources/NetworkImageProvider/DefaultInlineImageProvider.swift similarity index 74% rename from Sources/MarkdownUI/Extensibility/DefaultInlineImageProvider.swift rename to Sources/NetworkImageProvider/DefaultInlineImageProvider.swift index a4a266d1..5b8a156d 100644 --- a/Sources/MarkdownUI/Extensibility/DefaultInlineImageProvider.swift +++ b/Sources/NetworkImageProvider/DefaultInlineImageProvider.swift @@ -1,5 +1,6 @@ import NetworkImage import SwiftUI +import ImageProviders /// The default inline image provider, which loads images from the network. public struct DefaultInlineImageProvider: InlineImageProvider { @@ -21,3 +22,12 @@ extension InlineImageProvider where Self == DefaultInlineImageProvider { .init() } } + +// MARK: - Deprecated after 2.1.0: + +extension DefaultInlineImageProvider { + @available(*, deprecated, message: "Use the 'default' static property") + public init(urlSession: URLSession = .shared) { + self.init() + } +} diff --git a/Tests/MarkdownUITests/MarkdownImageTests.swift b/Tests/MarkdownUITests/MarkdownImageTests.swift index ce598581..e65ed4c2 100644 --- a/Tests/MarkdownUITests/MarkdownImageTests.swift +++ b/Tests/MarkdownUITests/MarkdownImageTests.swift @@ -4,6 +4,7 @@ import XCTest import MarkdownUI + import ImageProviders final class MarkdownImageTests: XCTestCase { private let layout = SwiftUISnapshotLayout.device(config: .iPhone8) diff --git a/Tests/MarkdownUITests/MarkdownTableTests.swift b/Tests/MarkdownUITests/MarkdownTableTests.swift index 639d14ca..343f55da 100644 --- a/Tests/MarkdownUITests/MarkdownTableTests.swift +++ b/Tests/MarkdownUITests/MarkdownTableTests.swift @@ -4,6 +4,7 @@ import XCTest import MarkdownUI + import ImageProviders final class MarkdownTableTests: XCTestCase { private let layout = SwiftUISnapshotLayout.device(config: .iPhone8) diff --git a/Tests/MarkdownUITests/ThemeDocCTests.swift b/Tests/MarkdownUITests/ThemeDocCTests.swift index d901ef27..2a2348e6 100644 --- a/Tests/MarkdownUITests/ThemeDocCTests.swift +++ b/Tests/MarkdownUITests/ThemeDocCTests.swift @@ -4,6 +4,7 @@ import XCTest import MarkdownUI + import ImageProviders final class ThemeDocCTests: XCTestCase { private let layout = SwiftUISnapshotLayout.device(config: .iPhone8)