How do I decode HTML entities in Swift?

后端 未结 23 1910
一生所求
一生所求 2020-11-22 01:47

I am pulling a JSON file from a site and one of the strings received is:

The Weeknd ‘King Of The Fall&         


        
相关标签:
23条回答
  • 2020-11-22 02:40

    Objective-C

    +(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];
    }
    
    0 讨论(0)
  • 2020-11-22 02:41

    Swift 4


    • String extension computed variable
    • Without extra guard, do, catch, etc...
    • Returns the original strings if decoding fails

    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
        }
    }
    
    0 讨论(0)
  • 2020-11-22 02:41

    Computed var version of @yishus' answer

    public extension String {
        /// Decodes string with HTML encoding.
        var htmlDecoded: String {
            guard let encodedData = self.data(using: .utf8) else { return self }
    
            let attributedOptions: [String : Any] = [
                NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
                NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue]
    
            do {
                let attributedString = try NSAttributedString(data: encodedData,
                                                              options: attributedOptions,
                                                              documentAttributes: nil)
                return attributedString.string
            } catch {
                print("Error: \(error)")
                return self
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-22 02:42

    Swift 4 Version

    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
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-22 02:42

    Swift 3.0 version with actual font size conversion

    Normally, if you directly convert HTML content to an attributed string, the font size is increased. You can try to convert an HTML string to an attributed string and back again to see the difference.

    Instead, here is the actual size conversion that makes sure the font size does not change, by applying the 0.75 ratio on all fonts:

    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
        }
    }
    
    0 讨论(0)
  • 2020-11-22 02:44

    Swift 4.1 +

    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
    } 
    
    0 讨论(0)
提交回复
热议问题