Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Json 如何在Swift中解码HTML实体?_Json_Swift_Html Entities - Fatal编程技术网

Json 如何在Swift中解码HTML实体?

Json 如何在Swift中解码HTML实体?,json,swift,html-entities,Json,Swift,Html Entities,我正在从一个站点提取一个JSON文件,收到的字符串之一是: 周末&8216;秋天的国王’;[视频首映式]|@TheWeeknd |#SoPhi 如何将‘之类的内容转换为正确的字符 我制作了一个Xcode游乐场来演示它: import UIKit var error: NSError? let blogUrl: NSURL = NSURL.URLWithString("http://sophisticatedignorance.net/api/get_recent_summ

我正在从一个站点提取一个JSON文件,收到的字符串之一是:

周末&8216;秋天的国王’;[视频首映式]|@TheWeeknd |#SoPhi
如何将
之类的内容转换为正确的字符

我制作了一个Xcode游乐场来演示它:

import UIKit

var error: NSError?
let blogUrl: NSURL = NSURL.URLWithString("http://sophisticatedignorance.net/api/get_recent_summary/")
let jsonData = NSData(contentsOfURL: blogUrl)

let dataDictionary = NSJSONSerialization.JSONObjectWithData(jsonData, options: nil, error: &error) as NSDictionary

var a = dataDictionary["posts"] as NSArray

println(a[0]["title"])
该答案最近一次针对Swift 5.2和iOS 13.4 SDK进行了修订


没有简单的方法可以做到这一点,但您可以使用
NSAttributedString
magic使这个过程尽可能轻松(请注意,此方法也会剥离所有HTML标记)

请记住仅从主线程初始化
NSAttributedString
。它使用WebKit来解析下面的HTML,从而满足需求

//这是您的[0][“title”]
让encodedString=“周末&8216;秋天之王&8217;”
guard let data=htmlEncodedString.data(使用:.utf8)else{
返回
}
let选项:[NSAttributedString.DocumentReadingOptionKey:Any]=[
.documentType:nsAttributeString.documentType.html,
.characterEncoding:String.Encoding.utf8.rawValue
]
guard let attributedString=try?NSAttribute字符串(数据:数据,选项:选项,文档属性:nil)其他{
返回
}
//本周的“秋天之王”
让decodedString=attributedString.string
扩展字符串{
init?(htmlEncodedString:String){
guard let data=htmlEncodedString.data(使用:.utf8)else{
归零
}
let选项:[NSAttributedString.DocumentReadingOptionKey:Any]=[
.documentType:nsAttributeString.documentType.html,
.characterEncoding:String.Encoding.utf8.rawValue
]
guard let attributedString=try?NSAttributedString(数据:数据,选项:选项,文档属性:nil)else{
归零
}
self.init(attributedString.string)
}
}
让encodedString=“周末&8216;秋天之王&8217;”
让decodedString=String(htmlEncodedString:encodedString)

@akashivsky的答案很好,并演示了如何利用
NSAttributedString
解码HTML实体。一个可能的缺点 (正如他所说)是所有的HTML标记也被删除了,所以

<strong> 4 &lt; 5 &amp; 3 &gt; 2</strong>
但这在iOS上不可用

这里是一个纯粹的Swift实现。它解码字符实体 引用,如使用字典的
,以及所有数字字符 像
&64
&x20ac
这样的实体。(请注意,我没有列出所有 252个HTML实体。)


Swift 4:

// Mapping from XML/HTML character entity reference to character
// From http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references
private let characterEntities : [ Substring : Character ] = [
    // XML predefined entities:
    "&quot;"    : "\"",
    "&amp;"     : "&",
    "&apos;"    : "'",
    "&lt;"      : "<",
    "&gt;"      : ">",

    // HTML character entity references:
    "&nbsp;"    : "\u{00a0}",
    // ...
    "&diams;"   : "♦",
]

extension String {

    /// Returns a new string made by replacing in the `String`
    /// all HTML character entity references with the corresponding
    /// character.
    var stringByDecodingHTMLEntities : String {

        // ===== Utility functions =====

        // Convert the number in the string to the corresponding
        // Unicode character, e.g.
        //    decodeNumeric("64", 10)   --> "@"
        //    decodeNumeric("20ac", 16) --> "€"
        func decodeNumeric(_ string : Substring, base : Int) -> Character? {
            guard let code = UInt32(string, radix: base),
                let uniScalar = UnicodeScalar(code) else { return nil }
            return Character(uniScalar)
        }

        // Decode the HTML character entity to the corresponding
        // Unicode character, return `nil` for invalid input.
        //     decode("&#64;")    --> "@"
        //     decode("&#x20ac;") --> "€"
        //     decode("&lt;")     --> "<"
        //     decode("&foo;")    --> nil
        func decode(_ entity : Substring) -> Character? {

            if entity.hasPrefix("&#x") || entity.hasPrefix("&#X") {
                return decodeNumeric(entity.dropFirst(3).dropLast(), base: 16)
            } else if entity.hasPrefix("&#") {
                return decodeNumeric(entity.dropFirst(2).dropLast(), base: 10)
            } else {
                return characterEntities[entity]
            }
        }

        // ===== Method starts here =====

        var result = ""
        var position = startIndex

        // Find the next '&' and copy the characters preceding it to `result`:
        while let ampRange = self[position...].range(of: "&") {
            result.append(contentsOf: self[position ..< ampRange.lowerBound])
            position = ampRange.lowerBound

            // Find the next ';' and copy everything from '&' to ';' into `entity`
            guard let semiRange = self[position...].range(of: ";") else {
                // No matching ';'.
                break
            }
            let entity = self[position ..< semiRange.upperBound]
            position = semiRange.upperBound

            if let decoded = decode(entity) {
                // Replace by decoded character:
                result.append(decoded)
            } else {
                // Invalid entity, copy verbatim:
                result.append(contentsOf: entity)
            }
        }
        // Copy remaining characters to `result`:
        result.append(contentsOf: self[position...])
        return result
    }
}
// Mapping from XML/HTML character entity reference to character
// From http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references
private let characterEntities : [ String : Character ] = [
    // XML predefined entities:
    "&quot;"    : "\"",
    "&amp;"     : "&",
    "&apos;"    : "'",
    "&lt;"      : "<",
    "&gt;"      : ">",

    // HTML character entity references:
    "&nbsp;"    : "\u{00a0}",
    // ...
    "&diams;"   : "♦",
]

extension String {

    /// Returns a new string made by replacing in the `String`
    /// all HTML character entity references with the corresponding
    /// character.
    var stringByDecodingHTMLEntities : String {

        // ===== Utility functions =====

        // Convert the number in the string to the corresponding
        // Unicode character, e.g.
        //    decodeNumeric("64", 10)   --> "@"
        //    decodeNumeric("20ac", 16) --> "€"
        func decodeNumeric(_ string : String, base : Int) -> Character? {
            guard let code = UInt32(string, radix: base),
                let uniScalar = UnicodeScalar(code) else { return nil }
            return Character(uniScalar)
        }

        // Decode the HTML character entity to the corresponding
        // Unicode character, return `nil` for invalid input.
        //     decode("&#64;")    --> "@"
        //     decode("&#x20ac;") --> "€"
        //     decode("&lt;")     --> "<"
        //     decode("&foo;")    --> nil
        func decode(_ entity : String) -> Character? {

            if entity.hasPrefix("&#x") || entity.hasPrefix("&#X"){
                return decodeNumeric(entity.substring(with: entity.index(entity.startIndex, offsetBy: 3) ..< entity.index(entity.endIndex, offsetBy: -1)), base: 16)
            } else if entity.hasPrefix("&#") {
                return decodeNumeric(entity.substring(with: entity.index(entity.startIndex, offsetBy: 2) ..< entity.index(entity.endIndex, offsetBy: -1)), base: 10)
            } else {
                return characterEntities[entity]
            }
        }

        // ===== Method starts here =====

        var result = ""
        var position = startIndex

        // Find the next '&' and copy the characters preceding it to `result`:
        while let ampRange = self.range(of: "&", range: position ..< endIndex) {
            result.append(self[position ..< ampRange.lowerBound])
            position = ampRange.lowerBound

            // Find the next ';' and copy everything from '&' to ';' into `entity`
            if let semiRange = self.range(of: ";", range: position ..< endIndex) {
                let entity = self[position ..< semiRange.upperBound]
                position = semiRange.upperBound

                if let decoded = decode(entity) {
                    // Replace by decoded character:
                    result.append(decoded)
                } else {
                    // Invalid entity, copy verbatim:
                    result.append(entity)
                }
            } else {
                // No matching ';'.
                break
            }
        }
        // Copy remaining characters to `result`:
        result.append(self[position ..< endIndex])
        return result
    }
}
// Mapping from XML/HTML character entity reference to character
// From http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references
private let characterEntities : [ String : Character ] = [
    // XML predefined entities:
    "&quot;"    : "\"",
    "&amp;"     : "&",
    "&apos;"    : "'",
    "&lt;"      : "<",
    "&gt;"      : ">",

    // HTML character entity references:
    "&nbsp;"    : "\u{00a0}",
    // ...
    "&diams;"   : "♦",
]

extension String {

    /// Returns a new string made by replacing in the `String`
    /// all HTML character entity references with the corresponding
    /// character.
    var stringByDecodingHTMLEntities : String {

        // ===== Utility functions =====

        // Convert the number in the string to the corresponding
        // Unicode character, e.g.
        //    decodeNumeric("64", 10)   --> "@"
        //    decodeNumeric("20ac", 16) --> "€"
        func decodeNumeric(string : String, base : Int32) -> Character? {
            let code = UInt32(strtoul(string, nil, base))
            return Character(UnicodeScalar(code))
        }

        // Decode the HTML character entity to the corresponding
        // Unicode character, return `nil` for invalid input.
        //     decode("&#64;")    --> "@"
        //     decode("&#x20ac;") --> "€"
        //     decode("&lt;")     --> "<"
        //     decode("&foo;")    --> nil
        func decode(entity : String) -> Character? {

            if entity.hasPrefix("&#x") || entity.hasPrefix("&#X"){
                return decodeNumeric(entity.substringFromIndex(entity.startIndex.advancedBy(3)), base: 16)
            } else if entity.hasPrefix("&#") {
                return decodeNumeric(entity.substringFromIndex(entity.startIndex.advancedBy(2)), base: 10)
            } else {
                return characterEntities[entity]
            }
        }

        // ===== Method starts here =====

        var result = ""
        var position = startIndex

        // Find the next '&' and copy the characters preceding it to `result`:
        while let ampRange = self.rangeOfString("&", range: position ..< endIndex) {
            result.appendContentsOf(self[position ..< ampRange.startIndex])
            position = ampRange.startIndex

            // Find the next ';' and copy everything from '&' to ';' into `entity`
            if let semiRange = self.rangeOfString(";", range: position ..< endIndex) {
                let entity = self[position ..< semiRange.endIndex]
                position = semiRange.endIndex

                if let decoded = decode(entity) {
                    // Replace by decoded character:
                    result.append(decoded)
                } else {
                    // Invalid entity, copy verbatim:
                    result.appendContentsOf(entity)
                }
            } else {
                // No matching ';'.
                break
            }
        }
        // Copy remaining characters to `result`:
        result.appendContentsOf(self[position ..< endIndex])
        return result
    }
}
let yourStringEncoded = yourStringWithHtmlcode.htmlDecoded
//从XML/HTML字符实体引用到字符的映射
//从http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references
私有let characterEntities:[子字符串:字符]=[
//XML预定义实体:
"""    : "\"",
“&;”:“&”,
“&apos;”:“”,
""      : "",
//HTML字符实体引用:
“”:“\u{00a0}”,
// ...
“&diams;”:”♦",
]
扩展字符串{
///返回通过在`字符串中替换而生成的新字符串`
///所有HTML字符实体引用都具有相应的
///性格。
var stringByDecodingHTMLEntities:String{
//====实用程序功能=====
//将字符串中的数字转换为相应的数字
//Unicode字符,例如。
//解码数字(“64”,10)-->“@”
//解码数字(“20ac”,16)-->“€”
func decodeNumeric(uString:Substring,base:Int)->字符{
guard let code=UInt32(字符串,基数:基数),
让uniScalar=UnicodeScalar(code)else{return nil}
返回字符(uniScalar)
}
//将HTML字符实体解码为相应的
//Unicode字符,对于无效输入返回'nil'。
//解码(@;“”-->“@”
//解码(€;“”-->“€”

//解码(“”-->“这将是我的方法。您可以添加Michael瀑布提到的实体词典

extension String {
    func htmlDecoded()->String {

        guard (self != "") else { return self }

        var newStr = self

        let entities = [
            "&quot;"    : "\"",
            "&amp;"     : "&",
            "&apos;"    : "'",
            "&lt;"      : "<",
            "&gt;"      : ">",
        ]

        for (name,value) in entities {
            newStr = newStr.stringByReplacingOccurrencesOfString(name, withString: value)
        }
        return newStr
    }
}


Swift 2版本

使用:


Swift 3版本


我正在寻找一个纯Swift 3.0实用程序,以从HTML字符引用(即macOS和Linux上的服务器端Swift应用程序)转义到/unescape,但没有找到任何全面的解决方案,因此我编写了自己的实现:

该包名为
HTMLEntities
,可与HTML4命名字符引用以及十六进制/十二进制数字字符引用一起使用,它将根据W3 HTML5规范识别特殊的数字字符引用(即
和#x80;
应不替换为欧元符号(unicode
U+20AC
)而不是作为
U+0080
的unicode字符,并且在取消切换时,某些范围的数字字符引用应替换为替换字符
U+FFFD

用法示例:

import HTMLEntities

// encode example
let html = "<script>alert(\"abc\")</script>"

print(html.htmlEscape())
// Prints ”&lt;script&gt;alert(&quot;abc&quot;)&lt;/script&gt;"

// decode example
let htmlencoded = "&lt;script&gt;alert(&quot;abc&quot;)&lt;/script&gt;"

print(htmlencoded.htmlUnescape())
// Prints ”<script>alert(\"abc\")</script>"

编辑:
HTMLEntities
从2.0.0版开始,现在支持HTML5命名字符引用。还实现了符合规范的解析。

更新了Swift 3上的答案

extension String {
    init?(htmlEncodedString: String) {
        let encodedData = htmlEncodedString.data(using: String.Encoding.utf8)!
        let attributedOptions = [ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType]

        guard let attributedString = try? NSAttributedString(data: encodedData, options: attributedOptions, documentAttributes: nil) else {
            return nil
        }
        self.init(attributedString.string)
   }
计算的var版本

具有实际字体大小转换的Swift 3.0版本 通常,如果您直接将HTML内容转换为属性字符串,则字体大小会增加。您可以尝试将HTML字符串转换为属性字符串,然后再次转换以查看差异

相反,这里是实际大小转换,通过在所有字体上应用0.75的比例,确保字体大小不会改变:

extension String {
    func htmlAttributedString() -> NSAttributedString? {
        guard let data = self.data(using: String.Encoding.utf16, allowLossyConversion: false) else { return nil }
        guard let attriStr = try? NSMutableAttributedString(
            data: data,
            options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
            documentAttributes: nil) else { return nil }
        attriStr.beginEditing()
        attriStr.enumerateAttribute(NSFontAttributeName, in: NSMakeRange(0, attriStr.length), options: .init(rawValue: 0)) {
            (value, range, stop) in
            if let font = value as? UIFont {
                let resizedFont = font.withSize(font.pointSize * 0.75)
                attriStr.addAttribute(NSFontAttributeName,
                                         value: resizedFont,
                                         range: range)
            }
        }
        attriStr.endEditing()
        return attriStr
    }
}
Swift 4版本
Swift 4

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

    mutating func toHtmlEncodedString() {
        guard let encodedData = self.data(using: .utf8) else {
            return
        }

        let attributedOptions: [NSAttributedString.DocumentReadingOptionKey : Any] = [
            NSAttributedString.DocumentReadingOptionKey(rawValue: NSAttributedString.DocumentAttributeKey.documentType.rawValue): NSAttributedString.DocumentType.html,
            NSAttributedString.DocumentReadingOptionKey(rawValue: NSAttributedString.DocumentAttributeKey.characterEncoding.rawValue): String.Encoding.utf8.rawValue
        ]

        do {
            let attributedString = try NSAttributedString(data: encodedData, options: attributedOptions, documentAttributes: nil)
            self = attributedString.string
        }
        catch {
            print("Error: \(error)")
        }
    }
func decodeHTML(string: String) -> String? {

    var decodedString: String?

    if let encodedData = string.data(using: .utf8) {
        let attributedOptions: [NSAttributedString.DocumentReadingOptionKey : Any] = [
            .documentType: NSAttributedString.DocumentType.html,
            .characterEncoding: String.Encoding.utf8.rawValue
        ]

        do {
            decodedString = try NSAttributedString(data: encodedData, options: attributedOptions, documentAttributes: nil).string
        } catch {
            print("\(error.localizedDescription)")
        }
    }

    return decodedString
}
简单用法

let clean = "Weeknd &#8216;King Of The Fall&#8217".replacingHTMLEntities ?? "default value"

Swift 4

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

    mutating func toHtmlEncodedString() {
        guard let encodedData = self.data(using: .utf8) else {
            return
        }

        let attributedOptions: [NSAttributedString.DocumentReadingOptionKey : Any] = [
            NSAttributedString.DocumentReadingOptionKey(rawValue: NSAttributedString.DocumentAttributeKey.documentType.rawValue): NSAttributedString.DocumentType.html,
            NSAttributedString.DocumentReadingOptionKey(rawValue: NSAttributedString.DocumentAttributeKey.characterEncoding.rawValue): String.Encoding.utf8.rawValue
        ]

        do {
            let attributedString = try NSAttributedString(data: encodedData, options: attributedOptions, documentAttributes: nil)
            self = attributedString.string
        }
        catch {
            print("Error: \(error)")
        }
    }
func decodeHTML(string: String) -> String? {

    var decodedString: String?

    if let encodedData = string.data(using: .utf8) {
        let attributedOptions: [NSAttributedString.DocumentReadingOptionKey : Any] = [
            .documentType: NSAttributedString.DocumentType.html,
            .characterEncoding: String.Encoding.utf8.rawValue
        ]

        do {
            decodedString = try NSAttributedString(data: encodedData, options: attributedOptions, documentAttributes: nil).string
        } catch {
            print("\(error.localizedDescription)")
        }
    }

    return decodedString
}

Swift 4

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

    mutating func toHtmlEncodedString() {
        guard let encodedData = self.data(using: .utf8) else {
            return
        }

        let attributedOptions: [NSAttributedString.DocumentReadingOptionKey : Any] = [
            NSAttributedString.DocumentReadingOptionKey(rawValue: NSAttributedString.DocumentAttributeKey.documentType.rawValue): NSAttributedString.DocumentType.html,
            NSAttributedString.DocumentReadingOptionKey(rawValue: NSAttributedString.DocumentAttributeKey.characterEncoding.rawValue): String.Encoding.utf8.rawValue
        ]

        do {
            let attributedString = try NSAttributedString(data: encodedData, options: attributedOptions, documentAttributes: nil)
            self = attributedString.string
        }
        catch {
            print("Error: \(error)")
        }
    }
func decodeHTML(string: String) -> String? {

    var decodedString: String?

    if let encodedData = string.data(using: .utf8) {
        let attributedOptions: [NSAttributedString.DocumentReadingOptionKey : Any] = [
            .documentType: NSAttributedString.DocumentType.html,
            .characterEncoding: String.Encoding.utf8.rawValue
        ]

        do {
            decodedString = try NSAttributedString(data: encodedData, options: attributedOptions, documentAttributes: nil).string
        } catch {
            print("\(error.localizedDescription)")
        }
    }

    return decodedString
}

  • 字符串扩展计算变量
  • 没有额外的保护、做、抓等
  • 如果解码失败,则返回原始字符串
  • <
    extension String {
    
        init(htmlEncodedString: String) {
            self.init()
            guard let encodedData = htmlEncodedString.data(using: .utf8) else {
                self = htmlEncodedString
                return
            }
    
            let attributedOptions: [NSAttributedString.DocumentReadingOptionKey : Any] = [
                .documentType: NSAttributedString.DocumentType.html,
                .characterEncoding: String.Encoding.utf8.rawValue
            ]
    
            do {
                let attributedString = try NSAttributedString(data: encodedData, options: attributedOptions, documentAttributes: nil)
                self = attributedString.string
            } 
            catch {
                print("Error: \(error)")
                self = htmlEncodedString
            }
        }
    }
    
    extension String {
        var replacingHTMLEntities: String? {
            do {
                return try NSAttributedString(data: Data(utf8), options: [
                    .documentType: NSAttributedString.DocumentType.html,
                    .characterEncoding: String.Encoding.utf8.rawValue
                ], documentAttributes: nil).string
            } catch {
                return nil
            }
        }
    }
    
    let clean = "Weeknd &#8216;King Of The Fall&#8217".replacingHTMLEntities ?? "default value"
    
    extension String {
    
        mutating func toHtmlEncodedString() {
            guard let encodedData = self.data(using: .utf8) else {
                return
            }
    
            let attributedOptions: [NSAttributedString.DocumentReadingOptionKey : Any] = [
                NSAttributedString.DocumentReadingOptionKey(rawValue: NSAttributedString.DocumentAttributeKey.documentType.rawValue): NSAttributedString.DocumentType.html,
                NSAttributedString.DocumentReadingOptionKey(rawValue: NSAttributedString.DocumentAttributeKey.characterEncoding.rawValue): String.Encoding.utf8.rawValue
            ]
    
            do {
                let attributedString = try NSAttributedString(data: encodedData, options: attributedOptions, documentAttributes: nil)
                self = attributedString.string
            }
            catch {
                print("Error: \(error)")
            }
        }
    
    extension String {
        var htmlDecoded: String {
            let decoded = try? NSAttributedString(data: Data(utf8), options: [
                .documentType: NSAttributedString.DocumentType.html,
                .characterEncoding: String.Encoding.utf8.rawValue
            ], documentAttributes: nil).string
    
            return decoded ?? self
        }
    }
    
    myString = String(htmlString: encodedString)
    
    extension String {
    
        init(htmlString: String) {
            self.init()
            guard let encodedData = htmlString.data(using: .utf8) else {
                self = htmlString
                return
            }
    
            let attributedOptions: [NSAttributedString.DocumentReadingOptionKey : Any] = [
               .documentType: NSAttributedString.DocumentType.html,
               .characterEncoding: String.Encoding.utf8.rawValue
            ]
    
            do {
                let attributedString = try NSAttributedString(data: encodedData,
                                                              options: attributedOptions,
                                                              documentAttributes: nil)
                self = attributedString.string
            } catch {
                print("Error: \(error.localizedDescription)")
                self = htmlString
            }
        }
    }
    
    textField.attributedText = try? NSAttributedString(htmlString: encodedString)
    
    extension NSAttributedString {
    
        convenience init(htmlString html: String) throws {
            try self.init(data: Data(html.utf8), options: [
                .documentType: NSAttributedString.DocumentType.html,
                .characterEncoding: String.Encoding.utf8.rawValue
                ], documentAttributes: nil)
        }
    
    }
    
    func decodeHTML(string: String) -> String? {
    
        var decodedString: String?
    
        if let encodedData = string.data(using: .utf8) {
            let attributedOptions: [NSAttributedString.DocumentReadingOptionKey : Any] = [
                .documentType: NSAttributedString.DocumentType.html,
                .characterEncoding: String.Encoding.utf8.rawValue
            ]
    
            do {
                decodedString = try NSAttributedString(data: encodedData, options: attributedOptions, documentAttributes: nil).string
            } catch {
                print("\(error.localizedDescription)")
            }
        }
    
        return decodedString
    }
    
    extension String {
        var htmlDecoded: String {
            let decoded = try? NSAttributedString(data: Data(utf8), options: [
                .documentType: NSAttributedString.DocumentType.html,
                .characterEncoding: String.Encoding.utf8.rawValue
                ], documentAttributes: nil).string
    
            return decoded ?? self
        }
    }
    
    let yourStringEncoded = yourStringWithHtmlcode.htmlDecoded
    
    var yourNewString = String(yourStringEncoded.filter { !"\n\t\r".contains($0) })
    yourNewString = yourNewString.replacingOccurrences(of: "\'", with: "", options: NSString.CompareOptions.literal, range: nil)
    
    var htmlDecoded: String {
    
    
        let attributedOptions: [NSAttributedString.DocumentReadingOptionKey : Any] = [
    
            NSAttributedString.DocumentReadingOptionKey.documentType : NSAttributedString.DocumentType.html,
            NSAttributedString.DocumentReadingOptionKey.characterEncoding : String.Encoding.utf8.rawValue
        ]
    
    
        let decoded = try? NSAttributedString(data: Data(utf8), options: attributedOptions
            , documentAttributes: nil).string
    
        return decoded ?? self
    } 
    
    +(NSString *) decodeHTMLEnocdedString:(NSString *)htmlEncodedString {
        if (!htmlEncodedString) {
            return nil;
        }
    
        NSData *data = [htmlEncodedString dataUsingEncoding:NSUTF8StringEncoding];
        NSDictionary *attributes = @{NSDocumentTypeDocumentAttribute:     NSHTMLTextDocumentType,
                                 NSCharacterEncodingDocumentAttribute:     @(NSUTF8StringEncoding)};
        NSAttributedString *attributedString = [[NSAttributedString alloc]     initWithData:data options:attributes documentAttributes:nil error:nil];
        return [attributedString string];
    }
    
    import UIKit
    
    extension String {
    
        init(htmlEncodedString: String) {
            self.init()
            guard let encodedData = htmlEncodedString.data(using: .utf8) else {
                self = htmlEncodedString
                return
            }
    
            let attributedOptions: [NSAttributedString.DocumentReadingOptionKey : Any] = [
                .documentType: NSAttributedString.DocumentType.html,
                .characterEncoding: String.Encoding.utf8.rawValue
            ]
    
            do {
                let attributedString = try NSAttributedString(data: encodedData, options: attributedOptions, documentAttributes: nil)
                self = attributedString.string
            } 
            catch {
                print("Error: \(error)")
                self = htmlEncodedString
            }
        }
    }