2009-12-13 48 views
0

我需要等待从SOAP Web服务的响应,我通过调用NSURLConnection的,因为我需要处理返回的数据,然后从我的课它返回到调用的类..NSURLConnection - 是否可以等待/阻止请求?

这里是我的代码:

#import <Foundation/Foundation.h> 


@interface UsersBLL : NSObject { 

NSMutableData *webData; 
NSMutableString *soapResults; 
NSXMLParser *xmlParser; 
BOOL *recordResults; 
NSNumber *EmailCount; 
} 

@property(nonatomic, retain) NSMutableData *webData; 
@property(nonatomic, retain) NSMutableString *soapResults; 
@property(nonatomic, retain) NSXMLParser *xmlParser; 



-(int)checkEmailAddress:(NSString*)emailAddress; 
@end 

#import "UsersBLL.h" 


@implementation UsersBLL 
@synthesize webData; 
@synthesize soapResults; 
@synthesize xmlParser; 

-(id)init { 
self = [super init]; 
return self; 
} 

-(int)checkEmailAddress:(NSString*)emailAddress { 
// Build the SOAP envelope 
NSString *soapMessage = [NSString stringWithFormat: 
     @"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" 
     "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" 
     "<soap:Body>\n" 
     "<CheckEmailAddress xmlns=\"http://tempuri.org/\">\n" 
     "<EmailAddress>%@</EmailAddress>\n" 
     "</CheckEmailAddress>\n" 
     "</soap:Body>\n" 
     "</soap:Envelope>\n", emailAddress]; 

NSLog(soapMessage); 

NSURL *url = [NSURL URLWithString:@"http://photoswapper.mick-walker.co.uk/UsersService.asmx?op=CheckEmailAddress"]; 
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url]; 
NSString *msgLength = [NSString stringWithFormat:@"%d", [soapMessage length]]; 

[theRequest addValue: @"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; 
[theRequest addValue: @"http://tempuri.org/CheckEmailAddress" forHTTPHeaderField:@"SOAPAction"]; 
[theRequest addValue: msgLength forHTTPHeaderField:@"Content-Length"]; 
[theRequest setHTTPMethod:@"POST"]; 
[theRequest setHTTPBody: [soapMessage dataUsingEncoding:NSUTF8StringEncoding]]; 

NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self]; 

if(theConnection) 
{ 
    webData = [[NSMutableData data] retain]; 
} 
else 
{ 
    NSLog(@"theConnection is NULL"); 
} 
NSLog(@"%@", EmailCount); 
} 

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
{ 
[webData setLength: 0]; 
} 
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{ 
[webData appendData:data]; 
} 
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 
{ 
NSLog(@"ERROR with theConenction"); 
[connection release]; 
[webData release]; 
} 
-(void)connectionDidFinishLoading:(NSURLConnection *)connection 
{ 
NSLog(@"DONE. Received Bytes: %d", [webData length]); 
NSString *theXML = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding]; 
NSLog(theXML); 
[theXML release]; 

if(xmlParser) 
{ 
    [xmlParser release]; 
} 

xmlParser = [[NSXMLParser alloc] initWithData: webData]; 
[xmlParser setDelegate: self]; 
[xmlParser setShouldResolveExternalEntities: YES]; 
[xmlParser parse]; 

[connection release]; 
[webData release]; 
} 

-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *) namespaceURI qualifiedName:(NSString *)qName 
    attributes: (NSDictionary *)attributeDict 
{ 
if([elementName isEqualToString:@"CheckEmailAddressResult"]) 
{ 
    if(!soapResults) 
    { 
    soapResults = [[NSMutableString alloc] init]; 
    } 
    recordResults = TRUE; 
} 
} 
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string 
{ 
if(recordResults) 
{ 
    [soapResults appendString: string]; 
} 
} 
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName 
{ 
if([elementName isEqualToString:@"CheckEmailAddressResult"]) 
{ 
    recordResults = FALSE; 
    NSNumberFormatter *formatter = [[NSNumberFormatter alloc]init]; 
    EmailCount = [formatter numberFromString:soapResults]; 
      [formatter release]; 
    [soapResults release]; 
    soapResults = nil; 
} 
} 

@end 

CheckEmailAddress被声明为返回一个整数值(我知道它在上面的示例中没有返回任何内容)。

我想要的是通过CheckEmailAddress方法,返回从Web服务检索到的值。然而,由于调用NSURLConnection并没有等到请求完成,我不能这样做。

如果有人能给我任何潜在的变通方法,我将不胜感激。

回答

2

最简单的解决方案是使用[NSURLConnection sendSynchronousRequest:returningResponse:error:]

它不允许像您采取的方法那么多的控制,但通常对于大多数应用程序来说已经足够了。

+1

正是我正要建议 - 要注意的是,如果它永远不会返回出于某种原因,你的程序将挂。 – wadesworld 2009-12-13 21:58:20

+0

是的,当我提到一个似乎存在但不响应或由于某种原因无法访问的主机时,经常会遇到这种情况。但是,将超时设置为合理的值大部分时间都是这样。 – Alfonso 2009-12-13 22:19:55

+0

我很抱歉跟进另一个问题,但我看不到如何sendSynchronousRequest可以帮助我获取数据,解析它并从我的方法返回结果 关注 – 2009-12-13 22:27:04

0

你有两个选择:

  • 使用+[NSURLConnection sendSynchronousRequest:returningResponse:error:]

  • 计划在自定义runloop模式的连接,直到数据到达或者你有需要取消运行该模式的循环连接

0

这一切都取决于异步的水平,你需要:

  • 如果它是确定整个请求过程中保持封锁您可能需要使用

    +[NSURLConnection sendSynchronousRequest:returningResponse:error:] 
    

    不过,韦德的建议,要小心超时添加到您的NSURLRequest,否则连接可能块和你的应用程序将挂起。

  • 如果没有,您可以简单地使用NSNotificationCenter。但是你必须小心与比赛条件对您的数据,特别是如果你正在处理多个请求