Reputation: 8371
I wrote a simple extension to decode the html entities:
extension String {
func htmlDecode() -> String {
if let encodedData = self.data(using: String.Encoding.unicode) {
let attributedString = try! NSAttributedString(data: encodedData, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: String.Encoding.unicode], documentAttributes: nil)
return attributedString.string
}
return self
}
}
Now it throws an error on the line if let attributedString …
:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 4 beyond bounds [0 .. 2]'
And self
is not nil or something, just a String
like this:
self = (String) "...über 25'000 Franken..."
Where is this strange NSArray
-exception coming from?
Upvotes: 11
Views: 2036
Reputation: 1
DispatchQueue.main.async { let text = yourHtmlText.htmlDecode() }
Upvotes: 0
Reputation: 4737
In my case, this was happening because I was trying to instantiate a NSAttributedString
from within a UICollectionViewCell
that was in detached state (before it was inserted in the parent UICollectionView).
Upvotes: 2
Reputation: 489
A shot in the dark: do you ensure that the initialization happens on the main thread?
I had exactly the same problem. I noticed that in my case the exception occurs under reproducible conditions (animations in a UICollectionViewController), but I was unable to find the actual cause. My best guess is that it's a framework bug, so I'd too suggest you file a radar.
I ended up pre-rendering my HTML formatted strings into a cache (aka array) at a time where it works, and then load the NSAttributedStrings from it on demand.
Note though that this solution may not fit your use case, since I only have to deal with a limited amount of formatted strings at a time and hence know the expense of rendering them in advance.
Upvotes: 4
Reputation: 8371
I just run over this error with a different error:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_SwiftValue unsignedIntegerValue]: unrecognized selector sent to instance 0x60000024b790'
And found a serious bug in this piece of code:
I was passing String.Encoding.unicode
- a Swift value - to an Objective-C method that crashed the app. After using String.Encoding.unicode.rawValue
the crash disappeared:
extension String {
func htmlDecode() -> String {
if let encodedData = self.data(using: String.Encoding.unicode) {
if let attributedString = try? NSAttributedString(data: encodedData, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: String.Encoding.unicode.rawValue], documentAttributes: nil) {
return attributedString.string
}
}
return self
}
}
Upvotes: -1
Reputation: 66242
Seems like a bug, possibly related to how Swift strings handle characters differently than NSString
.
I would file a radar.
Upvotes: 0