简介:
MailCore是一个第三方的邮件SDK,支持POP和IMAP 方式接收邮件,以及smtp邮件发送.github上提供的demo功能是非常少的,很多深入内容没有讲解,只能查看上面提供的类文档查看各个对象的内容,经过我长时间摸索出来,下面讲解有关其使用的方法。(转载请注明出处)
官方参考资料
Class documentation:http://libmailcore.com/mailcore2/api/index.html
Wiki: https://github.com/MailCore/mailcore2/wiki
一、 POP
1.需要先创建MCOPOPSession,并配置连接邮箱需要的各个参数
MCOPOPSession *session = [[MCOPOPSession alloc] init];
session.hostname = @"pop.qq.com";
session.port = 995;
[session setUsername:@"myMail@qq.com"];
[sessionsetPassword:@"yourPsw"];
[sessionsetConnectionType:MCOConnectionTypeTLS];
2.配置好参数后,创建MCOPOPOperation,通过该对象来操作邮件
MCOPOPOperation * checkOp = [sessioncheckAccountOperation];
//开启异步请求,检查目前该配置是否能正确登录邮箱
[checkOp start:^(NSError *error) {
NSLog(@"finished checking account.");
if (error == nil) {
//正确登录邮箱
/*在这里获取邮件头,通过邮件头可以获得邮件内容,详情看下面*/
} else {
NSLog(@"登录邮箱失败,请检查网络重试,error loading account: %@", error);
}
checkOp = nil;
}];
3.获取邮件头,通过MCOPOPFetchMessagesOperation来获取邮件头,获得的邮件头在MailCore使用了MCOPOPMessageInfo(有三个属性index,size,uid)来封装了
MCOPOPFetchMessagesOperation * op = [session fetchMessagesOperation];
//异步获取邮件头MCOPOPMessageInfo,保存在messages里
[op start:^(NSError * error,NSArray * messages) {
if (error==nil) {
//通过messages中的邮件头信息,可以进一步请求获得最终的邮件内容,获取方法见下面4
}
}];
4.通过MCOPOPMessageInfo获取邮件内容,得到MCOMessageParser,可从中获得邮件标题,正文,附件等信息
MCOPOPMessageInfo *messageInfo= messages[0];//拿到一个邮件头
int index= messageInfo.index;
MCOPOPFetchMessageOperation*messageOperation=[session fetchMessageOperationWithIndex: index];
//开启异步请求, messageData为邮件内容
[messageOperation start:^(NSError * error, NSData *messageData) {
// messageData is the RFC 822 formatted message data.
if (!error) {
//由data转换为MCOMessageParser
MCOMessageParser * msgPaser =[MCOMessageParser messageParserWithData:messageData];
//可从msgPaser获得邮件信息,如:msgPaser.header.subject为邮件标题
NSString *htmlString=[msgPaserhtmlBodyRendering];//获取邮件html正文
messageOperation=nil;
}else{
NSLog(@"获取邮件消息失败");
}
}];
5.关于MCOMessageParser
不管是pop还是IMAP获取的邮件,最后都需要得到MCOMessageParser来操作邮件内容,下面对其作个讲解。
// MCOMessageHeader包含了邮件标题,时间等头信息
MCOMessageHeader *header=msgPaser.header;
//获得邮件正文的HTML内容,一般使用webView加载
NSString * bodyHtml =[msgPaser htmlBodyRendering];
//获取附件(多个)
NSMutableArray *attachments=[[NSMutableArrayalloc]initWithArray:_msgPaser.attachments];
MCOAttachment *attachment=attachments[0]; //拿到一个附件MCOAttachment,可从中得到文件名,文件内容data
Ps:将附件写入本地
NSData*attachmentData=[attachmentdata];
//获取文件路径
NSString *tmpDirectory =NSTemporaryDirectory();
NSString *filePath=[tmpDirectorystringByAppendingPathComponent : attachment.filename ];
[attachmentData writeToFile:filePathatomically:YES];
PS:当邮件正文中有图片,在webview中如何加载出图片呢,可与通过注入js的方式修改html
定义js脚本:
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内容
NSMutableString * html =[NSMutableStringstring];
[html appendFormat:@"<html><head><script>%@</script></head>"
@"<body>%@</body><iframesrc='x-mailcore-msgviewloaded:' style='width: 0px; height: 0px; border:none;'>"
@"</iframe></html>", mainJavascript, bodyHtml];
[webView loadHTMLString:htmlbaseURL:nil];
//接着设置webview的委托
pragma mark - webview
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)requestnavigationType:(UIWebViewNavigationType)navigationType {
NSURLRequest*responseRequest = [selfwebView:webViewresource:nilwillSendRequest:requestredirectResponse:nilfromDataSource:nil];
if(responseRequest== request) {
return YES;
} else {
[webView loadRequest:responseRequest];
return NO;
}
}
- (NSURLRequest *)webView:(UIWebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)requestredirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(id)dataSource
{
if ([[[request URL] scheme] isEqualToString:@"x-mailcore-msgviewloaded"]) {
[self _loadImages];
}
return request;
}
//加载网页中的图片
- (void) _loadImages
{
NSString * result = [webViewstringByEvaluatingJavaScriptFromString:@"findCIDImageURL()"];
NSLog(@"-----加载网页中的图片-----");
NSLog(@"%@", result);
if (result==nil || [resultisEqualToString:@""]) {
return;
}
NSData * data = [result dataUsingEncoding:NSUTF8StringEncoding];
NSError *error = nil;
NSArray * imagesURLStrings = [NSJSONSerializationJSONObjectWithData:dataoptions:0error:&error];
for(NSString * urlStringin imagesURLStrings) {
MCOAbstractPart * part =nil;
NSURL * url;
url = [NSURL URLWithString:urlString];
if ([MCOCIDURLProtocolisCID:url]) {
part = [self _partForCIDURL:url];
}
else if ([MCOCIDURLProtocol isXMailcoreImage:url]) {
NSString * specifier = [urlresourceSpecifier];
NSString * partUniqueID = specifier;
part = [self _partForUniqueID:partUniqueID];
}
if (part == nil)
continue;
NSString * partUniqueID = [partuniqueID];
MCOAttachment * attachment = (MCOAttachment *) [msgPaser partForUniqueID:partUniqueID];
NSData * data =[attachmentdata];
if (data!=nil) {
//获取文件路径
NSString *tmpDirectory =NSTemporaryDirectory();
NSString *filePath=[tmpDirectorystringByAppendingPathComponent : attachment.filename ];
NSFileManager *fileManger=[NSFileManagerdefaultManager];
if (![fileManger fileExistsAtPath:filePath]) {//不存在就去请求加载
NSData *attachmentData=[attachmentdata];
[attachmentData writeToFile:filePathatomically:YES];
NSLog(@"资源:%@已经下载至%@", attachment.filename,filePath);
}
NSURL * cacheURL = [NSURLfileURLWithPath:filePath];
NSDictionary * args =@{@"URLKey": urlString,@"LocalPathKey": cacheURL.absoluteString};
NSString * jsonString = [self_jsonEscapedStringFromDictionary:args];
NSString * replaceScript = [NSStringstringWithFormat:@"replaceImageSrc(%@)", jsonString];
[webView stringByEvaluatingJavaScriptFromString:replaceScript];
}
}
}
- (NSString *)_jsonEscapedStringFromDictionary:(NSDictionary *)dictionary
{
NSData * json = [NSJSONSerializationdataWithJSONObject:dictionaryoptions:0error:nil];
NSString * jsonString = [[NSStringalloc]initWithData:jsonencoding:NSUTF8StringEncoding];
return jsonString;
}
- (NSURL *) _cacheJPEGImageData:(NSData *)imageData withFilename:(NSString *)filename
{
NSString * path = [[NSTemporaryDirectory()stringByAppendingPathComponent:filename]stringByAppendingPathExtension:@"jpg"];
[imageData writeToFile:pathatomically:YES];
return [NSURLfileURLWithPath:path];
}
- (MCOAbstractPart *) _partForCIDURL:(NSURL *)url
{
return [_messageParserpartForContentID:[urlresourceSpecifier]];
}
- (MCOAbstractPart *) _partForUniqueID:(NSString *)partUniqueID
{
return [_messageParserpartForUniqueID:partUniqueID];
}
二、 IMAP
1.需要先创建MCOIMAPSession,并配置连接邮箱需要的各个参数
session = [[MCOIMAPSessionalloc]init];
session.hostname =@"imap.qq.com";
session.port =993;
[session setUsername:@"mail@qq.com"];
[session setPassword:@"psw"];
[session setConnectionType:MCOConnectionTypeTLS];
session.connectionLogger = ^(void * connectionID,MCOConnectionLogType type,NSData * data) {
if (type != MCOConnectionLogTypeSentPrivate) {
NSLog(@"eventlogged:%p %i withData: %@", connectionID, type, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
}
};
//检查登录邮箱
MCOIMAPOperation *checkOp = [sessioncheckAccountOperation];
[checkOp start:^(NSError *error) {
NSLog(@"finished checking account.");
if (error == nil) {
//在这里获取邮件
[self getmail];
} else {
NSLog(@"error loading account: %@", error);
[self hideLoading];
ALERT_SHOW(@"登录邮箱失败,请检查网络重试");
}
checkOp = nil;
}];
2.获取邮件
MCOIMAPMessagesRequestKind requestKind = (MCOIMAPMessagesRequestKind)
(MCOIMAPMessagesRequestKindHeaders |MCOIMAPMessagesRequestKindStructure |
MCOIMAPMessagesRequestKindInternalDate |MCOIMAPMessagesRequestKindHeaderSubject |
MCOIMAPMessagesRequestKindFlags);
MCOIndexSet *uids = [MCOIndexSetindexSetWithRange:MCORangeMake(1,UINT64_MAX)];
MCOIMAPFetchMessagesOperation *fetchOperation = [sessionfetchMessagesByUIDOperationWithFolder:@"INBOX"requestKind:requestKinduids:uids];
//异步请求邮件,fetchedMessages为邮件列表,里面存放MCOIMAPMessage对象
[fetchOperationstart:^(NSError * error,NSArray * fetchedMessages,MCOIndexSet * vanishedMessages) {
if(error) {
NSLog(@"获取邮件列表失败。Error downloading message headers:%@", error);
}else{
// 在这里操作邮件内容,见3
}
}];
ps:如果想知道邮箱有什么文件夹可以用以下方法查看
MCOIMAPFetchFoldersOperation * op = [sessionfetchAllFoldersOperation];
[op start:^(NSError * error,NSArray *folders) {
NSLog(@"%@",folders);
}];
3.操作邮件内容
//拿出一个邮件MCOIMAPMessage(里面包含邮件头等信息)
MCOIMAPMessage *message = fetchedMessages [0];
//使用MCOIMAPMessageRenderingOperation来获得邮件概要信息
NSString *uidKey = [NSStringstringWithFormat:@"%d", message.uid];
MCOIMAPMessageRenderingOperation * messageRenderingOperation = [sessionplainTextBodyRenderingOperationWithMessage:messagefolder:@"INBOX"];
[messageRenderingOperationstart:^(NSString * plainTextBodyString,NSError * error) {
// plainTextBodyString为邮件的正文文本信息
}];
4.取到邮件内容,最终取得该邮件的MCOMessageParser
MCOIMAPFetchContentOperation * op = [sessionfetchMessageOperationWithFolder: @"INBOX"uid:[messageuid]];
// [_opsaddObject:op];
[op start:^(NSError * error,NSData * data) {
if ([error code] != MCOErrorNone) {
ALERT_SHOW(@"获取邮件数据失败");
return;
}
NSAssert(data != nil, @"data != nil");
//拿到MCOMessageParser后,如何处理,跟上文pop提到的MCOMessageParser一致
MCOMessageParser * msgPaser = [MCOMessageParsermessageParserWithData:data];
}];
三、 SMTP
1.先创建MCOSMTPSession,配置好各个连接smtp邮箱的参数
MCOSMTPSession*smtpSession = [[[MCOSMTPSessionalloc]init]autorelease];
smtpSession.username = @"yoursmtp@qq.com";
smtpSession.password = @"yourpws";
smtpSession.hostname = @"smtp.qq.com";
smtpSession.port = 465;
smtpSession.connectionType = MCOConnectionTypeTLS;
2.使用MCOMessageBuilder构建邮件体的发送内容
MCOMessageBuilder * builder = [[[MCOMessageBuilderalloc]init]autorelease];
//构建邮件头
[[builder header] setFrom:[MCOAddress addressWithDisplayName:nil mailbox: @"yoursmtp@qq.com"]];
//设置邮件的接受人(可以多个)
NSMutableArray *to = [NSMutableArrayarray];
NSArray *recipients=[@"32232@qq.com;toyou@qq.com"componentsSeparatedByString:@";"];
for(NSString *toAddressin recipients) {
//使用MCOAddress封装邮箱地址
MCOAddress *newAddress = [MCOAddressaddressWithMailbox:toAddress];
[to addObject:newAddress];
}
[[builder header] setTo:to];
//设置抄送人(多个)
NSArray *CC=[@"cc32232@qq.com;cctoyou@qq.com"componentsSeparatedByString:@";"];
NSMutableArray *cc = [NSMutableArrayarray];
for(NSString *ccAddressin CC) {
MCOAddress *newAddress = [MCOAddressaddressWithMailbox:ccAddress];
[ccaddObject:newAddress];
}
[[builder header] setCc:cc];
//设置密送人(多个)
NSArray *BCC=[@"bc32232@qq.com;bctoyou@qq.com"componentsSeparatedByString:@";"];
NSMutableArray *bcc = [NSMutableArrayarray];
for(NSString *bccAddressin BCC) {
MCOAddress *newAddress = [MCOAddressaddressWithMailbox:bccAddress];
[bcc addObject:newAddress];
}
[[builder header] setBcc:bcc];
//设置邮件标题
[[builder header] setSubject: @"给你的邮件"];
//设置邮件正文(纯文本)
[builder setTextBody: @"测试邮件的正文部分"];
ps:如果邮件是回复或者转发,原邮件中往往有附件以及正文中有其他图片资源,如果有需要你可将原文原封不动的也带过去,这里发送的正文就可以如下配置:
NSString * bodyHtml=@”<p>我是原邮件正文</p>”;
NSString *body=@"我是邮件回复的内容";
NSMutableString*fullBodyHtml=[NSMutableStringstringWithFormat:@"%@
-------------原始邮件-------------
%@",[body stringByReplacingOccurrencesOfString:@"n"withString:@"
"],bodyHtml];
[builder setHTMLBody:fullBodyHtml];
//添加正文里的附加资源
NSArray *inattachments=msgPaser.htmlInlineAttachments;
for (MCOAttachment*attachmentininattachments) {
[builder addRelatedAttachment:attachment];//添加html正文里的附加资源(图片)
}
//添加邮件附件
for (MCOAttachment*attachmentinattachments) {
[builder addAttachment:attachment];//添加附件
}
3.将构建好的邮件体发送出去
NSData * rfc822Data =[builder data];
MCOSMTPSendOperation *sendOperation = [smtpSessionsendOperationWithData:rfc822Data];
[sendOperation start:^(NSError *error) {
if(error) {
NSLog(@"%@邮件发送失败Error sending email:%@", username, error);
} else {
NSLog(@"%@ Successfullysent email!", username);
UIAlertView *alert=[[UIAlertViewalloc]initWithTitle:@"温馨提示"message:@"发送成功"delegate:selfcancelButtonTitle:@"确认"otherButtonTitles:nil];
[alert show];
[alert release];
}
}];