2011-11-01 71 views
0

我想改編一個關於肥皂web請求的教程。在教程中,點擊按鈕調用sendRequest方法,在didEndElement中,它爲最終的「hello world」設置一個標籤。很棒。現在我想採用sendRequest方法並讓它返回一個值。問題是我似乎無法理解被調用的委託方法何時被觸發。這是我使用的代碼:困惑的方法射擊的順序

-(void) sendRequest 
{ 
    recordResults = FALSE; 

    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" 
          "<HelloWorld xmlns=\"http://tempuri.org/\" />\n" 
          "</soap:Body>\n" 
          "</soap:Envelope>\n", @"test" 
          ]; 
    NSLog(soapMessage); 

    NSURL *url = [NSURL URLWithString:@"http://devportal.xxxxxxx.net/ProductCrossReference.asmx"]; 
    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/HelloWorld" 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"); 
    } 
} 

-(NSString*) getResult 
{ 
    return soapResults; 
} 


-(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:@"HelloWorldResult"]) 
    { 
     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:@"HelloWorldResponse"]) 
    { 
     recordResults = FALSE; 
     [soapResults release]; 
    } 
} 

現在,我將在我的視圖控制器按鈕,點擊此代碼:

-(IBAction)buttonClick:(id)sender 
{ 
    SOAPService* soap = [[SOAPService alloc] init]; 
    [soap sendRequest]; 
    greeting.text = [soap getResult]; 
} 

我很困惑,爲什麼的getResult將用於連接的調用方法之前進行發射和xmlParser。如果我在greeting.text = [soap getResult];上放置了一個斷點,它會在-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:方法的斷點之前被擊中。不應該將該方法作爲sendRequest方法的結果調用嗎?還是我完全脫離基地?

回答

1

連接方法是異步的,這意味着它們不像您期望的那樣串行運行,而是在後臺運行,然後在完成後嚮應用程序發送消息(事件)。如果他們沒有這樣做,那麼當用戶按下按鈕時,整個接口將鎖定,直到SOAP請求完成。

因此,您需要添加greeting.text = [soap getResult]一個回調(委託方法),它應該從

-(void)connectionDidFinishLoading:(NSURLConnection *)connection

被解僱的[xmlParser parse]電話後。

+0

感謝您的回覆。好的,現在就明白爲什麼這些方法是以這種方式發射的。但是,我如何讓這個更加可重用,而不是讓它設置greeting.text。換句話說,我將如何讓它返回一個值?我希望能夠將值傳入sendRequest方法並返回結果,這可能嗎? – Nick

+0

你想要一個委託方法 - 看看這裏:http://stackoverflow.com/questions/2534094/what-is-a-delegate-in-objective-cs-iphone-development – Benjie

+0

真棒,感謝您的建議。我花了比我更多的時間來承認弄清楚整個代表事情,但最終發現這個資源正在做的事情附近的確切的東西我是 http://css.dzone.com/articles/do-not-publishcreating -你的 – Nick