aboutsummaryrefslogtreecommitdiffhomepage
path: root/README.md
diff options
context:
space:
mode:
authorGravatar Oliver Clark Rickard <ocrickard@runway20.com>2013-05-28 15:05:53 -0600
committerGravatar Oliver Clark Rickard <ocrickard@runway20.com>2013-05-28 15:05:53 -0600
commit3c1f53c0556428fcc97f7a9f1f41f83527be362a (patch)
treeee9ae00a7cfb29e38074e83af2708fbd6f48ec37 /README.md
parentc1d65d644f5941421014900e1fbaad730cbe81a2 (diff)
Moved Quickstart guide into readme.
Diffstat (limited to 'README.md')
-rw-r--r--README.md147
1 files changed, 129 insertions, 18 deletions
diff --git a/README.md b/README.md
index 4406a808..72df3eee 100644
--- a/README.md
+++ b/README.md
@@ -1,27 +1,138 @@
-## Mailcore 2
+## Mailcore 2: Introduction ##
-MailCore 2 brings a new API redesigned from ground.
+MailCore 2 brings a new API designed from the ground up to be fast, portable, and asynchronous. It features:
-- POP, IMAP and SMTP support
-- RFC822 parser and generator
-- asynchronous APIs
-- HTML rendering of messages
+- **POP**, **IMAP** and **SMTP** support
+- **[RFC822](http://www.ietf.org/rfc/rfc0822.txt)** parser and generator
+- **Asynchronous** APIs
+- **HTML** rendering of messages
+- **iOS** and **Mac** support
-## Quick project setup instruction
+## Installation ##
-### Mac framework
+1. Checkout MailCore2 into a directory relative to your project.
+2. Under the `build-mac` directory, locate the `mailcore2.xcodeproj` file, and drag this into your Xcode project.
+3. **For Mac** - If you're building for Mac, you can either link against MailCore 2 as a framework, or as a static library:
+ * Mac framework
+ - Go to Build Phases from your build target, and under 'Link Binary With Libraries', add `MailCore.framework`.
+ - Make sure to use LLVM C++ standard library. Open Build Settings, scroll down to 'C++ Standard Library', and select `libc++`.
+ - In Build Phases, add a Target Dependency of `mailcore osx` (it's the one with a little toolbox icon).
+ * Mac static library
+ - Go to Build Phases from your build target, and under 'Link Binary With Libraries', add `libMailCore.a`.
+ - Set 'Other Linker Flags' under Build Settings: `-lctemplate -letpan -licudata -licui18n -licuuc -lxml2 -lsasl2 -liconv -ltidy -lc++ -all_load`
+ - Make sure to use LLVM C++ standard library. In Build Settings, locate 'C++ Standard Library', and select `libc++`.
+ - In Build Phases, add a Target Dependency of `static mailcore2 osx`.
+4. **For iOS** - If you're targeting iOS, you have to link against MailCore 2 as a static library:
+ * Add `libMailCore-ios.a`
+ * Set 'Other Linker Flags': `-lctemplate-ios -letpan-ios -licudata -licui18n -licuuc -lxml2 -lsasl2 -liconv -ltidy -lstdc++ -all_load`
+ * Make sure to use GNU C++ standard library. In Build Settings, locate 'C++ Standard Library', and select `libstdc++`.
+ * In Build Phases, add a Target Dependency of `static mailcore2 ios`.
+5. Profit.
-- Add mailcore.framework
-- Make sure to use LLVM C++ standard library.
+## Basic IMAP Usage ##
-### Mac static library
+### Asynchrony ###
-- Add libMailCore.a
-- Set "Other Linker Flags": `-lctemplate -letpan -licudata -licui18n -licuuc -lxml2 -lsasl2 -liconv -ltidy -lc++ -all_load`
-- Make sure to use LLVM C++ standard library.
+Using MailCore 2 is just a little more complex conceptually than the original MailCore. All fetch requests in MailCore 2 are made asynchronously through a queue. What does this mean? Well, let's take a look at a simple example:
-### iOS static library
+```objc
+ MCOIMAPSession *session = [[MCOIMAPSession alloc] init];
+ [session setHostname:@"imap.gmail.com"];
+ [session setPort:993];
+ [session setUsername:@"ADDRESS@gmail.com"];
+ [session setPassword:@"123456"];
+ [session setConnectionType:MCOConnectionTypeTLS];
-- Add libMailCore-ios.a
-- Set "Other Linker Flags": `lctemplate-ios -letpan-ios -licudata -licui18n -licuuc -lxml2 -lsasl2 -liconv -ltidy -lstdc++ -all_load`
-- Make sure to use GNU C++ standard library.
+ MCOIMAPMessagesRequestKind requestKind = MCOIMAPMessagesRequestKindHeaders;
+ NSString *folder = @"INBOX";
+ MCOIndexSet *uids = [MCOIndexSet indexSetWithRange:MCORangeMake(1, UINT64_MAX)];
+
+ MCOIMAPFetchMessagesOperation *fetchOperation = [session fetchMessagesByUIDOperationWithFolder:folder requestKind:requestKind uids:uids];
+
+ [fetchOperation start:^(NSError * error, NSArray * fetchedMessages, MCOIndexSet * vanishedMessages) {
+ //We've finished downloading the messages!
+
+ //Let's check if there was an error:
+ if(error) {
+ NSLog(@"Error downloading message headers:%@", error);
+ }
+
+ //And, let's print out the messages...
+ NSLog(@"The post man delivereth:%@", fetchedMessages);
+ }];
+```
+
+In this sample, we retrieved and printed a list of email headers from an IMAP server. In order to execute the fetch, we request an asynchronous operation object from the `MCOIMAPSession` instance with our parameters (more on this later). This operation object is able to initiate a connection to Gmail when we call the `start` method. Now here's where things get a little tricky. We call the `start` function with an Objective-C block, which is executed on the main thread when the fetch operation completes. The actual fetching from IMAP is done on a **background thread**, leaving your UI and other processing **free to use the main thread**.
+
+### Anatomy of a Message ###
+
+Background Reading:
+* [RFC821](http://tools.ietf.org/html/rfc821)
+* [RFC822](http://tools.ietf.org/html/rfc822)
+* [RFC5322](http://tools.ietf.org/html/rfc5322)
+* [RFC2045](http://tools.ietf.org/html/rfc2045)
+* [RFC2046](http://tools.ietf.org/html/rfc2046)
+* [RFC2047](http://tools.ietf.org/html/rfc2047)
+* [RFC2048](http://tools.ietf.org/html/rfc2048)
+* [RFC2049](http://tools.ietf.org/html/rfc2049)
+
+MailCore 2 has a new message structure that more closely mimics the structure of raw emails. This gives you as the user a lot of power, but can also be a little bewildering at first. When a fetch request completes and returns its results to your block, you will get an array of `MCOIMAPMessage` objects. Depending on what `kind` the fetch was made with, this message object can be only partially loaded from IMAP. In our example above, we used the `MCOIMAPMessagesRequestKindHeaders` as our `requestKind`. So we won't find any fields outside of the `header` filled out in the returned messages array. If you need more data, you can combine the `MCOIMAPMessagesRequestKind` bit masks:
+
+
+```objc
+ //From the Mac Example
+ MCOIMAPMessagesRequestKind requestKind = (MCOIMAPMessagesRequestKind)
+ (MCOIMAPMessagesRequestKindHeaders | MCOIMAPMessagesRequestKindStructure |
+ MCOIMAPMessagesRequestKindInternalDate | MCOIMAPMessagesRequestKindHeaderSubject |
+ MCOIMAPMessagesRequestKindFlags);
+```
+
+Many of the properties you probably need are either in the `header` of an MCOIMAPMessage, or direct properties of the message.
+
+So now comes the tricky part: you want the full message bodies from the emails. MailCore 2 allows you to fetch the entire contents of a message through the `MCOIMAPFetchContentOperation` instance, which responds with the NSData representation of the email. You can then use `MCOMessageParser` to generate your HTML body content.
+
+### 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.
+
+So, to render HTML from a MCOAbstractMessage subclass (MCOMessageParser, MCOIMAPMessage, MCOMessageBuilder), you can implement 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:
+
+```objc
+- (NSString *)MCOMessageView_templateForMainHeader:(MCOMessageView *)view {
+ NSLog(@"%s", __PRETTY_FUNCTION__);
+ return @"<div style=\"background-color:#eee\">\
+ <div><b>From:</b> {{FROM}}</div>\
+ <div><b>To:</b> {{TO}}</div>\
+ </div>";
+}
+
+- (NSDictionary *)MCOMessageView:(MCOMessageView *)view 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;
+ }
+
+ NSLog(@"%s:%@", __PRETTY_FUNCTION__, templateValues);
+
+ return templateValues;
+}
+```
+
+As you can see, we use [ctemplates](https://code.google.com/p/ctemplate/) in order to format and insert the data we want to display in different parts of the message.
+
+### TODO for this guide ###
+* Add images
+* Add more in-depth steps/examples for how to work with imap messages
+* Add examples for POP and SMTP.