Skip to content
dinhviethoa edited this page Nov 13, 2014 · 10 revisions

HTML Rendering

The three subclasses of MCOAbstractMessage (MCOIMAPMessage, MCOMessageParser, MCOMessageBuilder) each have html rendering APIs. HTML rendering of emails is actually a pretty complex operation. Emails come in many shapes and forms, and writing a single rendering engine for every application is difficult, and ultimately constricts you as the user. Instead, MailCore 2 uses HTML rendering delegates that you can use to compose a single html body out of a (potentially) complicated body structure.

The system as it is renders HTML in a generic format that should suit most purposes. You can get a rendered HTML version of the email to display to the user with one of the message classes with (example uses MCOMessageParser, though the other two children of MCOAbstractMessage work similarly).

You will need to download the message content for a MCOIMAPMessage it looks like this:

MCOIMAPSession *session; // get your session here
    
MCOIMAPFetchContentOperation *operation = [session fetchMessageByUIDOperationWithFolder:folder uid:message.uid];
    
[operation start:^(NSError *error, NSData *data) {
    MCOMessageParser *messageParser = [[MCOMessageParser alloc] initWithData:data];

    NSString *msgHTMLBody = [messageParser htmlRenderingWithDelegate:nil];
}];

Appendix A: Customizing Rendering

Although you likely will not need to, you can customize rendering HTML from a MCOAbstractMessage subclass (MCOMessageParser, MCOIMAPMessage, MCOMessageBuilder), by implementing the MCOHTMLRendererDelegate protocol. For each body part or attachment, you provide a delegate method that is able to provide a template, and the data to fit in that template. For example, here is one method pair for the main header:

- (NSString *)renderedHTMLWithParsedMessage:(MCOMessageParser *)parser {
    return [parser htmlRenderingWithDelegate:self];
}

- (NSString *)MCOAbstractMessage:(MCOAbstractMessage *)msg templateForMainHeader:(MCOMessageHeader *)header {
    return @"<div style=\\"background-color:#eee\\">\
    <div><b>From:</b> {{FROM}}</div>\
    <div><b>To:</b> {{TO}}</div>\
    </div>";
}

- (NSDictionary *)MCOAbstractMessage:(MCOAbstractMessage *)msg templateValuesForHeader:(MCOMessageHeader *)header {
    NSMutableDictionary *templateValues = [[NSMutableDictionary alloc] init];
    
    if(header.from) {
        templateValues[@"FROM"] = header.from.displayName ?: (header.from.mailbox ?: @"N/A");
    }
    
    if(header.to.count > 0) {
        NSMutableString *toString = [[NSMutableString alloc] init];
        for(MCOAddress *address in header.to) {
            if(toString.length > 0) {
                [toString appendString:@", "];
            }
            [toString appendFormat:@"%@", address.displayName ?: (address.mailbox ?: @"N/A")];
        }
        templateValues[@"TO"] = toString;
    }
    
    return templateValues;
}

As you can see, we use ctemplates in order to format and insert the data we want to display in different parts of the message.

Appendix B: Embedding images in the HTML content

Embedding images in the HTML