(一) - 邮箱收发协议
什么是POP3、SMTP和IMAP协议
电子邮件工作原理
网易163免费邮箱相关服务器信息:
网易邮箱已经默认开启POP3/SMTP/IMAP服务,方便你通过客户端更好地收发邮件,如果关闭可以通过以下方式开启: 什么是POP3、SMTP和IMAP?
(二) - 各大主流邮箱服务器信息和端口号
(三) - MailCore2 详细使用
简介
MailCore是一个第三方的邮件SDK,支持POP和IMAP 方式接收邮件,以及smtp邮件发送。
安装
1、从github上拉取代码
2、添加到项目中
把build-mac/mailcore2.xcodeproj拖进工程
3、在项目中添加静态库链接
选中工程--TARGETS--Build Phases
在 Link Binary With Libraries 中添加:
libMailCore-ios.a
CFNetwork.framework
Security.framework
在 Target Dependencies 中选择:
static maincore2 ios
4、设置Flags
选中工程--TARGETS--Build Setting
在 Other Linker Flags 中设置
-lctemplate-ios -letpan-ios -lxml2 -lsasl2 -liconv -ltidy -lz -lc++ -stdlib=libc++ -ObjC -lresolv
在 C++ Standard Library 中设置
libc++
MCOSMTPOperation *smtpOperation = [self.smtpSession loginOperation];
[smtpOperation start:^(NSError * error) {
if (error == nil) {
NSLog(@"login account successed");
} else {
NSLog(@"login account failure: %@", error);
}
}];
/*
如果邮件是回复或者转发,原邮件中往往有附件以及正文中有其他图片资源,
如果有需要你可将原文原封不动的也带过去,这里发送的正文就可以如下配置
*/
NSString * bodyHtml = @"<p>我是原邮件正文</p>";
NSString body = @"我是邮件回复的内容";
NSMutableStringfullBodyHtml = [NSMutableString stringWithFormat:@"%@
-------------原始邮件-------------
%@",[body stringByReplacingOccurrencesOfString:@"\n"withString:@"
"],bodyHtml];
[messageBuilder setHTMLBody:fullBodyHtml];
// 添加正文里的附加资源
NSArray inattachments = msgPaser.htmlInlineAttachments;
for (MCOAttachmentattachmentininattachments) {
[messageBuilder addRelatedAttachment:attachment]; //添加html正文里的附加资源(图片)
}
// 添加邮件附件
for (MCOAttachment*attachmentinattachments) {
[builder addAttachment:attachment]; //添加附件
}
// 发送邮件
NSData * rfc822Data =[messageBuilder data];
MCOSMTPSendOperation *sendOperation = [self.smtpSession sendOperationWithData:rfc822Data];
[sendOperation start:^(NSError *error) {
if (error == nil) {
NSLog(@"send message successed");
} else {
NSLog(@"send message failure: %@", error);
}
}];
MCOIMAPSession *imapSession = [[MCOIMAPSession alloc] init];
imapSession.hostname = hostname;
imapSession.port = port;
imapSession.username = username;
imapSession.password = passward;
imapSession.connectionType = MCOConnectionTypeTLS;
MCOIMAPOperation *imapOperation = [imapSession checkAccountOperation];
[imapOperation start:^(NSError * __nullable error) {
if (error == nil) {
NSLog(@"login account successed\n");
// 在这里获取邮件,获取文件夹信息
[self loadIMAPFolder];
} else {
NSLog(@"login account failure: %@\n", error);
}
}];
MCOIMAPFetchFoldersOperation *imapFetchFolderOp = [imapSession fetchAllFoldersOperation];
[imapFetchFolderOp start:^(NSError * error, NSArray * folders) {
[_folderList addObjectsFromArray:folders];
[_folderTableView reloadData];
}];
MCOIMAPMessagesRequestKind requestKind = (MCOIMAPMessagesRequestKind)
(MCOIMAPMessagesRequestKindHeaders | MCOIMAPMessagesRequestKindStructure |
MCOIMAPMessagesRequestKindInternalDate | MCOIMAPMessagesRequestKindHeaderSubject |
MCOIMAPMessagesRequestKindFlags);
// 获取收件箱信息(包含邮件总数等信息)
NSString *folderName = @"INBOX";
MCOIMAPFolderInfoOperation * folderInfoOperation = [imapSession folderInfoOperation:folderName];
[folderInfoOperation start:^(NSError *error, MCOIMAPFolderInfo * info) {
NSLog(@"total number: %d", info.messageCount);
NSInteger numberOfMessages = 10;
numberOfMessages -= 1;
MCOIndexSet *numbers = [MCOIndexSet indexSetWithRange:MCORangeMake([info messageCount] - numberOfMessages, numberOfMessages)];
MCOIMAPFetchMessagesOperation *imapMessagesFetchOp = [imapSession fetchMessagesByNumberOperationWithFolder:folderName
requestKind:requestKind
numbers:numbers];
// 异步获取邮件
[imapMessagesFetchOp start:^(NSError *error, NSArray *messages, MCOIndexSet *vanishedMessages) {
[_messageList addObjectsFromArray:messages];
[_messageTableView reloadData];
}];
}];
// 拿出一个邮件MCOIMAPMessage(里面包含邮件头等信息)
MCOIMAPMessage *message = _messageList [0];
// 使用MCOIMAPMessageRenderingOperation来获得邮件概要信息
NSString *uidKey = [NSString stringWithFormat:@"%d", message.uid];
MCOIMAPMessageRenderingOperation *messageRenderingOperation = [imapSession plainTextBodyRenderingOperationWithMessage:message folder:@"INBOX"];
[messageRenderingOperation start:^(NSString * plainTextBodyString,NSError * error) {
// plainTextBodyString为邮件的正文文本信息
}];
MCOIMAPFetchContentOperation * fetchContentOp = [self.imapSession fetchMessageOperationWithFolder:@"INBOX" uid:[message uid]];
[fetchContentOp start:^(NSError * error, NSData * data) {
if ([error code] != MCOErrorNone) {
return;
}
// 解析邮件内容
MCOMessageParser * msgPareser = [MCOMessageParser messageParserWithData:data];
NSString *content = [msgPareser htmlRenderingWithDelegate:self];
// 登录邮箱
MCOPOPOperation *popOperation = [popSession checkAccountOperation];
[popOperation start:^(NSError * __nullable error) {
if (error == nil) {
NSLog(@"login account successed");
} else {
NSLog(@"login account failure: %@", error);
}
}];
2、获取邮件信息(同IMAP)
3、关于MCOMessageParser
// MCOMessageHeader包含了邮件标题,时间等头信息
MCOMessageHeader *header = msgPaser.header;
// 获得邮件正文的HTML内容,一般使用webView加载
NSString * bodyHtml = [msgPaser htmlBodyRendering];
// 获取附件(多个)
NSMutableArray *attachments = [[NSMutableArray alloc] initWithArray:_msgPaser.attachments];
// 拿到一个附件MCOAttachment,可从中得到文件名,文件内容data
MCOAttachment *attachment = attachments[0];
// 获取文件路径
NSString *tmpDirectory = NSTemporaryDirectory();
NSString *filePath = [tmpDirectorystringByAppendingPathComponent : attachment.filename ];
[attachmentData writeToFile:filePathatomically:YES];
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;\
}\
}\
};\
";
MCOMessageParser * msgPareser = [MCOMessageParser messageParserWithData:data];
NSString *content = [msgPareser htmlRenderingWithDelegate:self];
NSMutableString * html = [NSMutableString string];
[html appendFormat:@"<html><head><script>%@</script></head>"
@"<body>%@</body><iframe src='x-mailcore-msgviewloaded:' style='width: 0px; height: 0px; border: none;'>"
@"</iframe></html>", mainJavascript, content];
[_webView loadHTMLString:content baseURL:nil];
pragma mark - webview
-
(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSURLRequest *responseRequest = [self webView:webView resource:nil willSendRequest:request redirectResponse:nil fromDataSource:nil];
if(responseRequest == request) {
return YES;
} else {
[webView loadRequest:responseRequest];
return NO;
}
} -
(NSURLRequest *)webView:(UIWebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(id)dataSource {
if ([[[request URL] scheme] isEqualToString:@"x-mailcore-msgviewloaded"]) {
[self _loadImages];
}
return request;
}
// 加载网页中的图片
-
(void) _loadImages {
NSString * result = [webView stringByEvaluatingJavaScriptFromString:@"findCIDImageURL()"];
NSLog(@"-----加载网页中的图片-----");
NSLog(@"%@", result);if (result == nil || [result isEqualToString:@""]) {
return;
}NSData * data = [result dataUsingEncoding:NSUTF8StringEncoding];
NSError *error = nil;
NSArray * imagesURLStrings = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];for (NSString * urlString in imagesURLStrings) {
MCOAbstractPart * part = nil;
NSURL *url = [NSURL URLWithString:urlString];if ([MCOCIDURLProtocol isCID:url]) { part = [self _partForCIDURL:url]; } else if ([MCOCIDURLProtocol isXMailcoreImage:url]) { NSString * specifier = [url resourceSpecifier]; NSString * partUniqueID = specifier; part = [self _partForUniqueID:partUniqueID]; } if (part == nil) { continue; } NSString * partUniqueID = [part uniqueID]; MCOAttachment * attachment = (MCOAttachment *) [msgPaser partForUniqueID:partUniqueID]; NSData * data =[attachment data]; if (data!=nil) { //获取文件路径 NSString *tmpDirectory =NSTemporaryDirectory(); NSString *filePath=[tmpDirectory stringByAppendingPathComponent : attachment.filename ]; NSFileManager *fileManger=[NSFileManager defaultManager]; if (![fileManger fileExistsAtPath:filePath]) { //不存在就去请求加载 NSData *attachmentData=[attachment data]; [attachmentData writeToFile:filePath atomically:YES]; NSLog(@"资源:%@已经下载至%@", attachment.filename,filePath); } NSURL * cacheURL = [NSURL fileURLWithPath:filePath]; NSDictionary * args =@{@"URLKey": urlString,@"LocalPathKey": cacheURL.absoluteString}; NSString * jsonString = [self _jsonEscapedStringFromDictionary:args]; NSString * replaceScript = [NSString stringWithFormat:@"replaceImageSrc(%@)", jsonString]; [webView stringByEvaluatingJavaScriptFromString:replaceScript]; }
}
} -
(NSString *)_jsonEscapedStringFromDictionary:(NSDictionary *)dictionary {
NSData * json = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:nil];
NSString * jsonString = [[NSString alloc] initWithData:json encoding:NSUTF8StringEncoding];
return jsonString;
} -
(NSURL *) _cacheJPEGImageData:(NSData *)imageData withFilename:(NSString *)filename {
NSString * path = [[NSTemporaryDirectory()stringByAppendingPathComponent:filename]stringByAppendingPathExtension:@"jpg"];
[imageData writeToFile:path atomically:YES];
return [NSURL fileURLWithPath:path];
} -
(MCOAbstractPart *) _partForCIDURL:(NSURL *)url {
return [_message partForContentID:[url resourceSpecifier]];
} -
(MCOAbstractPart *) _partForUniqueID:(NSString *)partUniqueID {
return [_message partForUniqueID:partUniqueID];
}