Konwertuj HTML na zwykły tekst w Swift

Pracuję nad prostą aplikacją czytnika RSS jako początkujący projekt w Xcode. Obecnie mam go skonfigurowany, że parsuje kanał, i umieszcza tytuł, datę publikacji, opis i treść i wyświetla go w widoku sieci Web.

Ostatnio postanowiłem pokazać opis (lub skróconą wersję zawartości) w widoku TableView używanym do wyboru posta. Jednak przy tym:

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

Pokazuje surowy HTML posta.

Chciałbym wiedzieć jak przekonwertować HTML na zwykły tekst tylko do szczegółowego UILabel TableView.

Dzięki!
Author: Martin R, 2015-01-24

6 answers

Możesz dodać to rozszerzenie, aby przekonwertować kod html na zwykły ciąg znaków:

Edycja / aktualizacja:

Dyskusja importer HTML nie powinien być wywoływany z tła wątku (czyli słownik opcji zawiera typ dokumentu z wartość html). Spróbuje zsynchronizować się z głównym wątkiem, nie uda, i przerwa. Wywołanie go z głównego wątku działa (ale może jeszcze czasu, jeśli HTML zawiera odniesienia do zasobów zewnętrznych, które należy unikać za wszelką cenę). Mechanizm importu HTML ma na celu do implementacji czegoś takiego jak markdown (czyli stylów tekstowych, kolory i tak dalej), nie dla ogólnego importu HTML.

Xcode 9 * Swift 4

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 {
        return html2AttributedString?.string ?? ""
    }
}

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

Xcode 8.3 * Swift 3.1

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

cell.detailTextLabel?.text = item.itemDescription.html2String
 176
Author: Leo Dabus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-29 01:39:16

Oto moja sugerowana odpowiedź. Zamiast rozszerzenia, jeśli chcesz umieścić wewnątrz funkcji.

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
        }
    }

I wywołanie tej funkcji i rzucenie Nsattributedstring na String

let attributedString = self.decodeString(encodedString)
let message = attributedString.string
 2
Author: Danboz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-26 06:19:50

Proszę przetestować ten kod dla detailTextLabel:

var attrStr = NSAttributedString(
        data: item.itemDescription.dataUsingEncoding(NSUnicodeStringEncoding, allowLossyConversion: true),
        options: [ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
        documentAttributes: nil,
        error: nil)
cell.detailTextLabel?.text = attrStr
 1
Author: Altimir Antonov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-25 00:41:35

Spróbuj tego rozwiązania w 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()
        }
    }
}

Aby użyć

self.lblValDesc.attributedText = str_postdescription.convertHtml()
 1
Author: Hardik Thakkar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-22 15:10:49

Użyłem Danboz answer, Tylko zmieniłem ją, aby zwracała prosty łańcuch (nie bogaty łańcuch tekstowy):

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
    }
}

Dla mnie działa jak czar, dzięki Danboz

 0
Author: Shaybc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-09 23:47:48
//Swift 4, Xcode 9

extension String {

    var utfData: Data? {
        return self.data(using: .utf8)
    }

    var attributedHtmlString: NSAttributedString? {
        guard let data = self.utfData else {
            return nil
        }
        do {
            return try NSAttributedString(data: data,
           options: [
                     .documentType: NSAttributedString.DocumentType.html,
                     .characterEncoding: String.Encoding.utf8.rawValue
                    ], documentAttributes: nil)
        } catch {
            print(error.localizedDescription)
            return nil
        }
    }
}

extension UITextView {
   func setHtmlText(_ html: String) {
      if let attributedText = html.attributedHtmlString {
         self.attributedText = attributedText
      }
   }
}
 0
Author: Suhit Patil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-12 12:41:00