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