IOS Chat application using XMPP Protocol (ejabberd) Room chat issue - chat

I am developing an IOS Chat application using XMPP Protocol(ejabberd). My chat room is created at my server, it return roomID to me.
I am facing an issue in room/group chat. When i am sending a single message it is repeating more than once like 3 to 4 times.How to fix this. My code is here
XMPPJID *roomJID = [XMPPJID jidWithString:[roomDict objectForKey:KEY_group_id]];
XMPPRoom *xmppRoom = [[XMPPRoom alloc] initWithRoomStorage:xmppRoomCoreDataStorage jid:roomJID dispatchQueue:dispatch_get_main_queue()];
[xmppRoom activate:[ChatHandler sharedInstance].xmppStream];
[xmppRoom addDelegate:self
delegateQueue:dispatch_get_main_queue()];
[self insertRoomObjectWithDictionary:roomDict];
[xmppRoom joinRoomUsingNickname:[[ChatHandler sharedInstance] xmppStream].myJID.user
history:nil
password:#""];
[xmppRoom fetchConfigurationForm];
return xmppRoom;

Following code snippet worked for me.. Try it for your code...
I have sent uuid of my device as child while sending message and checked the same uuid at the time of incoming message :
-(void)sendMessageWithBody:(NSString *)messageBody
{
if ([messageBody length] == 0) return;
NSXMLElement *body = [NSXMLElement elementWithName:#"body" stringValue:messageBody];
XMPPMessage *message = [XMPPMessage message];
[message addChild:body];
NSString *uuidString=[UIDevice currentDevice].identifierForVendor.UUIDString;
NSXMLElement *myMsgLogic=[NSXMLElement elementWithName:#"myMsgLogic" stringValue:uuidString];
[message addChild:myMsgLogic];
[self sendMessage:message];
}
-(void)xmppRoom:(XMPPRoom *)sender didReceiveMessage:(XMPPMessage *)message fromOccupant:(XMPPJID *)occupantJID;
{
[self handleIncomingMessage:message room:xmppRoom];
}
-(void)handleIncomingMessage:(XMPPMessage *)message room:(XMPPRoom *)room
{
NSString *uuidString=[UIDevice currentDevice].identifierForVendor.UUIDString;
NSString *messageLogic= [[message elementsForName:#"myMsgLogic"].firstObject stringValue];
if ([uuidString isEqualToString:messageLogic]) {
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:#"handleIncomingMessage" message:[message body] delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert show];
}
}

I have the same chat application using xmpp ejabbered. I was also facing the same problem. In my case on xmpp server they have set offline message storage to 100. If in offline mode the message limit crossed 100 then from 101th message I will get bounce back that message. So as a solution we changed the offline message limit to 500.
{mod_offline_odbc, [
{user_max_messages, 500}
]}

Related

XMPP push notifications causing problems (delay + duplications) in messages

XMPP push notifications causing problems (delay + duplications) in messages.
I have successfully created a chat application using XMPP + Ejabberd.
Without Push Notifications:
Both single and group chat messages are working perfectly.
With Push Notifications:
Sometimes everything works perfectly.Notifications are triggered and messages are received with out any delay or duplications.
Sometimes no notifications are triggered (while app in background) but messages are received perfectly.
Sometimes notifications are triggered but messages are received with delay and duplications.
Everything on the sever side is configured correctly.They advised to fix your issues by making sure each session connects with one persistent resource, making connection stable using whitespace keep alive and when connection is lost just rebinding with same resource.
I have stream management,xmppStream.enableBackgroundingOnSocket and App provides Voice over IP services background mode enabled.
When user logs out or app is terminated i teardown the stream and send an unavailable presence.
Below is my code for xmpp stream push notifications and connect/disconnect.
I am pulling out my hair over this.if you guys have any idea please let me know.
Thanks.
#pragma mark - Connect/Disconnect
- (BOOL)connect {
if (!_xmppStream) {
NSLog(#"Setting up Stream");
[self setupStream];
}
if (![_xmppStream isDisconnected]) {
return YES;
}
NSString *jabberID = [[NSUserDefaults standardUserDefaults] stringForKey:#"userID"];
NSString *myPassword = [[NSUserDefaults standardUserDefaults] stringForKey:#"userPassword"];
if (jabberID == nil || myPassword == nil) {
return NO;
}
[_xmppStream setMyJID:[XMPPJID jidWithString:jabberID]];
_password = myPassword;
NSError *error = nil;
if (![_xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error]){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:[NSString stringWithFormat:#"Can't connect to server! %#", [error localizedDescription]] delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert show];
return NO;
}
return YES;
}
- (void)disconnect {
[self goOffline];
[self teardownStream];
}
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender {
[self goOnline];
//Stream Management
NSXMLElement *enable = [NSXMLElement elementWithName:#"enable" xmlns:#"urn:xmpp:sm:3"];
[enable addAttributeWithName:#"resume" stringValue:#"true"];
[_xsm.xmppStream sendElement:enable];
//Push
[self configurePushNotifications];
//
}
-(void)configurePushNotifications{
NSString *jabberID = [[NSUserDefaults standardUserDefaults] stringForKey:#"userID"];
NSXMLElement *iq = [NSXMLElement elementWithName:#"iq"];
[iq addAttributeWithName:#"type" stringValue:#"set"];
[iq addAttributeWithName:#"id" stringValue:idString];
NSXMLElement *push = [NSXMLElement elementWithName:#"push" xmlns:#"p1:push"];
NSXMLElement *keepalive = [NSXMLElement elementWithName:#"keepalive"];
[keepalive addAttributeWithName:#"max" integerValue:30];
NSXMLElement *session = [NSXMLElement elementWithName:#"session"];
[session addAttributeWithName:#"duration" integerValue:60];
NSXMLElement *body = [NSXMLElement elementWithName:#"body"];
[body addAttributeWithName:#"send" stringValue:#"all"];
[body addAttributeWithName:#"groupchat" stringValue:#"true"];
[body addAttributeWithName:#"from" stringValue:jabberID];
NSXMLElement *status = [NSXMLElement elementWithName:#"status"];
[status addAttributeWithName:#"type" stringValue:[NSString stringWithFormat:#"New message from %#",jabberID]];
NSXMLElement *offline = [NSXMLElement elementWithName:#"offline" stringValue:#"true"];
[push addChild:keepalive];
[push addChild:session];
[push addChild:body];
[push addChild:status];
[push addChild:offline];
NSXMLElement *notification = [NSXMLElement elementWithName:#"notification"];
[notification addChild:[NSXMLElement elementWithName:#"type" stringValue:#"applepush"]];
[notification addChild:[NSXMLElement elementWithName:#"id" stringValue:_userDeviceToken]];
[push addChild:notification];
NSXMLElement *appid = [NSXMLElement elementWithName:#"appid" stringValue:#"appid"];
[push addChild:appid];
[iq addChild:push];
[[self xmppStream] sendElement:iq];
}
- (void)setupStream {
_xmppStream = [[XMPPStream alloc] init];
_xmppStream.hostName = kHostName;
_xmppStream.hostPort = kHostPort;
_xmppStream.enableBackgroundingOnSocket = YES;
[_xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
//XMPPReconnect
_xmppReconnect = [[XMPPReconnect alloc] init];
[_xmppReconnect activate:_xmppStream];
//Stream Management
_xsm = [[XMPPStreamManagement alloc] init];
[_xsm enableStreamManagementWithResumption:YES maxTimeout:0];
[_xsm activate:_xmppStream];
//Last Activity
_xmppLastActivity = [[XMPPLastActivity alloc] initWithDispatchQueue:dispatch_get_main_queue()];
[_xmppLastActivity addDelegate:self delegateQueue:dispatch_get_main_queue()];
[_xmppLastActivity activate:_xmppStream];
}
- (void)goOnline {
XMPPPresence *presence = [XMPPPresence presence];
[[self xmppStream] sendElement:presence];
}
- (void)goOffline {
XMPPPresence *presence = [XMPPPresence presenceWithType:#"unavailable"];
[[self xmppStream] sendElement:presence];
}
- (void)teardownStream {
[_xmppStream disconnect];
[_xmppStream removeDelegate:self];
[_xmppReconnect removeDelegate:self];
[_xmppLastActivity removeDelegate:self];
[_xmppReconnect deactivate];
_xmppStream = nil;
_xmppReconnect = nil;
_xmppLastActivity = nil;
}
You need to make sure that you are passing the resource when you connect to ejabberd. The resource should be randomly generated on first app install and on subsequent login, you should always use the same resource. Otherwise you are created a new long running detached session on each new login on the server and causing messages to be routed to all pending sessions. When those expires they are routed again etc.
In XMPP, the resource is the identifier of the device basically. You need to generate the JID for login with a string of form "user#domain/resource"
you should notify stream management to disconnect your session and
call this method for disconnect in tearDown :
[self.stream disconnectAfterSending];

FBWebDialogs presentRequestsDialogModallyWithSession is not working?

This code is not generating notification on friend's end.But sending successully generating no error.I am building a app for Game url on friend to invite them to play.i have written below code to send url.it's working fine and not generating no error but user is not getting any request for App.
//Fbwebdialog generating no error
[FBWebDialogs presentRequestsDialogModallyWithSession:[FBSession activeSession]
message:[NSString stringWithFormat:#"I just smashed friends! Can you beat it?"]
title:nil
parameters:params
handler:^(FBWebDialogResult result, NSURL *resultURL, NSError *error) {
if (error) {
// Case A: Error launching the dialog or sending request.
NSLog(#"Some errorr: %#", [error description]);
UIAlertView *alrt = [[UIAlertView alloc] initWithTitle:#"Invitiation Sending Failed" message:#"Unable to send inviation at this Moment, please make sure your are connected with internet" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alrt show];
} else {
if (![resultURL query]) {
return ;
NSLog(#"User canceled request.");
} else {
NSDictionary *params = [self parseURLParams:[resultURL query]];
NSMutableArray *recipientIDs = [[NSMutableArray alloc] init];
for (NSString *paramKey in params){
if ([paramKey hasPrefix:#"to["]){
[recipientIDs addObject:[params objectForKey:paramKey]];
}
}
if ([params objectForKey:#"request"]){
NSLog(#"Request ID: %#", [params objectForKey:#"request"]);
NSArray *requestIDs=[params objectForKey:#"request"];
}
if ([recipientIDs count] > 0){
//[self showMessage:#"Sent request successfully."];
//NSLog(#"Recipient ID(s): %#", recipientIDs);
// punGameViewController *pun=[[punGameViewController alloc]initWithNibName:#"punGameViewController" bundle:nil];
UIAlertView *alrt = [[UIAlertView alloc] initWithTitle:#"Success!" message:#"Successfully send" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alrt show];
// [self.navigationController pushViewController:pun animated:YES];
}
}
}
}];
//end of code here
check it find the reason not generating notification.
I found my answer to this question on a previously answered S/O question. Basically, you need to set the App Store Id and Bundle Id in the Facebook App settings in order for invites to get sent. You can find that info: here
Notifications sent by your app is only received on mobile devices if your app is a game. If your app is not a game, notifications are still delivered to the App Center on the desktop.

iPhone to retrieve gmail account details in app from setting

I am making an application where I want to send an email using smtp server.
It's working fine but if user does not provide the correct gmail account details such as (email id and password) email is not send.
What I want to do is I want to access user gmail account details from setting tab of the iPhone into my app?
Is it possible to do retrieve the gmail account detail into the app?
Please help me out with this.
Following is my code:
-(IBAction)sendemail
{
SKPSMTPMessage *testMsg = [[SKPSMTPMessage alloc] init];
//testMsg.fromEmail = #"Lexi mobile";//nimit51parekh#gmail.com
testMsg.fromEmail = soundOn;
NSLog(#"str_Uname=%#",testMsg.fromEmail);
//str_info = [str_info stringByReplacingOccurrencesOfString:#"," withString:#""];
testMsg.toEmail = [string_emailinfo objectAtIndex:0];
NSLog(#"autoemail=%#",testMsg.toEmail);
testMsg.relayHost = #"smtp.gmail.com";
testMsg.requiresAuth = YES;
testMsg.login = soundOn;
NSLog(#"autoelogin=%#",testMsg.login);
testMsg.pass = vibrateOn;
NSLog(#"autopass=%#",testMsg.pass);
testMsg.subject = #"Photo Sharing";
testMsg.wantsSecure = YES;
NSURL *url = [[NSURL alloc]initWithString:#"http://itunes.apple.com/us/app/umix-radio/id467041430?mt=8"];
NSString *msg2 = [NSString stringWithFormat:#"<html><b>DOWNLOAD NOW</b>&nbsp&nbsp</html>",url];
NSString *sendmsg=[[NSString alloc]initWithFormat:#"%#",msg2];
NSLog(#"automsg=%#",sendmsg);
testMsg.delegate = self;
NSDictionary *plainPart = [NSDictionary dictionaryWithObjectsAndKeys:#"text/plain",kSKPSMTPPartContentTypeKey,
sendmsg,kSKPSMTPPartMessageKey,#"8bit",kSKPSMTPPartContentTransferEncodingKey,nil];
testMsg.parts = [NSArray arrayWithObjects:plainPart,nil];
[testMsg send];
// [self DeleteRowAfterSending];
//[self performSelector:#selector(DeleteRowAfterSending) withObject:nil afterDelay:5.0];
}
-(void)messageSent:(SKPSMTPMessage *)message
{
[message release];
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Success" message:#"Your email is sent successfully" delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
[alert release];
NSLog(#"delegate - message sent");
}
-(void)messageFailed:(SKPSMTPMessage *)message error:(NSError *)error
{
[message release];
// open an alert with just an OK button
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Fail" message:#"Message sending failure" delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
[alert release];
NSLog(#"delegate - error(%d): %#", [error code], [error localizedDescription]);
}
What i want to do is i want to access user gamil account details from
setting tab of the iPhone into my app? is it possible to do retrive
the gamil account detail into the app?
No, and with good reason: that functionality would allow any developer access to anyone's e-mail account.
That would be a massive security hole.
Much like it is with Location Services, you're just going to have to ask the user to enter their e-mail address and password. And hope they want to trust your app with that kind of personal information. (Assuming Apple approves your app at all.)
Let the user give your app authorization from Google. check the oauth autorization with google api at their developers site?
https://developers.google.com/accounts/docs/OAuth2
As usual the user signs in with his account through google api and returns back to you an access_token to get information back from his account including his email which you need.

XMPPFramework not sending presence

Im developing an app for iPhone, in wich one of the functionalities is an instant message system, using XMPPFramework. By now, im testing it with Google Talk. The delegate is the same class that manages the User Interface. So, I got this code:
In viewDidLoad:
- (void)viewDidLoad
{
[super viewDidLoad];
[self setupStream];
}
The setupStream method:
- (void) setupStream
{
NSLog(#"Inside setupStream");
xmppStream = [[XMPPStream alloc] init];
[xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
[self connect];
}
The connect method:
- (BOOL) connect
{
NSLog(#"Inside connect method");
General *general = [General sharedManager];//this is a singleton to manage settings for every user
NSString *chatid;
NSString *chatpass;
//chatid=[general user];
chatid=#"somegmailaccount#gmail.com";
xmppStream.myJID=[XMPPJID jidWithString:chatid];
if (![xmppStream isDisconnected]) {
return YES;
}
NSError *error = nil;
if (![xmppStream connect:&error])
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error"
message:[NSString stringWithFormat:#"Can't connect to server %#", [error localizedDescription]]
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
return NO;
}
return YES;
}
In xmppStreamDidConnect method:
- (void) xmppStreamDidConnect:(XMPPStream *)sender
{
[xmppStream authenticateWithPassword:#"password" error:NULL];
[self goOnline];
}
And goOnline method:
- (void) goOnline
{
XMPPPresence *presence = [XMPPPresence presence];
[[self xmppStream] sendElement:presence];
NSLog(#"Presence sent");
}
With this, the presence is not sent. I have another google account that I try for testing (say, testing#gmail.com) and in this account the presence of somegmailaccount.gmail.com is not seen. Both accounts are connected and know each other, since I used this same accounts to develop the Android app.
Any idea about what i´m doing wrong? Any help is appreciated.
Thank you very much.
I found it! The presence is not sent this way:
XMPPPresence *presence = [XMPPPresence presence];
[[self xmppStream] sendElement:presence];
Insted, i have done it this way:
NSXMLElement *presence = [NSXMLElement elementWithName:#"presence"];
[xmppStream sendElement:presence];
This way, the presence is sent without any problem :)
With this code, i implement method xmppStreamDidAuthenticate:(XMPPStream *)sender
and the program DO enter that method without any call from my code. But if i put
[xmppStream setHostName:#"talk.google.com"];
[xmppStream setHostPort:5222];
... in method connect, the program DO NOT enter that method, nor xmppStreamDidConnect.
Im getting mad.

How to send an email to a receipent in background in iOS5?

In an iPhone app,I want to send an email to a person who has forgotten about their passcode . I want to send the mail in background (cant use MFMailComposeViewController for this) and also the app must not be pushed to background . Is there a way to achieve this?
The best way of doing this is using SKPSMTPMessage. You can download it from here: https://github.com/jetseven/skpsmtpmessage This is a very easy solution that I have used before for using "Forgot Password" solutions in iOS apps. To implement simply drag the downloaded files into your application, #import the the "SKPSMTPMessage.h" into your class, and implement the following code:
.h
#import "SKPSMTPMessage.h"
#interface SomeView : UIViewController <SKPSMTPMessageDelegate> {
}
- (IBAction)forgotPassword;
.m
- (IBAction)forgotPassword {
SKPSMTPMessage *forgotPassword = [[SKPSMTPMessage alloc] init];
[forgotPassword setFromEmail:#"some-email#gmail.com"]; // Change to your email address
[forgotPassword setToEmail:#"user-email#gmail.com"]; // Load this, or have user enter this
[forgotPassword setRelayHost:#"smtp.gmail.com"];
[theMessage setRequiresAuth:YES]; // GMail requires this
[forgotPassword setLogin:#"some-email#gmail.com"]; // Same as the "setFromEmail:" email
[forgotPassword setPass:#"password"]; // Password for the Gmail account that you are sending from
[forgotPassword setSubject:#"Forgot Password: My App"]; // Change this to change the subject of the email
[forgotPassword setWantsSecure:YES]; // Gmail Requires this
[forgotPassword setDelegate:self]; // Required
NSString *newpassword = #"helloworld";
NSString *message = [NSString stringWithFormat:#"Your password has been successfully reset. Your new password: %#", newpassword];
NSDictionary *plainPart = [NSDictionary dictionaryWithObjectsAndKeys:#"text/plain", kSKPSMTPPartContentTypeKey, message, kSKPSMTPPartMessageKey, #"8bit" , kSKPSMTPPartContentTransferEncodingKey, nil];
[forgotPassword setParts:[NSArray arrayWithObjects:plainPart, nil]];
[forgotPassword send];
}
Also be sure to include the following methods in the .m. You can change the contents of the UIAlertViews depending on what you want to display to the user.
- (void)messageSent:(SKPSMTPMessage *)message {
NSLog(#"Message Sent");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Password Reset" message:#"Check your email for your new password." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}
- (void)messageFailed:(SKPSMTPMessage *)message error:(NSError *)error {
NSLog(#"Message Failed With Error(s): %#", [error description]);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"There was an error reseting your password. Please try again later." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}
You also need to do the following before this will work.
Your Target -> Get Info -> Build -> All Configurations -> Other Link Flags: "-ObjC"
If you need help with this, see http://developer.apple.com/qa/qa2006/qa1490.html
EDIT:
* CFNetwork.framework must also be added for this to work! *
Let me know if you have any more questions.
Thanks,
Jacob
You can't use MFMailComposeViewController to do this. No API will allow you to send emails or any kind of message on behalf of the user without he seeing it.
The only I see is to make a call to your server and the server send the email, something like this:
NSURLRequest requestWithURL:[NSURL urlWithString:#"http://server.com/send_passcode?to=email#lala.com"]];
You cannot send SMS/Email without user acceptance. But there are a lot of web-services in internet which can send SMS/Email. I guess some app uses those services or uses own.
You CAN send email in the background (without using the default MFMail Controller). BUT you still need the user to fill out whatever form (or content you want to email) and have them click "Send".
Here is my post on how to do it. It includes code and images.
Locking the Fields in MFMailComposeViewController
P.S. this works and Apple has approved over 10 of my apps that use this code/method.
In reference to the PostageApp comment below if you wanted to send emails without any hassle of setting up an SMTP client you can check out the PostageKit wrapper for using the PostageApp service. Let's you send emails with a couple lines of code reliably.
https://github.com/twg/PostageKit
May be you should implement PHP script that will send out email to user. In ios, you can use POST method in NSURLConnection to call PHP script. You can find many scripts on Google to send out email to user.
Download SKPSMTP Library and import
#import "SKPSMTPMessage.h"
#import "NSData+Base64Additions.h"
-(IBAction)btnRecoverClicked:(id)Sender;
Then implement the method for sending mail in background.
-(IBAction) btnRecoverClicked:(id)sender {
NSString *str=#"Your password is:";
NSString *strUserPassword=[NSString stringWithFormat:#"%# %#",str,struserPassword];
NSLog(#"Start Sending");
SKPSMTPMessage *emailMessage = [[SKPSMTPMessage alloc] init];
emailMessage.fromEmail = #"XXXXX"; //sender email address
emailMessage.toEmail = struserEmail; //receiver email address
emailMessage.relayHost = #"smtp.gmail.com";
//emailMessage.ccEmail =#"your cc address";
//emailMessage.bccEmail =#"your bcc address";
emailMessage.requiresAuth = YES;
emailMessage.login = #"xxxxxxxx"; //sender email address
emailMessage.pass = #"XXXXXXX"; //sender email password
emailMessage.subject =#"Password Recovery";
emailMessage.wantsSecure = YES;
emailMessage.delegate = self; // you must include <SKPSMTPMessageDelegate> to your class
NSString *messageBody = [NSString stringWithFormat:#"Your password is: %#",struserPassword]
;
//for example : NSString *messageBody = [NSString stringWithFormat:#"Tour Name: %#\nName: %#\nEmail: %#\nContact No: %#\nAddress: %#\nNote: %#",selectedTour,nameField.text,emailField.text,foneField.text,addField.text,txtView.text];
// Now creating plain text email message
NSDictionary *plainMsg = [NSDictionary
dictionaryWithObjectsAndKeys:#"text/plain",kSKPSMTPPartContentTypeKey,
messageBody,kSKPSMTPPartMessageKey,#"8bit",kSKPSMTPPartContentTransferEncodingKey,nil];
emailMessage.parts = [NSArray arrayWithObjects:plainMsg,nil];
//in addition : Logic for attaching file with email message.
/*
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"filename" ofType:#"JPG"];
NSData *fileData = [NSData dataWithContentsOfFile:filePath];
NSDictionary *fileMsg = [NSDictionary dictionaryWithObjectsAndKeys:#"text/directory;\r\n\tx-
unix-mode=0644;\r\n\tname=\"filename.JPG\"",kSKPSMTPPartContentTypeKey,#"attachment;\r\n\tfilename=\"filename.JPG\"",kSKPSMTPPartContentDispositionKey,[fileData encodeBase64ForData],kSKPSMTPPartMessageKey,#"base64",kSKPSMTPPartContentTransferEncodingKey,nil];
emailMessage.parts = [NSArray arrayWithObjects:plainMsg,fileMsg,nil]; //including plain msg and attached file msg
*/
[emailMessage send];
// sending email- will take little time to send so its better to use indicator with message showing sending...
}
To handle the success and fail use
-(void)messageSent:(SKPSMTPMessage *)message{
NSLog(#"delegate - message sent");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Message sent to your mail." message:nil delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles: nil];
[alert show];
}
and
-(void)messageFailed:(SKPSMTPMessage *)message error:(NSError *)error{
// open an alert with just an OK button
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error!" message:[error localizedDescription] delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles: nil];
[alert show];
NSLog(#"delegate - error(%d): %#", [error code], [error localizedDescription]);
}
https://github.com/troyz/MailUtil
I have used library above to send mail in background, so it works.
pod "MailUtil", :git => 'https://github.com/troyz/MailUtil.git', :tag => '0.1.0'
Swift code is here:
import MailUtil
SendEmailOperation.setupConfig(withServer: "smtp.foo.com", withFrom: "foo#mailserver.com", withLogin: "foo#mailserver.com", withPassword: "*********")
let operation = SendEmailOperation(to: "foo#mailserver.com", subject: "Hello", body: "world", path: "/selected/path/for/your/file.pdf")
operation?.completionBlock = {
debugPrint("Mail sent!")
DispatchQueue.main.async {
//showMailSentPopup()
}
}
do {
try SendEmailOperation.sendEmail(operation)
} catch {
debugPrint("Mail could not sent or sending result could not handle - \(error)")
}