Запутался в порядке стрельбы - PullRequest
0 голосов
/ 01 ноября 2011

Я пытаюсь адаптировать учебник о мыльных веб-запросах.В учебном пособии нажатие кнопки вызывает метод sendRequest, а в didEndElement он устанавливает метку для результирующего «мира приветствия».Работает отлично.Теперь я хочу взять метод 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 Ответ

1 голос
/ 01 ноября 2011

Методы подключения являются асинхронными, то есть они не работают последовательно, как вы ожидаете, а работают в фоновом режиме, а затем отправляют сообщение (событие) вашему приложению после завершения. Если они этого не сделали, то когда пользователь нажал кнопку, весь интерфейс блокировался до тех пор, пока не был выполнен запрос SOAP.

Таким образом, вам необходимо добавить greeting.text = [soap getResult] к обратному вызову (метод делегата), который должен быть запущен с

-(void)connectionDidFinishLoading:(NSURLConnection *)connection

После звонка [xmlParser parse].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...