2009-12-13 31 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。但是你必須小心與比賽條件對您的數據,特別是如果你正在處理多個請求