代码之家  ›  专栏  ›  技术社区  ›  Mick Walker

NSURLConnection-是否可以等待/阻止请求?

  •  0
  • Mick Walker  · 技术社区  · 16 年前

    我需要等待SOAP Web服务的响应,我正在通过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不会等待请求完成,因此我无法执行此操作。

    4 回复  |  直到 11 年前
        1
  •  2
  •   Alfonso    16 年前

    [NSURLConnection sendSynchronousRequest:returningResponse:error:] .

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

        2
  •  1
  •   Community Mohan Dere    9 年前

    我刚刚发布了一个解决方案,它包装了一个异步NSURLConnection,以便能够阻止调用线程。以防你需要比标准更多的控制 [NSURLConnection sendSynchronousRequest:returningResponse:error:]

    NSURLConnection blocking wrapper implemented with semaphores

        3
  •  0
  •   Mike Abdullah    16 年前

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

        4
  •  0
  •   emathias    16 年前

    • 如果可以在整个请求过程中保持阻塞,您可能需要使用

        +[NSURLConnection sendSynchronousRequest:returningResponse:error:]
      

      但是,正如韦德所建议的,要小心在NSURLRequest中添加一个超时,否则连接可能会阻塞,应用程序将挂起。

    • 如果没有,您只需使用NSNotificationCenter即可。但您必须小心处理数据上的竞争条件,特别是在处理多个请求时

    推荐文章