Rain this morning 🌧
SwiftUI attributed strings
I’ve been working on a pure SwiftUI feed reader which uses Text elements for most of the content, but using the iOS 14 SDK I had not yet implemented embedded links, as the Text element did not support attributed strings. This has changed with the new iOS 15 SDK, which adds an AttributedString struct which can be passed to Text elements in place of a String.
In addition it is now possible to pass String values with a subset of Markdown formatting to Text elements directly, to create an AttributedString, and to create the Foundation basis NSAttributedString. But this does not always work as I expected.
When I pass a String literal with Markdown I get the expected behavior; thus
Text("**This** is a _test_ with a [link](https://elegantnewt.blog).")
yields the expected result
This is a test with a link.
However if I pass a reference to the same String to the Text element then the Markdown is not parsed:
let str = "**This** is a _test_ with a [link](https://elegantnewt.blog)."
Text(str)
results in
**This** is a _test_ with a [link](https://elegantnewt.blog).
If I use a string literal but try to inject the URL via interpolation I find that the link text is correct but is not marked as a link:
let url = "https://elegantnewt.blog"
Text("**This** is a _test_ with a [link](\(url)).")
produces
This is a test with a link.
However, if I create an AttributedString instance using the same input, and then pass that to the Text element, I do get the correct result, although I need to verify that the construction succeeds:
let markdown = "**This** is a _test_ with a [link](\(url))."
if let att = try? AttributedString(markdown: markdown) {
Text(att)
}
works as expected:
This is a test with a link.
As an alternative, if I construct an NSAttributedString from the same Markdown string reference, I again get the correct rendering:
if let nsAtt = try? NSAttributedString(markdown: markdown),
let att = try? AttributedString(nsAtt, including: AttributeScopes.SwiftUIAttributes.self) {
Text(att)
}
also yields
This is a test with a link.
But I need to be careful about how I construct that NSAttributedString. For example, if I build it from the corresponding HTML markup then the bold and italic modifiers aren’t rendered.
let html = "<b>This</b> is a <i>test</i> with a <a href=\"https://elegantnewt.blog\">link</a>."
let data = Data(html.utf8)
if let htmlNSAtt = try? NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html], documentAttributes: nil),
let htmlAtt = try? AttributedString(htmlNSAtt, including: AttributeScopes.SwiftUIAttributes.self) {
Text(htmlAtt)
}
results in
This is a test with a link.
Obviously I need to compare the NSAttributedString instances to determine the exact attributes being used in these different cases.
Last day before returning to town.
Still pretty busy, haven’t even downloaded Xcode 13 until now.
Less rain than expected so far.
View from lunch.
Trying to get caught up, despite the busy schedule we did manage to fit in a swim in a pond yesterday.
Too much going on today.
It seems that New England has moved to the tropics while we were out of town.
Achieved the goal of swimming every day, but came one G&T short of finishing the gin. Homeward bound…
Time to pack for the return trip.
Today I learned that posts are ordered by date, not post ID, and that post ID can be out of order.
The vacation can’t end until we finish the gin.
Next week seems to be WWDC and BEMF.
We are well into the last week of our vacation.
I think these are white tailed kites, we didn’t have the binoculars to be sure.


Crows have been using small rocks on the path to break snail shells, I saw several similar tableaus yesterday.
It’s a lovely morning in the village, and you are a windup goose.
Torrey Pines State Nature Reserve



Setting up a GitHub account was easy, now I have to set up two-factor authentication, personal access tokens, and keychain access. There should be a better way to manage this without sacrificing security.
Today I finally set up a personal GitHub account.
Cabrillo National Monument