Arturo
Arturo

Reputation: 4180

Convert html links inside text to clickable links - SwiftUI

Is there any up to date way to convert links inside the text? I'm getting this kind of text from an API:

var someText: String = "with banks (for example to the sometimes controversial but leading exchange <a href="https://www.coingecko.com/en/exchanges/bitfinex">Bitfinex</a>)."

How can I convert that link inside to a clickable link with the proper name, in the example above: Bitfinex ?

The text could contain multiple links. SwiftUI now supports markdown, manually I could do it like:

Text("[Privacy Policy](https://example.com)")

but how do I do it for a received text from api with multiple links?

Looking for a Swift 5 & SwiftUI 3 solution.

Upvotes: 6

Views: 3140

Answers (1)

Leo Dabus
Leo Dabus

Reputation: 236260

What you have is an html string. You can interpret your html string using NSAttributedString initializer options NSAttributedString.DocumentType.html and initialize a new AttributedString with it. No need to manipulate and/or manually parse your string:


First add this extension to your project:

extension StringProtocol {
    func htmlToAttributedString() throws -> AttributedString {
        try .init(
            .init(
                data: .init(utf8),
                options: [
                    .documentType: NSAttributedString.DocumentType.html,
                    .characterEncoding: String.Encoding.utf8.rawValue
                ],
                documentAttributes: nil
            )
        )
    }
}

Then extend Text to add a custom initializer:

extension Text {
    init(html: String, alert: String? = nil) {
        do {
            try self.init(html.htmlToAttributedString())
        } catch {
            self.init(alert ?? error.localizedDescription)
        }
    }
}

import SwiftUI

struct ContentView: View {
    
    var html = #"with banks (for example to the sometimes controversial but leading exchange <a href="https://www.coingecko.com/en/exchanges/bitfinex">Bitfinex</a>. For more info <a href="https://www.google.com/">Google</a>).""#

    var body: some View {
        Text(html: html)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Upvotes: 8

Related Questions