Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide better support for SwiftUI and AttributedString. #12

Open
makhocheung opened this issue Mar 13, 2023 · 5 comments
Open

Provide better support for SwiftUI and AttributedString. #12

makhocheung opened this issue Mar 13, 2023 · 5 comments
Labels
enhancement New feature or request

Comments

@makhocheung
Copy link

makhocheung commented Mar 13, 2023

Here is the example.

import Combine
import SwiftUI
import ZMarkupParser

struct MainView: View {
    @State var content = AttributedString("None")
    var body: some View {
        ScrollView {
            VStack {
                Text(content)
            }
        }
        .onAppear {
            content = AttributedString(parser.render(html))
        }
    }
}

struct MainView_Previews: PreviewProvider {
    static var previews: some View {
        MainView()
    }
}

let parser = ZHTMLParserBuilder.initWithDefault().set(rootStyle: MarkupStyle(font: MarkupStyleFont(size: 13))).build()

let html = #"""

Powered by ZhgChgLi. <br/>

<img src="https://user-images.githubusercontent.com/33706588/219608966-20e0c017-d05c-433a-9a52-091bc0cfd403.jpg"/>

🎄🎄🎄 <Hottest> <b>Christmas gi<u>fts</b> are here</u>! Give you more gift-giving inspiration~<br />
        The <u>final <del>countdown</del></u> on 12/9, NT$100 discount for all purchases over NT$1,000, plus a 12/12 one-day limited free shipping coupon<br />
        <zhgchgli>Top 10 Popular <b><span style="color:green">Christmas</span> Gift</b> Recommendations 👉</zhgchgli><br>
        <ol>
        <li><a href="https://zhgchg.li">Christmas Mini Diffuser Gift Box</a>|The first choice for exchanging gifts</li>
        <li><a href="https://zhgchg.li">German design hair remover</a>|<strong>500</strong> yuan practical gift like this</li>
        <li><a href="https://zhgchg.li">Drink cup</a>|Fund-raising and praise exceeded 10 million</li>
        </ol>
        <hr/>
        <p>Before 12/26, place an order and draw a round-trip ticket for two to Japan!</p>
        你好你好<span style="background-color:red">你好你好</span>你好你好 <br />
        안녕하세요안녕하세<span style="color:red">요안녕하세</span>요안녕하세요안녕하세요안녕하세요 <br />
        <span style="color:red">こんにちは</span>こんにちはこんにちは <br />


<h1>不支持</h1>
<h2>不支持</h2>
<h3>不支持</h3>
<h4>不支持</h4>
<h5>不支持</h5>
<h6>不支持</h6>

"""#

image

Here is the error printed by console.

2023-03-13 16:46:54.445491+0800 Demo[41916:3803493] [Demo] CGImageDestinationCreateWithData:4044: *** ERROR: CGImageDestinationCreateWithData: invalid capacity (0)
2023-03-13 16:46:54.445856+0800 Demo[41916:3803493] [Demo] finalizeDestination:3205: *** ERROR: CGImageDestinationFinalize was called, but there were no images added
2023-03-13 16:46:54.445881+0800 Demo[41916:3803493] CGImageDestinationFinalize failed for output type 'public.tiff'
@makhocheung makhocheung changed the title <img/> do not work in SwiftUI <img/> does not work in SwiftUI Mar 13, 2023
@makhocheung makhocheung changed the title <img/> does not work in SwiftUI <img/> does not work in SwiftUI. And does the library not support <h*/> labels currently? Mar 13, 2023
@zhgchgli0718
Copy link
Member

zhgchgli0718 commented Mar 13, 2023

Hi, @makhocheung thank you for using and providing feedback.

From the content of your issue, I have identified three problems that need to be resolved:

  • Easy - Support h1~h6. This is not a bug, but an extension is needed to support H tags.
  • Easy - I saw a log message that says "failed for output type 'public.tiff'" on macOS, which means I have a misunderstanding of AppKit's NSImage. This issue is also related to ZNSTextAttachment.
  • Need research - Make AttributedString support ZNSTextAttachment. Currently, we use ZNSTextAttachment to represent images.

I'll resolve it as soon as possible.

Thank you again for your feedback, I have not fully tested on macOS or using SwiftUI yet.

@zhgchgli0718
Copy link
Member

After conducting research, I have concluded that AttributedString and NSAttributedString are not small objects and do not share the same inheritance.
Therefore, I believe that using NSAttributedString in AttributedString or SwiftUI is not a good idea.
Instead, we should create a new mapper to map ZMarkupParser.Markup objects to SwiftUI Kit (Text/Image) components, rather than using NSAttributedString directly in AttributedString.

Unfortunately, it may not be implemented quickly.

A temporary dirty solution would be to find ZNSTextAttachment for each AttributedString and manually trigger startDownload() and handle delegate for it.

content.compactMap({ $0.attachment as? ZNSTextAttachment }).forEach { attachment in
     attachment.delegate = self
    attachment.startDownlaod()
})
// handler delegate
func zNSTextAttachment(didLoad textAttachment: ZNSTextAttachment, to: ZResizableNSTextAttachment) {
     //
    replace  textAttachment to to in AttributedString
}

I know it's very dirty, but as I mentioned earlier, it's not recommended to use it in SwiftUI currently.

@zhgchgli0718 zhgchgli0718 added this to the 2023Q2 milestone Mar 13, 2023
@zhgchgli0718 zhgchgli0718 added the enhancement New feature or request label Mar 13, 2023
@zhgchgli0718
Copy link
Member

Please let me know if there is anything I have misunderstood, as I am not very familiar with SwiftUI.

@makhocheung
Copy link
Author

Currently,AttributedString supports markdown natively except ![](),so it's normal that AttributedString can't load remote images. Maybe Apple will add this feature in the future.

we should create a new mapper to map ZMarkupParser.Markup objects to SwiftUI Kit (Text/Image) components, rather than using NSAttributedString directly in AttributedString.

This is a good idea. Developers may hope ZMarkupParser supports SwiftUI.

Actually, I'm appreciate that you have added support of h1~h6. ZMarkupParser currently satisfies my project. I will give more feedback later. Thank you.

@zhgchgli0718 zhgchgli0718 removed this from the 2023Q2 milestone Mar 18, 2023
@zhgchgli0718 zhgchgli0718 changed the title <img/> does not work in SwiftUI. And does the library not support <h*/> labels currently? Provide better support for SwiftUI and AttributedString. Mar 18, 2023
@charrondev
Copy link
Contributor

I'll add on here that this is really more of a failing of a failing of SwiftUI's Text() than of this library. It is very simple to convert between the 2 nowadays.

let nsAttr = parser.render(html)
let attr = AttributedString(nsAttr)

The real issue is that AttributedString and Text() are missing a lot of functionality, most notably support for NSParagraphStyle which you need to do paragraph level alignment, spacing, lineSpacing, justification, etc.

For my own projects I use a UIViewRepresentable wrapping a UITextView to get the maximum flexibility.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants