从HTML创建NSAttributedString时偶发格式错误异常求助
解决NSAttributedString解析HTML偶发NSCocoaErrorDomain Code=259错误
问题核心原因
你遇到的偶发格式错误,本质是NSAttributedString的HTML解析器依赖完整的HTML文档结构,孤立的行内标签(如<u>)在某些场景下会因为上下文缺失触发解析失败。另外,线程不安全、Localizable字符串转义异常也可能导致偶发报错。
具体修复方案
1. 给HTML片段包裹完整文档结构
修改StringProtocol扩展,将原始HTML字符串套入<html><body>标签,确保解析器识别为合法文档:
extension StringProtocol { var html2AttributedString: NSAttributedString? { // 包裹完整HTML结构 let wrappedHtml = "<html><body>\(self)</body></html>" return Data(wrappedHtml.utf8).html2AttributedString } } extension Data { var html2AttributedString: NSAttributedString? { do { return try NSAttributedString( data: self, options: [ .documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue ], documentAttributes: nil) } catch { bfprint("html2AttributedString: Html string parsing error: \(error)", tag: LogUtils.Tags.criticalDevError, level: .error) return nil } } }
2. 确保Localizable字符串正确解码
如果Localizable文件中存储的是转义后的HTML实体(如<u>),需先解码为原始标签再解析:
// 新增HTML实体解码扩展 extension StringProtocol { var htmlUnescaped: String { guard let data = data(using: .utf8) else { return String(self) } let options: [NSAttributedString.DocumentReadingOptionKey: Any] = [ .documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue ] return try? NSAttributedString(data: data, options: options, documentAttributes: nil).string ?? String(self) } } // 使用示例 let rawLocalizedString = NSLocalizedString("underlined_content", comment: "") let decodedHtml = rawLocalizedString.htmlUnescaped let attributedText = decodedHtml.html2AttributedString
3. 强制主线程解析(解决线程安全问题)
NSAttributedString的HTML解析依赖WebKit上下文,后台线程调用可能触发偶发冲突,需确保解析操作在主线程执行:
extension Data { var html2AttributedString: NSAttributedString? { var result: NSAttributedString? let semaphore = DispatchSemaphore(value: 0) // 切换到主线程执行解析 DispatchQueue.main.async { do { result = try NSAttributedString( data: self, options: [ .documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue ], documentAttributes: nil) } catch { bfprint("html2AttributedString: Html string parsing error: \(error)", tag: LogUtils.Tags.criticalDevError, level: .error) result = nil } semaphore.signal() } semaphore.wait() return result } }
优先级建议
优先尝试方案1(包裹完整HTML结构),这是触发Code=259错误最常见的原因;如果问题仍偶发,再检查线程是否合规;最后确认Localizable字符串的转义状态。
内容的提问来源于stack exchange,提问作者Roman Markov
相关产品推荐
相关产品推荐

