iOS邮件开发整理
邮件协议
常见的邮箱协议有 SMTP、POP3、IMAP等
- Simple Mail Transfer Protocol(SMTP)
SMTP是互联网上的一种通讯协议,主要功能是用在传送电子邮件,当我们通过电子邮件程序,寄E-mil给另外一个人时,必须通过SMTP通讯协议,将邮件送到对方的邮件服务器上,等到对方上网的时候,就可以收到你所寄的信
- Post Office Protocol 3(POP3)
POP3是邮局协议的第3个版本,是TCP/IP协议族中的一员(默认端口是110)。本协议主要用于支持使用客户端远程管理在服务器上的电子邮件。,它规定怎样将个人计算机连接到Internet的邮件服务器和下载电子邮件的电子协议。它是因特网电子邮件的第一个离线协议标准,POP3允许用户从服务器上把邮件存储到本地主机(即自己的计算机)上,同时删除保存在邮件服务器上的邮件,而POP3服务器则是遵循POP3协议的接收邮件服务器,用来接收电子邮件的
- Internet Mail Access Protocol(IMAP)
IMAP提供webmail 与电子邮件客户端之间的双向通信,客户端的操作都会反馈到服务器上,对邮件进行的操作,服务器上的邮件也会做相应的动作
IMAP相对POP3的好处
IMAP 允许你从任何设备访问你的电子邮件,无论你身在何处。 使用 IMAP 阅读电子邮件时,实际上不是在计算机上下载或存储它;而是从电子邮件服务读取它。 因此,你可以从世界上任何地方的不同设备检查你的电子邮件:你的手机、计算机、朋友的计算机。
IMAP 仅在单击邮件时下载邮件,附件不会自动下载。 这样,你就能比 POP 更快地检查邮件。
POP 的工作原理是联系电子邮件服务并从中下载所有新邮件。 下载到电脑或 Mac 后,将从电子邮件服务中删除它们。 这意味着,在下载电子邮件后,只能使用 同一台计算机对其进行访问。 如果尝试从其他设备访问电子邮件,则之前下载的邮件将不可用。
已发送邮件存储在本地电脑或 Mac 上,而不是存储在电子邮件服务器上
简单地说,SMTP管‘发’, POP3/IMAP管‘收’。
邮件的发收过程
写完邮件,点击‘发送’。这时邮件软件会发消息给邮件服务器上的SMTP service。这时有两种情况
- 如果邮件的收信人也是处于同一个domain,比如从http://aaa.com 发送给123的邮箱,SMTP service只需要转给local的POP3 Service即可。
- 如果邮件收信人是另外的domain,比如 http://aaa.com 发送给http://bbb.com, SMTP service需要通过询问DNS,找到属于bbb的SMTP service的host。
MailCore2 详细使用
MailCore是一个第三方的邮件SDK,支持POP和IMAP 方式接收邮件,以及smtp邮件发送
发邮件
- 先创建MCOSMTPSession,配置smtp邮箱参数
MCOSMTPSession *smtpSession = [[MCOSMTPSession alloc] init];
smtpSession.hostname = @"smtp.exmail.qq.com";
smtpSession.port = 587;
smtpSession.username = @"aaa@qq.com";
smtpSession.password = @"passward";
smtpSession.connectionType = MCOConnectionTypeStartTLS;
MCOSMTPOperation *smtpOperation = [self.smtpSession loginOperation];
[smtpOperation start:^(NSError * error) {
if (error == nil) {
NSLog(@"login account successed");
} else {
NSLog(@"login account failure: %@", error);
}
}];
- 使用MCOMessageBuilder构建邮件体的发送内容
// 构建邮件体的发送内容
MCOMessageBuilder *messageBuilder = [[MCOMessageBuilder alloc] init];
messageBuilder.header.from = [MCOAddress addressWithDisplayName:@"张三" mailbox:@"111111@qq.com"]; // 发送人
messageBuilder.header.to = @[[MCOAddress addressWithMailbox:@"222222@qq.com"]]; // 收件人(多人)
messageBuilder.header.cc = @[[MCOAddress addressWithMailbox:@"@333333qq.com"]]; // 抄送(多人)
messageBuilder.header.bcc = @[[MCOAddress addressWithMailbox:@"444444@qq.com"]]; // 密送(多人)
messageBuilder.header.subject = @"测试邮件"; // 邮件标题
messageBuilder.textBody = @"hello world"; // 邮件正文
/*
如果邮件是回复或者转发,原邮件中往往有附件以及正文中有其他图片资源,
如果有需要你可将原文原封不动的也带过去,这里发送的正文就可以如下配置
*/
NSString * bodyHtml = @"<p>我是原邮件正文</p>";
NSString *body = @"我是邮件回复的内容";
NSMutableString*fullBodyHtml = [NSMutableString stringWithFormat:@"%@<br/>-------------原始邮件-------------<br/>%@",[body stringByReplacingOccurrencesOfString:@"\n"withString:@"<br/>"],bodyHtml];
[messageBuilder setHTMLBody:fullBodyHtml];
// 添加正文里的附加资源
NSArray *inattachments = msgPaser.htmlInlineAttachments;
for (MCOAttachment*attachmentininattachments) {
[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,配置imap邮箱参数
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为邮件的正文文本信息
}];
- 获取邮件内容,用MCOMessageParser解析邮件
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];
];