I'm getting a warning in the debugger in XCode: Incorrect NSStringEncoding value 0x8000100 detected when converting an NSAttributedString to html data. Not sure what is causing this or how to fix it. Here is my code:
let testString = NSAttributedString(string: "test")
let documentAttributes: [NSAttributedString.DocumentAttributeKey: Any] = [.documentType: NSAttributedString.DocumentType.html]
let htmlData = try? testString.data(from: NSRange(location: 0, length: testString.length), documentAttributes: documentAttributes)
The data does get created, but not sure why I'm getting the warning.
I finally figured out what was causing this. It seems that the string to data function wants some idea of what text encoding to use. Here is the fixed code which removes the debugger warning:
let testString = NSAttributedString(string: "test")
let documentAttributes: [NSAttributedString.DocumentAttributeKey: Any] = [.documentType: NSAttributedString.DocumentType.html, .characterEncoding:String.Encoding.utf8.rawValue]
let htmlData = try? testString.data(from: NSRange(location: 0, length: testString.length), documentAttributes: documentAttributes)
I have on WKInterfaceLabel in which i can not load HTML Tag like
<h1>Grishneshwar Jyotirling</h1>
and I can't use NSMutableAttributedString so please help me to finding regarding things.
var htmlText = "<h1>Grishneshwar Jyotirling</h1> Grishneshwar Jyotirling"
let attributeText: NSAttributedString?
if let htmlData = htmlText.dataUsingEncoding(NSUnicodeStringEncoding) {
do {
attributeText = try NSAttributedString(data: htmlData , options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil)
myLabel.setAttributedText(attributeText)
}catch let e as NSError {
print("Couldn't translate \(htmlText): \(e.localizedDescription) ")
}
I want to be able to edit the HTML I get from my api request, changing the font and increasing among other things.
let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, error) in
var dataString:String = NSString(data: data, encoding: NSUTF8StringEncoding)! as String
dispatch_async(dispatch_get_main_queue()) {
var attributedString:NSAttributedString = NSAttributedString(data: data, options:[NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: NSUTF8StringEncoding], documentAttributes: nil, error: nil)!
self.textView.attributedText = attributedString
}
}
To access the properties correctly you should be using an NSMutableAttributeString.
Change your String instantiation to this:
var attributedString: NSMutableAttributedString = NSMutableAttributedString(data: data, options:[NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: NSUTF8StringEncoding], documentAttributes: nil, error: nil)!
And add an attribute like so:
mutableString.addAttribute(NSFontAttributeName, value: UIFont(name: "Avenir", size: 18.0)!, range: NSRange(location:2,length:4))
This is just an example, you can create your own attributes to suit your needs.
In Swift, I Decoding HTML using NSAttributedString, see below:
let encodedString = "Phải công nhận rằng kể từ lúc ông Thăng làm bộ trưởng"
let encodedData = encodedString.dataUsingEncoding(NSUTF8StringEncoding)
let attributedOptions = [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType]
let attributedString = NSAttributedString(data: encodedData, options: attributedOptions, documentAttributes: nil, error: nil)
let decodedString = attributedString.string
println(decodedString)
But the result like this:
Phải công nháºn rằng kể từ lúc ông Thăng là m bá»™
trưởng
The true result must be the same with the encodedString
What's wrong in this method?
You have to specify the used character encoding in the document options:
let encodedString = "Phải công nhận rằng kể từ lúc ông Thăng làm bộ trưởng"
let encodedData = encodedString.data(using: .utf8)!
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)
let decodedString = attributedString.string
print(decodedString)
} catch {
// error ...
}
// Output: Phải công nhận rằng kể từ lúc ông Thăng làm bộ trưởng
(Updated for Swift 4)
I would like to display html formatted text on a UILabel in IOS.
In Android, it has api like this .setText(Html.fromHtml(somestring));
Set TextView text from html-formatted string resource in XML
I would like to know what / if there is an equivalent in ios?
I search and find this thread:
How to show HTML text from API on the iPhone?
But it suggests using UIWebView. I need to display html formatted string in each table cell, so I think have 1 webview per row seems a bit heavy.
Is that any other alternative?
Thank you.
Swift 3.0
do {
let attrStr = try NSAttributedString(
data: "<b><i>text</i></b>".data(using: String.Encoding.unicode, allowLossyConversion: true)!,
options: [ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
documentAttributes: nil)
label.attributedText = attrStr
} catch let error {
}
for Swift 2.0:
var attrStr = try! NSAttributedString(
data: "<b><i>text</i></b>".dataUsingEncoding(NSUnicodeStringEncoding, allowLossyConversion: true)!,
options: [ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
documentAttributes: nil)
label.attributedText = attrStr
Swift 4
import UIKit
let htmlString = "<html><body> Some <b>html</b> string </body></html>"
// works even without <html><body> </body></html> tags, BTW
let data = htmlString.data(using: String.Encoding.unicode)! // mind "!"
let attrStr = try? NSAttributedString( // do catch
data: data,
options: [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html],
documentAttributes: nil)
// suppose we have an UILabel, but any element with NSAttributedString will do
label.attributedText = attrStr
Supplement: controlling the font of resulting formatted string
To use properly scaled (i.e. with respect to user settings) system (or any other) font you may do the following.
let newFont = UIFontMetrics.default.scaledFont(for: UIFont.systemFont(ofSize: UIFont.systemFontSize)) // The same is possible for custom font.
let mattrStr = NSMutableAttributedString(attributedString: attrStr!)
mattrStr.beginEditing()
mattrStr.enumerateAttribute(.font, in: NSRange(location: 0, length: mattrStr.length), options: .longestEffectiveRangeNotRequired) { (value, range, _) in
if let oFont = value as? UIFont, let newFontDescriptor = oFont.fontDescriptor.withFamily(newFont.familyName).withSymbolicTraits(oFont.fontDescriptor.symbolicTraits) {
let nFont = UIFont(descriptor: newFontDescriptor, size: newFont.pointSize)
mattrStr.removeAttribute(.font, range: range)
mattrStr.addAttribute(.font, value: nFont, range: range)
}
}
mattrStr.endEditing()
label.attributedText = mattrStr
You could try an attributed string:
var attrStr = NSAttributedString(
data: "<b><i>text</i></b>".dataUsingEncoding(NSUnicodeStringEncoding, allowLossyConversion: true),
options: [ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
documentAttributes: nil,
error: nil)
label.attributedText = attrStr
Objective-C Version:
NSError *error = nil;
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithData:contentData
options:#{NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType}
documentAttributes:nil error:&error];
This is just the Objective-C conversion of the above answers. All the answers above are right and reference taken from the above answers for this.
For me, Paul's answer worked. But for custom fonts I had to put following hack.
//Please take care of force unwrapping
let data = htmlString.data(using: String.Encoding.unicode)!
let mattrStr = try! NSMutableAttributedString(
data: data,
options: [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html],
documentAttributes: nil)
let normalFont = UIFontMetrics.default.scaledFont(for: UIFont(name: "NormalFontName", size: 15.0)!)//
let boldFont = UIFontMetrics.default.scaledFont(for: UIFont(name: "BoldFontName", size: 15.0)!)
mattrStr.beginEditing()
mattrStr.enumerateAttribute(.font, in: NSRange(location: 0, length: mattrStr.length), options: .longestEffectiveRangeNotRequired) { (value, range, _) in
if let oFont = value as? UIFont{
mattrStr.removeAttribute(.font, range: range)
if oFont.fontName.contains("Bold"){
mattrStr.addAttribute(.font, value: boldFont, range: range)
}
else{
mattrStr.addAttribute(.font, value: normalFont, range: range)
}
}
}
Try this:
let label : UILable! = String.stringFromHTML("html String")
func stringFromHTML( string: String?) -> String
{
do{
let str = try NSAttributedString(data:string!.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true
)!, options:[NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: NSNumber(unsignedLong: NSUTF8StringEncoding)], documentAttributes: nil)
return str.string
} catch
{
print("html error\n",error)
}
return ""
}
Hope its helpful.