MailCore2 的使用

简介:
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];

    }

}];
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容