如何在 swift 中使用 Gmail api 发送电子邮件
How send Email using Gmail api in swift
Gmail Api has no clear documentation on how to do this, I have been trying with this但是有很多事情是悬而未决的。
我已经寻求外部资源。 Source 1 and Source 2。第一个好像是用了api的势,用的是函数queryForUsersMessagesSendWithUploadParameters
.
而第二个大约多一点。虽然这在 Objective-C 中不是问题,但 GTMMIMEDocument 对象除外,它不知道从哪里或是否从库中获取。
我的问题是,是否有人有更清晰和/或更易于理解的代码,或者更好的发送电子邮件指南
如果您的目标是发送电子邮件,我建议使用 iOS 的 MailCore 库。
在文档中有 Objective-c 中的示例,但它与 Swift
兼容
这是如何使用 MailCore 和 Swift 发送电子邮件的示例:
var smtpSession = MCOSMTPSession()
smtpSession.hostname = "smtp.gmail.com"
smtpSession.username = "matt@gmail.com"
smtpSession.password = "xxxxxxxxxxxxxxxx"
smtpSession.port = 465
smtpSession.authType = MCOAuthType.SASLPlain
smtpSession.connectionType = MCOConnectionType.TLS
smtpSession.connectionLogger = {(connectionID, type, data) in
if data != nil {
if let string = NSString(data: data, encoding: NSUTF8StringEncoding){
NSLog("Connectionlogger: \(string)")
}
}
}
var builder = MCOMessageBuilder()
builder.header.to = [MCOAddress(displayName: "Rool", mailbox: "itsrool@gmail.com")]
builder.header.from = MCOAddress(displayName: "Matt R", mailbox: "matt@gmail.com")
builder.header.subject = "My message"
builder.htmlBody = "Yo Rool, this is a test message!"
let rfc822Data = builder.data()
let sendOperation = smtpSession.sendOperationWithData(rfc822Data)
sendOperation.start { (error) -> Void in
if (error != nil) {
NSLog("Error sending email: \(error)")
} else {
NSLog("Successfully sent email!")
}
}
我找到了解决方案
class func sendEmail() {
var gtlMessage = GTLGmailMessage()
gtlMessage.raw = self.generateRawString()
let appd = UIApplication.sharedApplication().delegate as! AppDelegate
let query = GTLQueryGmail.queryForUsersMessagesSendWithUploadParameters(nil)
query.message = gtlMessage
appd.service.executeQuery(query, completionHandler: { (ticket, response, error) -> Void in
println("ticket \(ticket)")
println("response \(response)")
println("error \(error)")
})
}
class func generateRawString() -> String {
var dateFormatter:NSDateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "EEE, dd MMM yyyy HH:mm:ss Z"; //RFC2822-Format
var todayString:String = dateFormatter.stringFromDate(NSDate())
var rawMessage = "" +
"Date: \(todayString)\r\n" +
"From: <mail>\r\n" +
"To: username <mail>\r\n" +
"Subject: Test send email\r\n\r\n" +
"Test body"
println("message \(rawMessage)")
return GTLEncodeWebSafeBase64(rawMessage.dataUsingEncoding(NSUTF8StringEncoding))
}
根据Google API文档(https://developers.google.com/gmail/api/guides/sending),我们可以知道有两种方法可以帮助您成功发送消息(draft.send, message.send).毫无疑问,两者使用 api 是不同的,但结果是一样的。
由于您给出了上述方法之一,因此我们将其称为message.send。另一种方式是draft.send,所以我们应该上传"UploadParameters"到Gmail草稿,上传成功后,我们可以得到一些关于gmail草稿的信息。最后,我们要发送邮件内容,发送成功后,草稿邮件会自动删除。代码如下:
func postEmailMessageRequest(model: MEMailMessageModel, request: CompletionRequest) {
let uploadParameters = GTLUploadParameters()
uploadParameters.data = model.snippet.dataUsingEncoding(NSUTF8StringEncoding)
uploadParameters.MIMEType = model.mimeType!
let query = GTLQueryGmail.queryForUsersDraftsCreateWithUploadParameters(uploadParameters) as! GTLQueryProtocol!
service.executeQuery(query) { (ticket : GTLServiceTicket!, messages : AnyObject!, error : NSError?) -> Void in
if error == nil {
let messages = (messages as! GTLGmailDraft)
messages.message.threadId = model.threadID
self.sendMailRequest(messages, model: model, request: request)
} else {
request(status: false, result: "upload success")
}
}
}
func sendMailRequest(draft: GTLGmailDraft, model: MEMailMessageModel, request: CompletionRequest) {
let query = GTLQueryGmail.queryForUsersDraftsSendWithUploadParameters(nil) as! GTLQueryGmail
draft.message.raw = self.generateRawString(model)
query.draft = draft
self.service.executeQuery(query, completionHandler: { (ticket, response, error) -> Void in
if error == nil {
request(status: true, result: "send success") // after this, the draft will be delete
} else {
request(status: false, result: "send failure")
}
})
}
func generateRawString(model: MEMailMessageModel) -> String {
let date = MEMailMessagelFormatUtil.coverDateFromDate(NSDate(), dateFormat: "EEE, dd MMM yyyy HH:mm:ss Z")! // get current date
var fromEamil = ""
if let str = NSUserDefaults.standardUserDefaults().valueForKey("userEmail") as? String {
fromEamil = str
}
var rawMessage = ""
if model.isReply { // how to reply, but how to reply the email is another question.
rawMessage = "" + "In-Reply-To: \(model.messageID!)\r\n"
if let references = model.references {
rawMessage += "References: \(references) \(model.messageID!)\r\n"
} else {
rawMessage += "References: \(model.messageID!)\r\n"
}
}
rawMessage += "Date: \(date)\r\n" +
"From: <\(fromEamil)>\r\n" +
"To: \(model.toName!) <\(model.toMail)>\r\n" +
"Subject: \(model.subject) \r\n\r\n" + "\(model.snippet)"
return GTLEncodeWebSafeBase64(rawMessage.dataUsingEncoding(NSUTF8StringEncoding))
}
这是我最终实现的最终解决方案:
播客文件:
pod 'GoogleAPIClient/Gmail'
示例Swift 5 代码:
import Foundation
import GoogleAPIClient
class GMailManager {
let service = GTLServiceGmail()
func sendEmail() {
guard let query = GTLQueryGmail.queryForUsersMessagesSend(with: nil) else {
return
}
let gtlMessage = GTLGmailMessage()
gtlMessage.raw = self.generateRawString()
query.message = gtlMessage
self.service.executeQuery(query, completionHandler: { (ticket, response, error) -> Void in
print("ticket \(String(describing: ticket))")
print("response \(String(describing: response))")
print("error \(String(describing: error))")
})
}
func generateRawString() -> String {
let dateFormatter:DateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEE, dd MMM yyyy HH:mm:ss Z"; //RFC2822-Format
let todayString:String = dateFormatter.string(from: NSDate() as Date)
let rawMessage = "" +
"Date: \(todayString)\r\n" +
"From: <mail>\r\n" +
"To: username <mail>\r\n" +
"Subject: Test send email\r\n\r\n" +
"Test body"
print("message \(rawMessage)")
return GTLEncodeWebSafeBase64(rawMessage.data(using: String.Encoding.utf8))
}
}
Gmail Api has no clear documentation on how to do this, I have been trying with this但是有很多事情是悬而未决的。
我已经寻求外部资源。 Source 1 and Source 2。第一个好像是用了api的势,用的是函数queryForUsersMessagesSendWithUploadParameters
.
而第二个大约多一点。虽然这在 Objective-C 中不是问题,但 GTMMIMEDocument 对象除外,它不知道从哪里或是否从库中获取。
我的问题是,是否有人有更清晰和/或更易于理解的代码,或者更好的发送电子邮件指南
如果您的目标是发送电子邮件,我建议使用 iOS 的 MailCore 库。 在文档中有 Objective-c 中的示例,但它与 Swift
兼容这是如何使用 MailCore 和 Swift 发送电子邮件的示例:
var smtpSession = MCOSMTPSession()
smtpSession.hostname = "smtp.gmail.com"
smtpSession.username = "matt@gmail.com"
smtpSession.password = "xxxxxxxxxxxxxxxx"
smtpSession.port = 465
smtpSession.authType = MCOAuthType.SASLPlain
smtpSession.connectionType = MCOConnectionType.TLS
smtpSession.connectionLogger = {(connectionID, type, data) in
if data != nil {
if let string = NSString(data: data, encoding: NSUTF8StringEncoding){
NSLog("Connectionlogger: \(string)")
}
}
}
var builder = MCOMessageBuilder()
builder.header.to = [MCOAddress(displayName: "Rool", mailbox: "itsrool@gmail.com")]
builder.header.from = MCOAddress(displayName: "Matt R", mailbox: "matt@gmail.com")
builder.header.subject = "My message"
builder.htmlBody = "Yo Rool, this is a test message!"
let rfc822Data = builder.data()
let sendOperation = smtpSession.sendOperationWithData(rfc822Data)
sendOperation.start { (error) -> Void in
if (error != nil) {
NSLog("Error sending email: \(error)")
} else {
NSLog("Successfully sent email!")
}
}
我找到了解决方案
class func sendEmail() {
var gtlMessage = GTLGmailMessage()
gtlMessage.raw = self.generateRawString()
let appd = UIApplication.sharedApplication().delegate as! AppDelegate
let query = GTLQueryGmail.queryForUsersMessagesSendWithUploadParameters(nil)
query.message = gtlMessage
appd.service.executeQuery(query, completionHandler: { (ticket, response, error) -> Void in
println("ticket \(ticket)")
println("response \(response)")
println("error \(error)")
})
}
class func generateRawString() -> String {
var dateFormatter:NSDateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "EEE, dd MMM yyyy HH:mm:ss Z"; //RFC2822-Format
var todayString:String = dateFormatter.stringFromDate(NSDate())
var rawMessage = "" +
"Date: \(todayString)\r\n" +
"From: <mail>\r\n" +
"To: username <mail>\r\n" +
"Subject: Test send email\r\n\r\n" +
"Test body"
println("message \(rawMessage)")
return GTLEncodeWebSafeBase64(rawMessage.dataUsingEncoding(NSUTF8StringEncoding))
}
根据Google API文档(https://developers.google.com/gmail/api/guides/sending),我们可以知道有两种方法可以帮助您成功发送消息(draft.send, message.send).毫无疑问,两者使用 api 是不同的,但结果是一样的。 由于您给出了上述方法之一,因此我们将其称为message.send。另一种方式是draft.send,所以我们应该上传"UploadParameters"到Gmail草稿,上传成功后,我们可以得到一些关于gmail草稿的信息。最后,我们要发送邮件内容,发送成功后,草稿邮件会自动删除。代码如下:
func postEmailMessageRequest(model: MEMailMessageModel, request: CompletionRequest) {
let uploadParameters = GTLUploadParameters()
uploadParameters.data = model.snippet.dataUsingEncoding(NSUTF8StringEncoding)
uploadParameters.MIMEType = model.mimeType!
let query = GTLQueryGmail.queryForUsersDraftsCreateWithUploadParameters(uploadParameters) as! GTLQueryProtocol!
service.executeQuery(query) { (ticket : GTLServiceTicket!, messages : AnyObject!, error : NSError?) -> Void in
if error == nil {
let messages = (messages as! GTLGmailDraft)
messages.message.threadId = model.threadID
self.sendMailRequest(messages, model: model, request: request)
} else {
request(status: false, result: "upload success")
}
}
}
func sendMailRequest(draft: GTLGmailDraft, model: MEMailMessageModel, request: CompletionRequest) {
let query = GTLQueryGmail.queryForUsersDraftsSendWithUploadParameters(nil) as! GTLQueryGmail
draft.message.raw = self.generateRawString(model)
query.draft = draft
self.service.executeQuery(query, completionHandler: { (ticket, response, error) -> Void in
if error == nil {
request(status: true, result: "send success") // after this, the draft will be delete
} else {
request(status: false, result: "send failure")
}
})
}
func generateRawString(model: MEMailMessageModel) -> String {
let date = MEMailMessagelFormatUtil.coverDateFromDate(NSDate(), dateFormat: "EEE, dd MMM yyyy HH:mm:ss Z")! // get current date
var fromEamil = ""
if let str = NSUserDefaults.standardUserDefaults().valueForKey("userEmail") as? String {
fromEamil = str
}
var rawMessage = ""
if model.isReply { // how to reply, but how to reply the email is another question.
rawMessage = "" + "In-Reply-To: \(model.messageID!)\r\n"
if let references = model.references {
rawMessage += "References: \(references) \(model.messageID!)\r\n"
} else {
rawMessage += "References: \(model.messageID!)\r\n"
}
}
rawMessage += "Date: \(date)\r\n" +
"From: <\(fromEamil)>\r\n" +
"To: \(model.toName!) <\(model.toMail)>\r\n" +
"Subject: \(model.subject) \r\n\r\n" + "\(model.snippet)"
return GTLEncodeWebSafeBase64(rawMessage.dataUsingEncoding(NSUTF8StringEncoding))
}
这是我最终实现的最终解决方案:
播客文件:
pod 'GoogleAPIClient/Gmail'
示例Swift 5 代码:
import Foundation
import GoogleAPIClient
class GMailManager {
let service = GTLServiceGmail()
func sendEmail() {
guard let query = GTLQueryGmail.queryForUsersMessagesSend(with: nil) else {
return
}
let gtlMessage = GTLGmailMessage()
gtlMessage.raw = self.generateRawString()
query.message = gtlMessage
self.service.executeQuery(query, completionHandler: { (ticket, response, error) -> Void in
print("ticket \(String(describing: ticket))")
print("response \(String(describing: response))")
print("error \(String(describing: error))")
})
}
func generateRawString() -> String {
let dateFormatter:DateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEE, dd MMM yyyy HH:mm:ss Z"; //RFC2822-Format
let todayString:String = dateFormatter.string(from: NSDate() as Date)
let rawMessage = "" +
"Date: \(todayString)\r\n" +
"From: <mail>\r\n" +
"To: username <mail>\r\n" +
"Subject: Test send email\r\n\r\n" +
"Test body"
print("message \(rawMessage)")
return GTLEncodeWebSafeBase64(rawMessage.data(using: String.Encoding.utf8))
}
}