Jacobo Koenig
Jacobo Koenig

Reputation: 12514

Swift- Setting attributes to string crashes with empty strings

I am using an extension to parse HTML text into an attributed string from a dynamically retrieved post.

I notice now that my app is crashing when retrieving a post that has empty content.

extension NSAttributedString {

    public convenience init?(HTMLString html: String, font: UIFont? = nil) throws {

        let options: [String: Any] = [...]

        guard let data = html.data(using: .utf8, allowLossyConversion: true) else {
            throw NSError(domain: "Parse Error", code: 0, userInfo: nil)
        }

        if let font = font {
            guard let attr = try? NSMutableAttributedString(data: data, options: options, documentAttributes: nil) else {
                throw NSError(domain: "Parse Error", code: 0, userInfo: nil)
            }
            var attrs = attr.attributes(at: 0, effectiveRange: nil) //APP CRASHES HERE
            attrs[NSFontAttributeName] = font
            attr.setAttributes(attrs, range: NSRange(location: 0, length: attr.length))
            self.init(attributedString: attr)
        } else {
            try? self.init(data: data, options: options, documentAttributes: nil)
        }}}

Here is my exception:

'NSRangeException', reason: 'NSMutableRLEArray objectAtIndex:effectiveRange:: Out of bounds'

I am not very good at handling errors yet, is there a way to prevent this exception from arising regardless of the content?

I tried a do/catch block but it says that no calls to throwing functions happen in this line:

do {
var attrs = attr.attributes(at: 0, effectiveRange: nil) //APP CRASHES HERE
            attrs[NSFontAttributeName] = font
            attr.setAttributes(attrs, range: NSRange(location: 0, length: attr.length))
            self.init(attributedString: attr)
   } catch {
print("error")
}

Upvotes: 0

Views: 1699

Answers (2)

user5890979
user5890979

Reputation:

Do a simple check on your yourString.characters.count before running the code otherwise NSRange will crash if it's nil.

Upvotes: 1

vadian
vadian

Reputation: 285064

Just include the check for empty string in the first guard:

guard !html.isEmpty, let data = html.data(using: .utf8, allowLossyConversion: true) else {...

Or if you want to get an empty attributed string if the string is empty put the check in the font line:

if !html.isEmpty, let font = font { ...

Upvotes: 2

Related Questions