簡(jiǎn)介:
MailCore是一個(gè)第三方的郵件SDK伴逸,支持POP和IMAP 方式接收郵件,以及smtp郵件發(fā)送.github上提供的demo功能是非常少的边灭,很多深入內(nèi)容沒有講解丘跌,只能查看上面提供的類文檔查看各個(gè)對(duì)象的內(nèi)容,經(jīng)過(guò)我長(zhǎng)時(shí)間摸索出來(lái)狠角,下面講解有關(guān)其使用的方法号杠。(轉(zhuǎn)載請(qǐng)注明出處)
官方參考資料
Class documentation:http://libmailcore.com/mailcore2/api/index.html
Wiki: https://github.com/MailCore/mailcore2/wiki
一、 POP
1.需要先創(chuàng)建MCOPOPSession丰歌,并配置連接郵箱需要的各個(gè)參數(shù)
MCOPOPSession *session = [[MCOPOPSession alloc] init];
session.hostname = @"pop.qq.com";
session.port = 995;
[session setUsername:@"myMail@qq.com"];
[sessionsetPassword:@"yourPsw"];
[sessionsetConnectionType:MCOConnectionTypeTLS];
2.配置好參數(shù)后姨蟋,創(chuàng)建MCOPOPOperation,通過(guò)該對(duì)象來(lái)操作郵件
MCOPOPOperation * checkOp = [sessioncheckAccountOperation];
//開啟異步請(qǐng)求立帖,檢查目前該配置是否能正確登錄郵箱
[checkOp start:^(NSError *error) {
NSLog(@"finished checking account.");
if (error == nil) {
//正確登錄郵箱
/*在這里獲取郵件頭眼溶,通過(guò)郵件頭可以獲得郵件內(nèi)容,詳情看下面*/
} else {
NSLog(@"登錄郵箱失敗晓勇,請(qǐng)檢查網(wǎng)絡(luò)重試,error loading account: %@", error);
}
checkOp = nil;
}];
3.獲取郵件頭堂飞,通過(guò)MCOPOPFetchMessagesOperation來(lái)獲取郵件頭灌旧,獲得的郵件頭在MailCore使用了MCOPOPMessageInfo(有三個(gè)屬性index,size,uid)來(lái)封裝了
MCOPOPFetchMessagesOperation * op = [session fetchMessagesOperation];
//異步獲取郵件頭MCOPOPMessageInfo,保存在messages里
[op start:^(NSError * error,NSArray * messages) {
if (error==nil) {
//通過(guò)messages中的郵件頭信息绰筛,可以進(jìn)一步請(qǐng)求獲得最終的郵件內(nèi)容,獲取方法見下面4
}
}];
4.通過(guò)MCOPOPMessageInfo獲取郵件內(nèi)容,得到MCOMessageParser枢泰,可從中獲得郵件標(biāo)題,正文铝噩,附件等信息
MCOPOPMessageInfo *messageInfo= messages[0];//拿到一個(gè)郵件頭
int index= messageInfo.index;
MCOPOPFetchMessageOperation*messageOperation=[session fetchMessageOperationWithIndex: index];
//開啟異步請(qǐng)求, messageData為郵件內(nèi)容
[messageOperation start:^(NSError * error, NSData *messageData) {
// messageData is the RFC 822 formatted message data.
if (!error) {
//由data轉(zhuǎn)換為MCOMessageParser
MCOMessageParser * msgPaser =[MCOMessageParser messageParserWithData:messageData];
//可從msgPaser獲得郵件信息衡蚂,如:msgPaser.header.subject為郵件標(biāo)題
NSString *htmlString=[msgPaserhtmlBodyRendering];//獲取郵件html正文
messageOperation=nil;
}else{
NSLog(@"獲取郵件消息失敗");
}
}];
5.關(guān)于MCOMessageParser
不管是pop還是IMAP獲取的郵件,最后都需要得到MCOMessageParser來(lái)操作郵件內(nèi)容骏庸,下面對(duì)其作個(gè)講解毛甲。
// MCOMessageHeader包含了郵件標(biāo)題,時(shí)間等頭信息
MCOMessageHeader *header=msgPaser.header;
//獲得郵件正文的HTML內(nèi)容,一般使用webView加載
NSString * bodyHtml =[msgPaser htmlBodyRendering];
//獲取附件(多個(gè))
NSMutableArray *attachments=[[NSMutableArrayalloc]initWithArray:_msgPaser.attachments];
MCOAttachment *attachment=attachments[0]; //拿到一個(gè)附件MCOAttachment,可從中得到文件名具被,文件內(nèi)容data
Ps:將附件寫入本地
NSData*attachmentData=[attachmentdata];
//獲取文件路徑
NSString *tmpDirectory =NSTemporaryDirectory();
NSString *filePath=[tmpDirectorystringByAppendingPathComponent : attachment.filename ];
[attachmentData writeToFile:filePathatomically:YES];
PS:當(dāng)郵件正文中有圖片丽啡,在webview中如何加載出圖片呢,可與通過(guò)注入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內(nèi)容
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];
//接著設(shè)置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;
}
//加載網(wǎng)頁(yè)中的圖片
- (void) _loadImages
{
NSString * result = [webViewstringByEvaluatingJavaScriptFromString:@"findCIDImageURL()"];
NSLog(@"-----加載網(wǎng)頁(yè)中的圖片-----");
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]) {//不存在就去請(qǐng)求加載
NSData *attachmentData=[attachmentdata];
[attachmentData writeToFile:filePathatomically:YES];
NSLog(@"資源:%@已經(jīng)下載至%@", 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.需要先創(chuàng)建MCOIMAPSession补箍,并配置連接郵箱需要的各個(gè)參數(shù)
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(@"登錄郵箱失敗,請(qǐng)檢查網(wǎng)絡(luò)重試");
}
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];
//異步請(qǐng)求郵件啸蜜,fetchedMessages為郵件列表坑雅,里面存放MCOIMAPMessage對(duì)象
[fetchOperationstart:^(NSError * error,NSArray * fetchedMessages,MCOIndexSet * vanishedMessages) {
if(error) {
NSLog(@"獲取郵件列表失敗。Error downloading message headers:%@", error);
}else{
// 在這里操作郵件內(nèi)容衬横,見3
}
}];
ps:如果想知道郵箱有什么文件夾可以用以下方法查看
MCOIMAPFetchFoldersOperation * op = [sessionfetchAllFoldersOperation];
[op start:^(NSError * error,NSArray *folders) {
NSLog(@"%@",folders);
}];
3.操作郵件內(nèi)容
//拿出一個(gè)郵件MCOIMAPMessage(里面包含郵件頭等信息)
MCOIMAPMessage *message = fetchedMessages [0];
//使用MCOIMAPMessageRenderingOperation來(lái)獲得郵件概要信息
NSString *uidKey = [NSStringstringWithFormat:@"%d", message.uid];
MCOIMAPMessageRenderingOperation * messageRenderingOperation = [sessionplainTextBodyRenderingOperationWithMessage:messagefolder:@"INBOX"];
[messageRenderingOperationstart:^(NSString * plainTextBodyString,NSError * error) {
// plainTextBodyString為郵件的正文文本信息
}];
4.取到郵件內(nèi)容裹粤,最終取得該郵件的MCOMessageParser
MCOIMAPFetchContentOperation * op = [sessionfetchMessageOperationWithFolder: @"INBOX"uid:[messageuid]];
// [_opsaddObject:op];
[op start:^(NSError * error,NSData * data) {
if ([error code] != MCOErrorNone) {
ALERT_SHOW(@"獲取郵件數(shù)據(jù)失敗");
return;
}
NSAssert(data != nil, @"data != nil");
//拿到MCOMessageParser后,如何處理蜂林,跟上文pop提到的MCOMessageParser一致
MCOMessageParser * msgPaser = [MCOMessageParsermessageParserWithData:data];
}];
三遥诉、 SMTP
1.先創(chuàng)建MCOSMTPSession,配置好各個(gè)連接smtp郵箱的參數(shù)
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構(gòu)建郵件體的發(fā)送內(nèi)容
MCOMessageBuilder * builder = [[[MCOMessageBuilderalloc]init]autorelease];
//構(gòu)建郵件頭
[[builder header] setFrom:[MCOAddress addressWithDisplayName:nil mailbox: @"yoursmtp@qq.com"]];
//設(shè)置郵件的接受人(可以多個(gè))
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];
//設(shè)置抄送人(多個(gè))
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];
//設(shè)置密送人(多個(gè))
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];
//設(shè)置郵件標(biāo)題
[[builder header] setSubject: @"給你的郵件"];
//設(shè)置郵件正文(純文本)
[builder setTextBody: @"測(cè)試郵件的正文部分"];
ps:如果郵件是回復(fù)或者轉(zhuǎn)發(fā),原郵件中往往有附件以及正文中有其他圖片資源噪叙,如果有需要你可將原文原封不動(dòng)的也帶過(guò)去矮锈,這里發(fā)送的正文就可以如下配置:
NSString * bodyHtml=@”<p>我是原郵件正文</p>”;
NSString *body=@"我是郵件回復(fù)的內(nèi)容";
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.將構(gòu)建好的郵件體發(fā)送出去
NSData * rfc822Data =[builder data];
MCOSMTPSendOperation *sendOperation = [smtpSessionsendOperationWithData:rfc822Data];
[sendOperation start:^(NSError *error) {
if(error) {
NSLog(@"%@郵件發(fā)送失敗Error sending email:%@", username, error);
} else {
NSLog(@"%@ Successfullysent email!", username);
UIAlertView *alert=[[UIAlertViewalloc]initWithTitle:@"溫馨提示"message:@"發(fā)送成功"delegate:selfcancelButtonTitle:@"確認(rèn)"otherButtonTitles:nil];
[alert show];
[alert release];
}
}];