The Gmail Api has no clear documentation on how to do this, I have been trying with this but there are many things that are in the air.
I have sought external source
Here is the final solution I have finally make it work :
Podfile :
pod 'GoogleAPIClient/Gmail'
Sample Swift 5 code:
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))
}
}
I found the solution
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))
}
According to Google API documentation(https://developers.google.com/gmail/api/guides/sending), we can know there are have two ways can help you send message success(draft.send, message.send). without a doubt, both of them use api are different, but the result is the same. As you give one of the above way can got that, we just call it message.send. With another way is draft.send, so we should upload "UploadParameters" to Gmail draft, after we upload success, we can get some message about gmail draft. At last, we should send mail content, when we send success, the draft message will automatic delete. Code goes be as follows:
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))
}
If your goal is to send an email I suggest using the MailCore library for iOS. In the documentation there are examples just in Objective-c but it is compatible with Swift
This is an example of how to send an email with MailCore and 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!")
}
}