在Swift中将HTML转换为纯文本


68

我正在开发一个简单的RSS Reader应用程序,作为Xcode中的初学者项目。目前,我已设置它解析提要,并将标题,发布日期,描述和内容放置在WebView中。

我最近决定在用于选择帖子的TableView中显示说明(或内容的删节版本)。但是,这样做时:

cell.textLabel?.text = item.title?.uppercaseString
cell.detailTextLabel?.text = item.itemDescription //.itemDescription is a String

它显示了帖子的原始HTML。

我想知道如何仅将TableView的详细UILabel转换为纯HTML。

谢谢!

Answers:


231

您可以添加此扩展名以将html代码转换为常规字符串:

编辑/更新:

讨论不应从后台线程调用HTML导入器(即,选项字典包含值为html的documentType)。它将尝试与主线程同步,失败并超时。从主线程调用它是可行的(但如果HTML包含对外部资源的引用,仍可能会超时,应该不惜一切代价避免这样做)。HTML导入机制旨在实现诸如markdown之类的东西(即,文本样式,颜色等),而不是用于常规HTML导入。

Xcode 11.4•Swift 5.2

extension Data {
    var html2AttributedString: NSAttributedString? {
        do {
            return try NSAttributedString(data: self, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil)
        } catch {
            print("error:", error)
            return  nil
        }
    }
    var html2String: String { html2AttributedString?.string ?? "" }
}

extension StringProtocol {
    var html2AttributedString: NSAttributedString? {
        Data(utf8).html2AttributedString
    }
    var html2String: String {
        html2AttributedString?.string ?? ""
    }
}

cell.detailTextLabel?.text = item.itemDescription.html2String

13
这种方法非常笨重处理器
INNI

1
对于Swift 3:+1,默认情况下,Xcode通过将我的代码从Swift 2转换NSUTF8StringEncoding为来移植String.Encoding.utf8,但它一直崩溃。多亏了这个答案,我能够通过将其附加.rawValueEncoding枚举来修复它。
kabiroberai

1
不会在迅速的4上编译
Hemant Singh

1
这在ios 10上工作正常,但在ios 11上,它对html数据做了一些奇怪的事情,就像它忽略了自定义字体的字体粗细一样。除非明确定义。
Gustavo_fringe

1
@LeoDabus我认为这是Playgrounds中的一些脆弱之处。关闭Xcode并重新启动可以解决我第一次遇到的错误。
阿德里安

6

斯威夫特4,Xcode 9

extension String {
    
    var utfData: Data {
        return Data(utf8)
    }
    
    var attributedHtmlString: NSAttributedString? {
        
        do {
            return try NSAttributedString(data: utfData, options: [
              .documentType: NSAttributedString.DocumentType.html,
              .characterEncoding: String.Encoding.utf8.rawValue
            ], 
            documentAttributes: nil)
        } catch {
            print("Error:", error)
            return nil
        }
    }
}

extension UILabel {
   func setAttributedHtmlText(_ html: String) {
      if let attributedText = html.attributedHtmlString {
         self.attributedText = attributedText
      } 
   }
}

ANY字符串可以转换为utf8数据。返回optional是没有意义的。Justreturn Data(utf8)
Leo Dabus

在这里,我们希望将字符串转换为NSAttributedString,为什么只返回Data(utf8)会很有用?
Suhit Patil'1

我的意思是var utf8data: Data { return Data(utf8) }从您的方法中删除警卫
Leo Dabus

BtwlocalizedDescription是多余的。Just print(error)
Leo Dabus,

2

这是我建议的答案。如果要放入函数中,请不要使用扩展名。

func decodeString(encodedString:String) -> NSAttributedString?
    {
        let encodedData = encodedString.dataUsingEncoding(NSUTF8StringEncoding)!
        do {
            return try NSAttributedString(data: encodedData, options: [NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType,NSCharacterEncodingDocumentAttribute:NSUTF8StringEncoding], documentAttributes: nil)
        } catch let error as NSError {
            print(error.localizedDescription)
            return nil
        }
    }

并调用该函数并将NSAttributedString转换为String

let attributedString = self.decodeString(encodedString)
let message = attributedString.string

1

请使用此代码测试detailTextLabel:

var attrStr = NSAttributedString(
        data: item.itemDescription.dataUsingEncoding(NSUnicodeStringEncoding, allowLossyConversion: true),
        options: [ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
        documentAttributes: nil,
        error: nil)
cell.detailTextLabel?.text = attrStr

@AltimirAntonov,您好,感谢您的回复。item.itemDescription是一个字符串-也许我应该早一点澄清一下。我应该将其转换为NSData吗?
Zaid Syed 2015年

1

在swift3中尝试此解决方案

extension String{
    func convertHtml() -> NSAttributedString{
        guard let data = data(using: .utf8) else { return NSAttributedString() }
        do{
            return try NSAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue], documentAttributes: nil)
        }catch{
            return NSAttributedString()
        }
    }
}

使用

self.lblValDesc.attributedText = str_postdescription.convertHtml()

1

Swift4.0扩展

 extension String {
    var html2AttributedString: String? {
    guard let data = data(using: .utf8) else { return nil }
    do {
        return try NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil).string

    } catch let error as NSError {
        print(error.localizedDescription)
        return  nil
    }
  }
}

0

我使用了Danboz答案,只是将其更改为返回一个简单的String(而不是富文本字符串):

static func htmlToText(encodedString:String) -> String?
{
    let encodedData = encodedString.dataUsingEncoding(NSUTF8StringEncoding)!
    do
    {
        return try NSAttributedString(data: encodedData, options: [NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType,NSCharacterEncodingDocumentAttribute:NSUTF8StringEncoding], documentAttributes: nil).string
    } catch let error as NSError {
        print(error.localizedDescription)
        return nil
    }
}

对我来说,它就像一种魅力,谢谢Danboz


0
let content = givenString // html included string
let attrStr = try! NSAttributedString(data: content.data(using: String.Encoding.unicode, allowLossyConversion: true)!,options: [ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],documentAttributes: nil)
self.labelName.attributedText = attrStr    
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.