邮箱开发(三) - MailCore2 详细使用

简介

MailCore是一个第三方的邮件SDK,支持POP和IMAP 方式接收邮件,以及smtp邮件发送。

安装

1、从github上拉取代码

git clone https://github.com/MailCore/mailcore2/

2、添加到项目中

把build-mac/mailcore2.xcodeproj拖进工程

3、在项目中添加静态库链接

选中工程--TARGETS--Build Phases

在 Link Binary With Libraries 中添加:

libMailCore-ios.a
CFNetwork.framework
Security.framework

在 Target Dependencies 中选择:

static maincore2 ios

4、设置Flags

选中工程--TARGETS--Build Setting

在 Other Linker Flags 中设置

-lctemplate-ios -letpan-ios -lxml2 -lsasl2 -liconv -ltidy -lz -lc++ -stdlib=libc++ -ObjC -lresolv

在 C++ Standard Library 中设置

libc++

然后选择相应 Target 编译。

SMTP(Simple Mail Transfer Protocol)

1、先创建MCOSMTPSession,配置smtp邮箱参数

    MCOSMTPSession *smtpSession = [[MCOSMTPSession alloc] init];
    smtpSession.hostname = @"smtp.exmail.qq.com";
    smtpSession.port = 587;
    smtpSession.username = @"hello@qq.com";
    smtpSession.password = @"passward";
    smtpSession.connectionType = MCOConnectionTypeStartTLS;
    
    MCOSMTPOperation *smtpOperation = [self.smtpSession loginOperation];
    [smtpOperation start:^(NSError * error) {
        if (error == nil) {
            NSLog(@"login account successed");
        } else {
            NSLog(@"login account failure: %@", error);
        }
    }];

2、使用MCOMessageBuilder构建邮件体的发送内容

    // 构建邮件体的发送内容
    MCOMessageBuilder *messageBuilder = [[MCOMessageBuilder alloc] init];
    messageBuilder.header.from = [MCOAddress addressWithDisplayName:@"张三" mailbox:@"111111@qq.com"];   // 发送人
    messageBuilder.header.to = @[[MCOAddress addressWithMailbox:@"222222@qq.com"]];       // 收件人(多人)
    messageBuilder.header.cc = @[[MCOAddress addressWithMailbox:@"@333333qq.com"]];      // 抄送(多人)
    messageBuilder.header.bcc = @[[MCOAddress addressWithMailbox:@"444444@qq.com"]];    // 密送(多人)
    messageBuilder.header.subject = @"测试邮件";    // 邮件标题
    messageBuilder.textBody = @"hello world";           // 邮件正文
    
    /* 
     如果邮件是回复或者转发,原邮件中往往有附件以及正文中有其他图片资源,
     如果有需要你可将原文原封不动的也带过去,这里发送的正文就可以如下配置 
     */
    NSString * bodyHtml = @"<p>我是原邮件正文</p>";
    NSString *body = @"我是邮件回复的内容";
    NSMutableString*fullBodyHtml = [NSMutableString stringWithFormat:@"%@<br/>-------------原始邮件-------------<br/>%@",[body stringByReplacingOccurrencesOfString:@"\n"withString:@"<br/>"],bodyHtml];
    [messageBuilder setHTMLBody:fullBodyHtml];
    
    // 添加正文里的附加资源
    NSArray *inattachments = msgPaser.htmlInlineAttachments;
    for (MCOAttachment*attachmentininattachments) {
        [messageBuilder addRelatedAttachment:attachment];    //添加html正文里的附加资源(图片)
    }
    
    // 添加邮件附件
    for (MCOAttachment*attachmentinattachments) {
        [builder addAttachment:attachment];    //添加附件
    }

3、将构建好的邮件发送出去

    // 发送邮件
    NSData * rfc822Data =[messageBuilder data];
    MCOSMTPSendOperation *sendOperation = [self.smtpSession sendOperationWithData:rfc822Data];
    [sendOperation start:^(NSError *error) {
        if (error == nil) {
            NSLog(@"send message successed");
        } else {
            NSLog(@"send message failure: %@", error);
        }
    }];

IMAP(Internet Mail Access Protocol)

1、先创建MCOIMAPSession,配置imap邮箱参数

    MCOIMAPSession *imapSession = [[MCOIMAPSession alloc] init];
    imapSession.hostname = hostname;
    imapSession.port = port;
    imapSession.username = username;
    imapSession.password = passward;
    imapSession.connectionType = MCOConnectionTypeTLS;
    
    MCOIMAPOperation *imapOperation = [imapSession checkAccountOperation];
    [imapOperation start:^(NSError * __nullable error) {
        if (error == nil) {
            NSLog(@"login account successed\n");
            
            // 在这里获取邮件,获取文件夹信息
            [self loadIMAPFolder];
        } else {
            NSLog(@"login account failure: %@\n", error);
        }
    }];

2、获取文件夹目录

    MCOIMAPFetchFoldersOperation *imapFetchFolderOp = [imapSession fetchAllFoldersOperation];
    [imapFetchFolderOp start:^(NSError * error, NSArray * folders) {
        [_folderList addObjectsFromArray:folders];
        [_folderTableView reloadData];
    }];

3、获取收件箱邮件

    MCOIMAPMessagesRequestKind requestKind = (MCOIMAPMessagesRequestKind)
    (MCOIMAPMessagesRequestKindHeaders | MCOIMAPMessagesRequestKindStructure |
     MCOIMAPMessagesRequestKindInternalDate | MCOIMAPMessagesRequestKindHeaderSubject |
     MCOIMAPMessagesRequestKindFlags);
    
    // 获取收件箱信息(包含邮件总数等信息)
    NSString *folderName = @"INBOX";
    MCOIMAPFolderInfoOperation * folderInfoOperation = [imapSession folderInfoOperation:folderName];
    [folderInfoOperation start:^(NSError *error, MCOIMAPFolderInfo * info) {
        
        NSLog(@"total number: %d", info.messageCount);
        
        NSInteger numberOfMessages = 10;
        numberOfMessages -= 1;
        MCOIndexSet *numbers = [MCOIndexSet indexSetWithRange:MCORangeMake([info messageCount] - numberOfMessages, numberOfMessages)];
        
        MCOIMAPFetchMessagesOperation *imapMessagesFetchOp = [imapSession fetchMessagesByNumberOperationWithFolder:folderName
                                                                                                                                                                      requestKind:requestKind
                                                                                                                                                                            numbers:numbers];
        
        // 异步获取邮件
        [imapMessagesFetchOp start:^(NSError *error, NSArray *messages, MCOIndexSet *vanishedMessages) {
            [_messageList addObjectsFromArray:messages];
            [_messageTableView reloadData];
        }];
    }];

4、获取邮件头

    // 拿出一个邮件MCOIMAPMessage(里面包含邮件头等信息)
    MCOIMAPMessage *message = _messageList [0];
    
    // 使用MCOIMAPMessageRenderingOperation来获得邮件概要信息
    NSString *uidKey = [NSString stringWithFormat:@"%d", message.uid];
    
    MCOIMAPMessageRenderingOperation *messageRenderingOperation = [imapSession plainTextBodyRenderingOperationWithMessage:message folder:@"INBOX"];
    [messageRenderingOperation start:^(NSString * plainTextBodyString,NSError * error) {
        
        // plainTextBodyString为邮件的正文文本信息
        
    }];

5、获取邮件内容,用MCOMessageParser解析邮件

    MCOIMAPFetchContentOperation * fetchContentOp = [self.imapSession fetchMessageOperationWithFolder:@"INBOX" uid:[message uid]];
    [fetchContentOp start:^(NSError * error, NSData * data) {
        if ([error code] != MCOErrorNone) {
            return;
        }
        
        // 解析邮件内容
        MCOMessageParser * msgPareser = [MCOMessageParser messageParserWithData:data];
        NSString *content = [msgPareser htmlRenderingWithDelegate:self];

POP(Post Office Protocol)

1、先创建MCOIMAPSession,配置imap邮箱参数

    MCOPOPSession *popSession = [[MCOPOPSession alloc] init];
    popSession.hostname = @"smtp.exmail.qq.com";
    popSession.port = 995;
    popSession.username = @"hello@qq.com";
    popSession.password = @"passward";
    popSession.connectionType = MCOConnectionTypeTLS;
    
    // 登录邮箱
    MCOPOPOperation *popOperation = [popSession checkAccountOperation];
    [popOperation start:^(NSError * __nullable error) {
        if (error == nil) {
            NSLog(@"login account successed");
        } else {
            NSLog(@"login account failure: %@", error);
        }
    }];

2、获取邮件信息(同IMAP)

3、关于MCOMessageParser

不管是pop还是IMAP获取的邮件,最后都要得到MCOMessageParser来操作邮件内容。
    // MCOMessageHeader包含了邮件标题,时间等头信息
    MCOMessageHeader *header = msgPaser.header;
    
    // 获得邮件正文的HTML内容,一般使用webView加载
    NSString * bodyHtml = [msgPaser htmlBodyRendering];
    
    // 获取附件(多个)
    NSMutableArray *attachments = [[NSMutableArray alloc] initWithArray:_msgPaser.attachments];
    
    // 拿到一个附件MCOAttachment,可从中得到文件名,文件内容data
    MCOAttachment *attachment = attachments[0];

将附件写入本地
    // 获取文件路径
    NSString *tmpDirectory = NSTemporaryDirectory();
    NSString *filePath = [tmpDirectorystringByAppendingPathComponent : attachment.filename ];
    [attachmentData writeToFile:filePathatomically:YES];
当邮件正文有图片,在webview中如何加载图片,可通过注入js的方式修改html
定义脚本:
static NSString * mainJavascript = @"\
var imageElements = function() {\
var imageNodes = document.getElementsByTagName('img');\
return [].slice.call(imageNodes);\
};\
\
var findCIDImageURL = function() {\
var images = imageElements();\
\
var imgLinks = [];\
for (var i = 0; i < images.length; i++) {\
var url = images[i].getAttribute('src');\
if (url.indexOf('cid:') == 0 || url.indexOf('x-mailcore-image:') == 0)\
imgLinks.push(url);\
}\
return JSON.stringify(imgLinks);\
};\
\
var replaceImageSrc = function(info) {\
var images = imageElements();\
\
for (var i = 0; i < images.length; i++) {\
var url = images[i].getAttribute('src');\
if (url.indexOf(info.URLKey) == 0) {\
images[i].setAttribute('src', info.LocalPathKey);\
break;\
}\
}\
};\
";

修改刚才获取的html内容
    MCOMessageParser * msgPareser = [MCOMessageParser messageParserWithData:data];
    NSString *content = [msgPareser htmlRenderingWithDelegate:self];
    
    NSMutableString * html = [NSMutableString string];
    [html appendFormat:@"<html><head><script>%@</script></head>"
     @"<body>%@</body><iframe src='x-mailcore-msgviewloaded:' style='width: 0px; height: 0px; border: none;'>"
     @"</iframe></html>", mainJavascript, content];
    [_webView loadHTMLString:content baseURL:nil];

设置webView代理
#pragma mark - webview
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    
    NSURLRequest *responseRequest = [self webView:webView resource:nil willSendRequest:request redirectResponse:nil fromDataSource:nil];
    
    if(responseRequest == request) {
        return YES;
    } else {
        [webView loadRequest:responseRequest];
        return NO;
    }
}

- (NSURLRequest *)webView:(UIWebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(id)dataSource {
    
    if ([[[request URL] scheme] isEqualToString:@"x-mailcore-msgviewloaded"]) {
        [self _loadImages];
    }
    return request;
}

// 加载网页中的图片
- (void) _loadImages {
    NSString * result = [webView stringByEvaluatingJavaScriptFromString:@"findCIDImageURL()"];
    NSLog(@"-----加载网页中的图片-----");
    NSLog(@"%@", result);
    
    if (result == nil || [result isEqualToString:@""]) {
        return;
    }
    
    NSData * data = [result dataUsingEncoding:NSUTF8StringEncoding];
    NSError *error = nil;
    NSArray * imagesURLStrings = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
    
    for (NSString * urlString in imagesURLStrings) {
        MCOAbstractPart * part = nil;
        NSURL *url = [NSURL URLWithString:urlString];
        
        if ([MCOCIDURLProtocol isCID:url]) {
            part = [self _partForCIDURL:url];
        }
        else if ([MCOCIDURLProtocol isXMailcoreImage:url]) {
            NSString * specifier = [url resourceSpecifier];
            NSString * partUniqueID = specifier;
            part = [self _partForUniqueID:partUniqueID];
        }
        
        if (part == nil) {
            continue;
        }
        
        NSString * partUniqueID = [part uniqueID];
        MCOAttachment * attachment = (MCOAttachment *) [msgPaser partForUniqueID:partUniqueID];
        NSData * data =[attachment data];
        
        if (data!=nil) {
            
            //获取文件路径
            NSString *tmpDirectory =NSTemporaryDirectory();
            NSString *filePath=[tmpDirectory stringByAppendingPathComponent : attachment.filename ];
            
            NSFileManager *fileManger=[NSFileManager defaultManager];
            if (![fileManger fileExistsAtPath:filePath]) {
                //不存在就去请求加载
                NSData *attachmentData=[attachment data];
                [attachmentData writeToFile:filePath atomically:YES];
                NSLog(@"资源:%@已经下载至%@", attachment.filename,filePath);
            }
            
            NSURL * cacheURL = [NSURL fileURLWithPath:filePath];
            NSDictionary * args =@{@"URLKey": urlString,@"LocalPathKey": cacheURL.absoluteString};
            
            NSString * jsonString = [self _jsonEscapedStringFromDictionary:args];
            NSString * replaceScript = [NSString stringWithFormat:@"replaceImageSrc(%@)", jsonString];
            [webView stringByEvaluatingJavaScriptFromString:replaceScript];
        }
    }
}

- (NSString *)_jsonEscapedStringFromDictionary:(NSDictionary *)dictionary {
    
    NSData * json = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:nil];
    NSString * jsonString = [[NSString alloc] initWithData:json encoding:NSUTF8StringEncoding];
    return jsonString;
}

- (NSURL *) _cacheJPEGImageData:(NSData *)imageData withFilename:(NSString *)filename {
    
    NSString * path = [[NSTemporaryDirectory()stringByAppendingPathComponent:filename]stringByAppendingPathExtension:@"jpg"];
    [imageData writeToFile:path atomically:YES];
    return [NSURL fileURLWithPath:path];
}

- (MCOAbstractPart *) _partForCIDURL:(NSURL *)url {
    return [_message partForContentID:[url resourceSpecifier]];
}

- (MCOAbstractPart *) _partForUniqueID:(NSString *)partUniqueID {
    return [_message partForUniqueID:partUniqueID];
}


  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值