# AttributedString to String

**URL:** <https://forums.swift.org/t/attributedstring-to-string/61667>\
**Category:** Using Swift\
**Created:** [November 28, 2022, 8:44pm UTC](https://forums.swift.org/t/attributedstring-to-string/61667 "2022-11-28T20:44:46Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Stan\_Smida](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/stan_smida/32/10999_2.png) [@Stan\_Smida](https://forums.swift.org/u/Stan_Smida)\
**Post date:** [November 28, 2022, 8:44pm UTC](https://forums.swift.org/t/attributedstring-to-string/61667/1 "2022-11-28T20:44:46Z")

</div>

What is a designated API to get `String` from `AttributedString`?

---

<div class="post-metadata">

**Author:** ![itaiferber](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/itaiferber/32/33840_2.png) [@itaiferber](https://forums.swift.org/u/itaiferber)\
**Post date:** [November 28, 2022, 9:41pm UTC](https://forums.swift.org/t/attributedstring-to-string/61667/2 "2022-11-28T21:41:43Z")

</div>

As far as I can tell, there are currently two ways to fetch a `String` from an `AttributedString` at the moment, both revolving around `AttributedString.CharacterView`:

1. `String` has [an initializer](https://developer.apple.com/documentation/swift/string/init(_:)-8og6g) which takes a `Sequence` of `Characters` and constructs itself from that sequence. Given an `AttributedString` `attrStr`, you can write `String(attrStr.characters)`.

2. It's not particularly intuitive to find, but the `AttributedString` work added an [initializer to `String`](https://developer.apple.com/documentation/swift/string/init(_:)-5ruqx) which takes a _slice_ of an `AttributedString`, [reaches into its `_guts` to grab the underlying `String`](https://github.com/apple/swift-corelibs-foundation/blob/0787ce675eb6a91dfb073908d14a52fcae26c404/Sources/Foundation/AttributedString/AttributedString.swift#L2062), slices the underlying `String`, and returns a bulk copy of _that_.

I haven't thought through the slicing aspects, but it _appears_ to me that not offering read access to the underlying `String` directly may only be an API oversight. Someone from the Foundation team, feel free to correct me, but this may be worth filing Feedback for. (As an alternative, it also seems reasonable to offer `String.init(_: AttributedString.CharacterView)` and `String.init<S: AttributedStringProtocol>(_: S)` as fast-path shortcuts for performing this conversion with fewer performance implications.)

---

<div class="post-metadata">

**Author:** ![Stan\_Smida](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/stan_smida/32/10999_2.png) [@Stan\_Smida](https://forums.swift.org/u/Stan_Smida)\
**Post date:** [November 29, 2022, 7:36am UTC](https://forums.swift.org/t/attributedstring-to-string/61667/3 "2022-11-29T07:36:01Z")

</div>

Thank you. I was using 1. without thinking about performance. It just didn't feel like a proper API to do the thing. For now I perhaps just switch to 2.

+1 for encouraging for more expressive API.

---

<div class="post-metadata">

**Author:** ![valeriyvan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/valeriyvan/32/8705_2.png) [@valeriyvan](https://forums.swift.org/u/valeriyvan)\
**Post date:** [February 19, 2024, 8:40pm UTC](https://forums.swift.org/t/attributedstring-to-string/61667/4 "2024-02-19T20:40:42Z")

</div>

> [@itaiferber](#):
>
> `AttributedString.CharacterView`

One more way: `NSAttributedString(attributedString).string`.

---

<div class="post-metadata">

**Author:** ![anesbitt](https://avatars.discourse-cdn.com/v4/letter/a/22d042/32.png) [@anesbitt](https://forums.swift.org/u/anesbitt)\
**Post date:** [May 28, 2025, 7:02pm UTC](https://forums.swift.org/t/attributedstring-to-string/61667/5 "2025-05-28T19:02:26Z")

</div>

> [@itaiferber](#):
>
> `String(attrStr.characters[...])`

Good call with the characters[...] idea.

FWIW some very rough timing tests suggest 'characters[...]' is about 25% faster than 'characters'.

They are both more the 10 x faster than NSAttributedString(attrStr).string route.

But context and caching makes it all very approximate.

---

<div class="post-metadata">

**Author:** ![jmschonfeld](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jmschonfeld/32/20922_2.png) [@jmschonfeld](https://forums.swift.org/u/jmschonfeld)\
**Post date:** [May 28, 2025, 7:49pm UTC](https://forums.swift.org/t/attributedstring-to-string/61667/6 "2025-05-28T19:49:51Z")

</div>

Yes using `attrStr.characters[...]` is much faster because we have an explicit overload for this in Foundation, but using `attrStr.characters` is slower as it falls back to the Sequence implementation. The use of `[...]` shouldn't be necessary, it's simply an oversight in the original API and the new API to fix this exists in the repo but is disabled as it needs to be pitched/approved: [swift-foundation/Sources/FoundationEssentials/AttributedString/Conversion.swift at e072f824bcd6f0d4bdb28142d15439e8afc4df00 · swiftlang/swift-foundation · GitHub](https://github.com/swiftlang/swift-foundation/blob/e072f824bcd6f0d4bdb28142d15439e8afc4df00/Sources/FoundationEssentials/AttributedString/Conversion.swift#L30-L42), but I don't see any reason why that couldn't be added if it were to be pitched

I'd definitely recommend against `NSAttributedString(attrStr).string` as that converts the entire `AttributedString` contents to an `NSAttributedString` (potentially `dlopen`-ing UI frameworks to find their attribute scopes, converting attribute values, and bridging the string content to a UTF-16-based `NSString` before bridging the `NSString` back to a `String`) which is why you see that one being far slower.

---

<div class="post-metadata">

**Author:** ![jmschonfeld](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jmschonfeld/32/20922_2.png) [@jmschonfeld](https://forums.swift.org/u/jmschonfeld)\
**Post date:** [February 20, 2026, 1:01am UTC](https://forums.swift.org/t/attributedstring-to-string/61667/7 "2026-02-20T01:01:47Z")

</div>

PR to add the specialized entry point to swift-foundation: [Specialize AttributedString.CharacterView to String conversion by jmschonfeld · Pull Request #1766 · swiftlang/swift-foundation · GitHub](https://github.com/swiftlang/swift-foundation/pull/1766)

---

<div class="post-metadata">

**Author:** ![grynspan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/grynspan/32/15315_2.png) [@grynspan](https://forums.swift.org/u/grynspan)\
**Post date:** [February 20, 2026, 4:17pm UTC](https://forums.swift.org/t/attributedstring-to-string/61667/8 "2026-02-20T16:17:23Z")

</div>

IMHO this is just a bug fix/performance optimization and does not need a separate pitch/review.
