28

As the title tells,now i can simple convert HTML into NSAttributedString with initWithHTML:documentAttributes: , but what i want to do here is reverse. Is there any 3rd party library to achieve this?

   @implementation NSAttributedString(HTML)
-(NSString *)htmlForAttributedString{
    NSArray * exclude = [NSArray arrayWithObjects:@"doctype",
                         @"html",
                         @"head",
                         @"body",
                         @"xml",
                         nil
                         ];
    NSDictionary * htmlAtt = [NSDictionary
                              dictionaryWithObjectsAndKeys:NSHTMLTextDocumentType,
                              NSDocumentTypeDocumentAttribute,
                              exclude,
                              NSExcludedElementsDocumentAttribute,
                              nil
                              ];
    NSError * error;
    NSData * htmlData = [self dataFromRange:NSMakeRange(0, [self length])
                               documentAttributes:htmlAtt error:&error
                         ];
        //NSAttributedString * htmlString = [[NSAttributedString alloc]initWithHTML:htmlData documentAttributes:&htmlAtt];
    NSString * htmlString = [[NSString alloc] initWithData:htmlData encoding:NSUTF8StringEncoding];
    return htmlString;
}
@end
2
  • 2
    The title asks how to convert HTML into NSAttributeString, while the question does vice-versa. Commented Mar 15, 2011 at 5:37
  • What exactly is the problem with the code you've posted? It should work. Commented Jan 4, 2013 at 21:16

3 Answers 3

45

Use dataFromRange:documentAttributes: with the document type attribute (NSDocumentTypeDocumentAttribute) set to HTML (NSHTMLTextDocumentType):

NSAttributedString *s = ...;
NSDictionary *documentAttributes = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};    
NSData *htmlData = [s dataFromRange:NSMakeRange(0, s.length) documentAttributes:documentAttributes error:NULL];
NSString *htmlString = [[NSString alloc] initWithData:htmlData encoding:NSUTF8StringEncoding];
Sign up to request clarification or add additional context in comments.

9 Comments

If the text contains link, than it wont create a href for the link.
I just need Bold, Italic, Underline & StrikeThrough tags in my HTML but converting NSAttributedString to HTML outputs a lot of css to achieve this. Any alternative to keep this simple?
@ilight . did u find the solution for getting HTML tags for bold italic & underline
The biggest problem that i am facing is, when i am using this, the font size of the content is getting increased, why i dont know but it almost getting doubled
Has anyone found a way to get cleaner/custom HTML out of the NSAttributedString.DocumentType.html conversion?
|
13

This is a swift 4 conversion of @omz answer, hope is useful to anyone landing here

extension NSAttributedString {
    var attributedString2Html: String? {
        do {
            let htmlData = try self.data(from: NSRange(location: 0, length: self.length), documentAttributes:[.documentType: NSAttributedString.DocumentType.html]);
            return String.init(data: htmlData, encoding: String.Encoding.utf8)
        } catch {
            print("error:", error)
            return nil
        }
    }
}

Comments

0

This should help to get the html string from Attributed String.

- (NSString *)htmlStringFromAttributedString:(NSAttributedString *)attributedString {
    NSMutableString *htmlString = [NSMutableString string];
    [htmlString appendString:@"<html><head></head><body>"];

    [attributedString enumerateAttributesInRange:NSMakeRange(0, attributedString.length) options:0 usingBlock:^(NSDictionary<NSAttributedStringKey,id> * _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) {
        NSString *text = [attributedString.string substringWithRange:range];
        
        // Start building HTML tags based on attributes
        if (attrs[NSFontAttributeName]) {
            UIFont *font = attrs[NSFontAttributeName];
            if ([font.fontName rangeOfString:@"Bold"].location != NSNotFound) {
                [htmlString appendString:@"<strong>"];
            }
            if ([font.fontName rangeOfString:@"Italic"].location != NSNotFound) {
                [htmlString appendString:@"<em>"];
            }
            if ([font.fontName rangeOfString:@"Oblique"].location != NSNotFound) {
                [htmlString appendString:@"<i>"];
            }
        }
        if (attrs[NSUnderlineStyleAttributeName]) {
            [htmlString appendString:@"<u>"];
        }

        // Append text
        [htmlString appendString:text];

        // Close HTML tags
        if (attrs[NSFontAttributeName]) {
            UIFont *font = attrs[NSFontAttributeName];
            if ([font.fontName rangeOfString:@"Bold"].location != NSNotFound) {
                [htmlString appendString:@"</strong>"];
            }
            if ([font.fontName rangeOfString:@"Italic"].location != NSNotFound) {
                [htmlString appendString:@"</em>"];
            }
            if ([font.fontName rangeOfString:@"Oblique"].location != NSNotFound) {
                [htmlString appendString:@"</i>"];
            }
        }
        if (attrs[NSUnderlineStyleAttributeName]) {
            [htmlString appendString:@"</u>"];
        }
    }];

    [htmlString appendString:@"</body></html>"];
    return htmlString;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.