contentful / rich-text-renderer.swift

Render Contentful Rich Text fields to native strings and views
MIT License
30 stars 32 forks source link

Support for SwiftUI #37

Open kamila-and opened 2 years ago

kamila-and commented 2 years ago

Hi, will this library or another library ever support SwiftUI? Or is there anyone who successfully managed to integrate this library in their SwiftUI project that could help me out? Thanks

PiotrBogus commented 1 year ago
import Foundation
import SwiftUI
import Contentful

@available(iOS 13.0, *)
public struct SwiftUIRichTextView: UIViewControllerRepresentable {
    private let richTextViewController: RichTextViewController
    @Binding private var richTextDocument: RichTextDocument?

    public init(
        richTextViewController: RichTextViewController,
        richTextDocument: Binding<RichTextDocument?> = .constant(nil)
    ) {
        self.richTextViewController = richTextViewController
        _richTextDocument = richTextDocument
    }

    public func makeUIViewController(context _: Context) -> RichTextViewController {
        return richTextViewController
    }

    public func updateUIViewController(_ viewController: RichTextViewController, context _: Context) {
        viewController.richTextDocument = richTextDocument
    }
}
PiotrBogus commented 1 year ago

Here is example how to use it:

@available(iOS 13.0, *)
struct SwiftUIMainView: View {
    private var richTextViewController: RichTextViewController {
        var configuration = DefaultRendererConfiguration()
        configuration.resourceLinkBlockViewProvider = ExampleBlockViewProvider()
        configuration.resourceLinkInlineStringProvider = ExampleInlineStringProvider()

        let renderersProvider = DefaultRenderersProvider()

        let renderer = RichTextDocumentRenderer(
            configuration: configuration,
            nodeRenderers: renderersProvider
        )

        return RichTextViewController(renderer: renderer)
    }

    private let client = ContentfulService()
    @State var richTextDocument: RichTextDocument?

    var body: some View {
        VStack {
            SwiftUIRichTextView(
                richTextViewController: richTextViewController,
                richTextDocument: $richTextDocument
            )
        }.onAppear {
            fetchContent()
        }
    }

    private func fetchContent() {
        client.fetchArticle { result in
            switch result {
            case .success(let article):
                print(article)
                richTextDocument = article.content

            case .failure(let error):
                print(error)
            }
        }
    }
}
TizianoCoroneo commented 6 months ago

@PiotrBogus in this example, ExampleBlockViewProvider() and ExampleInlineStringProvider() are required to provide UIView objects to render embedded entries inside rich text. Is there any way to provide SwiftUI views? If the library changed these "provider" objects to provide UIViewControllers instead it would be trivial to return UIHostingController instead, solving the issue.

TizianoCoroneo commented 6 months ago

CC @mariuskatcontentful

alizeec commented 1 month ago

Hi, I have the same issue. If I follow your code @PiotrBogus , I just have white rectangles