2012-05-18 27 views
0

我使用這段代碼來創建一些NSOperations並將它們添加到隊列:的NSOperation子類不調用委託方法和NSOperationQueue不是等到完成

HUD = [MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES]; 
     //HUD.labelText = @"Downloading.."; 
     //HUD.dimBackground = YES; 

     /* Operation Queue init */ 
     NSOperationQueue *queue = [NSOperationQueue new]; 

     // Spawn request operations & add them to queue 
     SoapRequestOperation *operation = [[SoapRequestOperation alloc] initWithRequest:@"<?xml version=\"1.0\" encoding=\"utf-8\"?> <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/\"> <soap:Body> <Categories xmlns=\"http://tempuri.org/\"> <UID>string</UID> <Username>string</Username> <Password>string</Password> </Categories>  </soap:Body> </soap:Envelope>" andValue:@"Categories"]; 

     [queue addOperation:operation]; 

     operation = [[SoapRequestOperation alloc] initWithRequest:@"<?xml version=\"1.0\" encoding=\"utf-8\"?> <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/\"> <soap:Body> <Currencies xmlns=\"http://tempuri.org/\"> <UID>string</UID> <Username>string</Username> <Password>string</Password> </Currencies>  </soap:Body> </soap:Envelope>" andValue:@"Currencies"]; 

     [queue addOperation:operation]; 

     operation = [[SoapRequestOperation alloc] initWithRequest:@"<?xml version=\"1.0\" encoding=\"utf-8\"?> <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/\"> <soap:Body> <Nominals xmlns=\"http://tempuri.org/\"> <UID>string</UID> <Username>string</Username> <Password>string</Password> </Nominals> </soap:Body> </soap:Envelope>" andValue:@"Nominals"]; 

     [queue addOperation:operation]; 

     operation = [[SoapRequestOperation alloc] initWithRequest:@"<?xml version=\"1.0\" encoding=\"utf-8\"?> <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/\"> <soap:Body> <Projects xmlns=\"http://tempuri.org/\"> <UID>string</UID> <Username>string</Username> <Password>string</Password> </Projects>  </soap:Body> </soap:Envelope>" andValue:@"Projects"]; 

     [queue addOperation:operation]; 

     operation = [[SoapRequestOperation alloc] initWithRequest:@"<?xml version=\"1.0\" encoding=\"utf-8\"?> <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/\"> <soap:Body> <Register xmlns=\"http://tempuri.org/\"> <UID>string</UID> <Username>string</Username> <Password>string</Password> <OrganisationCode>string</OrganisationCode> </Register> </soap:Body> </soap:Envelope>" andValue:@"Register"]; 

     [queue addOperation:operation]; 

     [queue waitUntilAllOperationsAreFinished]; 

     [self reloadTableData]; 

     HUD.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"37x-Checkmark.png"]]; 
     HUD.mode = MBProgressHUDModeCustomView; 
     [HUD hide:YES afterDelay:2]; 

這是我的NSOperation子類.m文件:

#import "SoapRequestOperation.h" 
#import "Currency.h" 
#import "Category.h" 
#import "Project.h" 
#import "Constants.h" 

@implementation SoapRequestOperation 

@synthesize request, value; 

-(id) initWithRequest:(NSString *)l_Request andValue:(NSString *)l_Value{ 
    if (self = [super init]) { 
     /* do most of initialization */ 
     self.request = l_Request; 
     self.value = l_Value; 
     xmlBlock = 0; 
     appDelegate = [[UIApplication sharedApplication] delegate]; 
    } 
    return(self); 
} 

- (void) main { 
    if ([value isEqualToString:@"Category"]){ 
     xmlBlock = CATEGORY; 
    } 
    else if ([value isEqualToString:@"Currency"]){ 
     xmlBlock = CURRENCY; 
    } 
    else if ([value isEqualToString:@"Nominal"]){ 
     xmlBlock = NOMINAL; 
    } 
    else if ([value isEqualToString:@"Project"]){ 
     xmlBlock = PROJECT; 
    } 
    else { 
     xmlBlock = REGISTER; 
    } 

    NSString *soapMsg = request; 
    //---print it to the Debugger Console for verification--- 
    NSLog(@"%@", soapMsg); 
    NSURL *url = [NSURL URLWithString: 
        @"http://www.$^$%£%@%^£.co.uk/$$^$^£$^£.asmx"]; 
    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url]; 
    //---set the headers--- 
    NSString *msgLength = [NSString stringWithFormat:@"%d", 
          [soapMsg length]]; 
    [req addValue:@"text/xml; charset=utf-8" 
forHTTPHeaderField:@"Content-Type"]; 
    [req addValue:[NSString stringWithFormat:@"http://tempuri.org/%@", value] 
forHTTPHeaderField:@"SOAPAction"]; 
    [req addValue:msgLength forHTTPHeaderField:@"Content-Length"]; 
    //---set the HTTP method and body--- 
    [req setHTTPMethod:@"POST"]; 
    [req setHTTPBody: [soapMsg dataUsingEncoding:NSUTF8StringEncoding]]; 
    //[activityIndicator startAnimating]; 
    conn = [[NSURLConnection alloc] initWithRequest:req delegate:self]; 
    if (conn) { 
     webData = [NSMutableData data]; 
    } 
} 

-(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 { 

} 

-(void) connectionDidFinishLoading:(NSURLConnection *) connection { 
    NSLog(@"DONE. Received Bytes: %d", [webData length]); 
    NSString *theXML = [[NSString alloc] 
         initWithBytes: [webData mutableBytes] 
         length:[webData length] 
         encoding:NSUTF8StringEncoding]; 
    //---shows the XML--- 
    NSLog(@"%@", theXML); 

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

} 

//---when the start of an element is found--- 
-(void) parser:(NSXMLParser *) parser 
didStartElement:(NSString *) elementName 
    namespaceURI:(NSString *) namespaceURI 
qualifiedName:(NSString *) qName 
    attributes:(NSDictionary *) attributeDict { 
    currentElement = [elementName copy]; 

    //Category 
    if([currentElement isEqualToString:@"Item"]) 
    { 
     category = [[NSMutableDictionary alloc] init]; 
     categoryName = [[NSMutableString alloc] init]; 
    } 

    //Currency 
    if ([currentElement isEqualToString: @"Currency"]) { 
     currency = [[NSMutableDictionary alloc] init]; 
     countryName = [[NSMutableString alloc] init]; 
     currencyName = [[NSMutableString alloc] init]; 
     currencyUnit = [[NSMutableString alloc] init]; 
     shortName = [[NSMutableString alloc] init]; 
    } 

    //Nominal 
    if([currentElement isEqualToString:@"Nominal"]) 
    { 
     nominal = [[NSMutableDictionary alloc] init]; 
     name = [[NSMutableString alloc] init]; 
     description = [[NSMutableString alloc] init]; 
     paid = [[NSMutableString alloc] init]; 
    } 

    //Project 
    if([currentElement isEqualToString:@"Project"]) 
    { 
     project = [[NSMutableDictionary alloc] init]; 
     projectName = [[NSMutableString alloc] init]; 
     projectDescription = [[NSMutableString alloc] init]; 
    } 

    //Register 
    if([currentElement isEqualToString:@"RegisterResult"]) 
    { 
     elementFound = YES; 
    } 

} 

-(void)parser:(NSXMLParser *) parser foundCharacters:(NSString *)string 
{ 
    //Category 
    if (xmlBlock == CATEGORY){ 
     if ([currentElement isEqualToString: @"Item"]){ 
      [categoryName appendString:string]; 
     } 
    } 

    //Currency 
    if (xmlBlock == CURRENCY){ 
     if ([currentElement isEqualToString: @"CountryName"]){ 
      [countryName appendString:string]; 
     } 
     else if ([currentElement isEqualToString: @"CurrencyName"]){ 
      [currencyName appendString:string]; 
     } 
     else if ([currentElement isEqualToString: @"Unit"]){ 
      [currencyUnit appendString:string]; 
     } 
     else if ([currentElement isEqualToString: @"ShortName"]){ 
      [shortName appendString:string]; 
     } 
    } 

    //Nominal 
    if ([currentElement isEqualToString: @"Name"] && xmlBlock == NOMINAL){ 
     [name appendString:string]; 
    } 
    else if ([currentElement isEqualToString: @"Description"] && xmlBlock == NOMINAL){ 
     [description appendString:string]; 
    } 
    else if ([currentElement isEqualToString: @"Paid"]){ 
     [paid appendString:string]; 
    } 

    //Project 
    if (xmlBlock == PROJECT) { 
     if ([currentElement isEqualToString: @"Name"]){ 
      [projectName appendString:string]; 
     } 
     else if ([currentElement isEqualToString: @"Description"]){ 
      [projectDescription appendString:string]; 
     } 
    } 

    //Register 
    if (xmlBlock == REGISTER && elementFound){ 
     registerVal = string; 
    } 
} 

//---when the end of element is found--- 
-(void)parser:(NSXMLParser *)parser 
didEndElement:(NSString *)elementName 
namespaceURI:(NSString *)namespaceURI 
qualifiedName:(NSString *)qName 
{  
    if ([elementName isEqualToString:@"Item"]) 
    { 
     // save values to an item, then store that item into the array... 
     [category setObject:categoryName forKey:@"categoryName"]; 

     [categories addObject:[category copy]]; 

     Category *c = [[Category alloc] init]; 
     c.categoryName = categoryName; 
     c.totalValue = @"0.00"; 
     [appDelegate.categories addObject:c]; 

     NSLog(@"%d", [appDelegate.categories count]); 
    } 

    //Currency 
    if ([elementName isEqualToString: @"Currency"]) { 
     // save values to an item, then store that item into the array... 
     [currency setObject:countryName forKey:@"countryName"]; 
     [currency setObject:currencyName forKey:@"currencyName"]; 
     [currency setObject:currencyUnit forKey:@"unit"]; 
     [currency setObject:shortName forKey:@"shortName"]; 

     [currencies addObject:[currency copy]]; 

     Currency *c = [[Currency alloc] init]; 
     c.totalValue = @"0.00"; 
     c.countryName = countryName; 
     c.currencyName = currencyName; 
     double myDouble = [currencyUnit doubleValue]; 
     c.unit = myDouble; 
     c.shortName = shortName; 

     [appDelegate.currencies addObject:c]; 

     NSLog(@"%d", [appDelegate.currencies count]); 

    } 

    //Nominal 
    if ([elementName isEqualToString:@"Nominal"]) 
    { 
     // save values to an item, then store that item into the array... 
     [nominal setObject:name forKey:@"name"]; 
     [nominal setObject:description forKey:@"description"]; 
     [nominal setObject:paid forKey:@"paid"]; 

     [nominals addObject:[nominal copy]]; 

     NSLog(@"%d", [nominals count]); 

    } 

    if ([elementName isEqualToString:@"Project"]) 
    { 
     // save values to an item, then store that item into the array... 
     [project setObject:projectName forKey:@"projectName"]; 
     [project setObject:projectDescription forKey:@"projectDescription"]; 

     [projects addObject:[project copy]]; 

     Project *p = [NSEntityDescription 
         insertNewObjectForEntityForName:@"Project" 
         inManagedObjectContext:appDelegate.managedObjectContext]; 
     [p setValue:projectName forKey:@"name"]; 
     [p setValue:@"0.00" forKey:@"totalValue"]; 
     NSError *error; 
     if (![appDelegate.managedObjectContext save:&error]) { 
      NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]); 
     } 
     [appDelegate.projects addObject:p]; 

     NSLog(@"%d", [appDelegate.currencies count]); 
    } 

    if ([elementName isEqualToString:@"RegisterResult"]) 
    { 
     if ([registerVal isEqualToString:@"true"]){ 
      boolRegister = YES; 
     } 
     else { 
      boolRegister = NO; 
     } 

     NSLog(@"BOOL = %@", (boolRegister ? @"YES" : @"NO")); 

     elementFound = FALSE; 
    } 
} 

不幸的是,NSURLConnection的和的NSXMLParser委託方法不被稱爲(一切都是因爲它應該是在頭文件)。並且我不確定我是否完全理解該行:

[queue waitUntilAllOperationsAreFinished]; 

這應該不會導致調用線程等待所有操作完成?我有一種感覺,由於NSOperation子類本身的錯誤,這條線不工作?

任何人都可以幫助我嗎?

非常感謝,

傑克

+0

你必須在主線程上執行NSURLConnections。 NSOperations不在主線程上執行,這就是爲什麼你的連接不工作,爲什麼沒有任何代表被調用。 – shoughton123

+0

@ shoughton123我明白了,這個問題的答案也是如此:http://stackoverflow.com/questions/10654129/better-approach-to-performing-a-series-of-soap-requests-in-objective-c provided由薩阿德不正確?或者我誤解了?謝謝。 –

+0

你絕對不需要在主線程上運行NSURLConnections。 – Joel

回答

0

喬爾是正確的start方法,你應該調用main方法要在主線程上啓動,或者你需要永葆線程至極調用的方法ID。

相關問題