我使用这段代码来创建一些 NSOperations 并将它们添加到队列中:
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 子类本身的错误,这条线不起作用?
有谁可以帮我离开这里吗?
非常感谢,
杰克