You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从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实体(如&lt;u&gt;),需先解码为原始标签再解析:

// 新增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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 19:03:28