使用smtp连接ios发送邮件时显示等待视图?

问题描述

| 我正在开发一个使用邮件核心引擎发送邮件的应用程序。我创建了自己的viewController发送邮件。我要在邮件发送过程中显示等待视图。邮件发送完成后,总是显示我的等待视图。这是某种线程问题吗? 这是我用来发送邮件代码
- (IBAction) sendTapped:(id) sender {

[txtfSubject resignFirstResponder];
[txtfReceptient resignFirstResponder];
[txtvMessageBody resignFirstResponder];

[self setTo:txtfReceptient.text];
[self setFrom:username];
[self setSubject:txtfSubject.text];
[self setBody:txtvMessageBody.text];

[self performSelector:@selector(prepareAndSendMail) withObject:nil afterDelay:0.34];
}


- (void) prepareAndSendMail {


[WNAppDelegate performSelectorOnMainThread:@selector(showWaitingView) withObject:nil waitUntilDone:NO];

//Todo: send mail here
CTCoreMessage *msg = [[CTCoreMessage alloc] init];
[msg setTo:[myMessage to]];
[msg setFrom:[myMessage from]];

//Encode message here
Nsstring *encodedMessage = nil;

@try {
    encodedMessage = [self encodeMessage:txtvMessageBody.text];
}
@catch (NSException * e) {
    NSLog(@\"An exception occurred while encoding message\");
}
@finally {
    if(encodedMessage){
        [msg setBody:encodedMessage];
    }
}

[msg setSubject:[myMessage subject]];

BOOL success =  [self sendMailOnAnotherThread:msg];

[msg release];

[WNAppDelegate performSelectorOnMainThread:@selector(removeWaitingView) withObject:nil waitUntilDone:NO];
//[appDelegate removeWaitingView];
if(!success) {
    UIAlertView * empty_alert = [[UIAlertView alloc] initWithTitle:@\"Error\"
                                                           message:@\"Could not send.\" 
                                                          delegate:nil 
                                                 cancelButtonTitle:@\"OK\" 
                                                 otherButtonTitles:nil];
    [empty_alert show];
    [empty_alert autorelease];
    return;
}   
else {
    //Message sent successfully
    if(self.target && [self.target respondsToSelector:@selector(messageSentSuccessfully)]){
        [self.target messageSentSuccessfully];
    }

    WN_POST_NOTIFICATION(kMessageSentSuccessfully,nil);
}

[self dismissModalViewControllerAnimated:YES];  
 }

- (BOOL) sendMailOnAnotherThread:(CTCoreMessage*)message {


BOOL success = YES;

BOOL auth = YES;
BOOL tls = YES;

@try {
    [CTSMTPConnection sendMessage:message server:GMAIL_SERVER  username:username
                         password:password port:GMAIL_PORT_Number useTLS:tls useAuth:auth];
}
@catch (NSException * e) {
    //Msg Failed to send;
    success = FALSE;
}
return success;     
}
    

解决方法

好的,谢谢您提供的所有信息。现在问题已解决。 我在这里发布我的代码,以防有人需要它。
- (IBAction) sendTapped:(id) sender {

[txtfSubject resignFirstResponder];
[txtfReceptient resignFirstResponder];
[txtvMessageBody resignFirstResponder];

[self setTo:txtfReceptient.text];
[self setFrom:username];
[self setSubject:txtfSubject.text];
[self setBody:txtvMessageBody.text];

[self performSelector:@selector(prepareAndSendMail) withObject:nil afterDelay:0.34];
}


- (void) prepareAndSendMail {

//[((WalnutAppDelegate*)WNAppDelegate) performSelectorOnMainThread:@selector(showWaitingView) withObject:nil waitUntilDone:NO];
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSThread *aNewThread = [[[NSThread alloc] initWithTarget:((WalnutAppDelegate*)WNAppDelegate) selector:@selector(showWaitingView) object:nil] autorelease];
[aNewThread start];


//[NSThread detachNewThreadSelector: toTarget:((WalnutAppDelegate*)WNAppDelegate) withObject:nil];

//TODO: send mail here
CTCoreMessage *msg = [[CTCoreMessage alloc] init];
[msg setTo:[myMessage to]];
[msg setFrom:[myMessage from]];

//Encode message here
NSString *encodedMessage = nil;

@try {
    encodedMessage = [self encodeMessage:txtvMessageBody.text];
}
@catch (NSException * e) {
    NSLog(@\"An exception occurred while encoding message\");
}
@finally {
    if(encodedMessage){
        [msg setBody:encodedMessage];
    }
}

[msg setSubject:[myMessage subject]];

BOOL success =  [self sendMailOnAnotherThread:msg];

[msg release];

//[NSThread detachNewThreadSelector:@selector(removeWaitingView) toTarget:((WalnutAppDelegate*)WNAppDelegate) withObject:nil];

[((WalnutAppDelegate*)WNAppDelegate) performSelectorOnMainThread:@selector(removeWaitingView) withObject:nil waitUntilDone:NO];
[pool drain];


if(!success) {
    UIAlertView * empty_alert = [[UIAlertView alloc] initWithTitle:@\"Error\"
                                                           message:@\"Could not send.\" 
                                                          delegate:nil 
                                                 cancelButtonTitle:@\"OK\" 
                                                 otherButtonTitles:nil];
    [empty_alert show];
    [empty_alert autorelease];
    return;
}   
else {
    //Message sent successfully
    if(self.target && [self.target respondsToSelector:@selector(messageSentSuccessfully)]){
        [self.target messageSentSuccessfully];
    }

    WN_POST_NOTIFICATION(kMessageSentSuccessfully,nil);
}

[self dismissModalViewControllerAnimated:YES];  
}

- (BOOL) sendMailOnAnotherThread:(CTCoreMessage*)message {


BOOL success = YES;

BOOL auth = YES;
BOOL tls = YES;

@try {
    [CTSMTPConnection sendMessage:message server:GMAIL_SERVER  username:username
                         password:password port:GMAIL_PORT_Number useTLS:tls useAuth:auth];
}
@catch (NSException * e) {
    //Msg failed to send;
    success = FALSE;
}
return success;     
}

- (void)showWaitingView {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

CGRect frame = CGRectMake(90,190,32,32);
UIActivityIndicatorView* progressInd = [[UIActivityIndicatorView alloc] initWithFrame:frame];
[progressInd startAnimating];
progressInd.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;

frame = CGRectMake(130,193,140,30);
UILabel *waitingLable = [[UILabel alloc] initWithFrame:frame];
waitingLable.text = @\"Processing...\";
waitingLable.textColor = [UIColor whiteColor];
waitingLable.font = [UIFont systemFontOfSize:20];;
waitingLable.backgroundColor = [UIColor clearColor];
frame = [[UIScreen mainScreen] applicationFrame];
UIView *theView = [[UIView alloc] initWithFrame:frame];
theView.backgroundColor = [UIColor blackColor];
theView.alpha = 0.7;
theView.tag = 999;
[theView addSubview:progressInd];
[theView addSubview:waitingLable];

[progressInd release];
[waitingLable release];

[window addSubview:[theView autorelease]];
[window bringSubviewToFront:theView];
[pool drain];
}

- (void)removeWaitingView {
UIView *v = [window viewWithTag:999];
if(v) [v removeFromSuperview];

}
    ,是的。您需要返回运行循环才能更新UI。因此,最好在主线程中显示等待视图,在后台线程中发送邮件,然后再次隐藏并删除主线程中的等待视图。您应该只从主线程更新UI。您可以使用performSelectorInBackground和performSelectorOnMainThread来轻松实现,而无需手动创建线程。您也可以这样使用dispatch_async:
//show waiting view
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{
    //prepare mail here

    dispatch_async(dispatch_get_main_queue(),^{
        //send mail
        //hide waiting view
    });
});
    ,由于您正在主线程上执行
prepareAndSendMail
,因此在当前运行循环结束之后,
WNAppDelegate performSelectorOnMainThread:@selector(showWaitingView) withObject:nil waitUntilDone:NO];
将调用
showWaitingView
,此时您将已发送邮件。将
waitUntilDone:
设定为
YES
将显示您想要的等待时间。