MailCore2 详细使用

来源:互联网 发布:nginx跳转 域名不变 编辑:程序博客网 时间:2024/05/29 08:51

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:@"%@<br/>-------------原始邮件-------------<br/>%@",[body stringByReplacingOccurrencesOfString:@"\n"withString:@"<br/>"],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];

        }

    }];

 

1 0