I use the following hack-job code to perform a series of SOAP requests that download data from a server for use in the application:
This code is called when the ‘update’ button is pressed:
- (IBAction) update {
UIAlertView *errorView;
if([[Reachability reachabilityForInternetConnection] currentReachabilityStatus] == NotReachable) {
errorView = [[UIAlertView alloc]
initWithTitle: @"Network Error"
message: @"No Network connection availible!"
delegate: self
cancelButtonTitle: @"OK" otherButtonTitles: nil];
[errorView show];
}
else
{
[appDelegate.categories removeAllObjects];
[appDelegate.currencies removeAllObjects];
[appDelegate.projects removeAllObjects];
HUD = [MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES];
HUD.labelText = @"Downloading..";
[self requestCategories];
}
}
Below is a typical request, I use approximately 6 of them.
// SOAP requests
- (void) requestCategories {
// Indeterminate mode
categories = [[NSMutableArray alloc] init];
xmlBlock = CATEGORY;
NSString *soapMsg =
[NSString stringWithFormat:
@"<?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>"
];
//---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:@"http://tempuri.org/Categories"
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];
}
}
Below are my delegate methods for NSURLConnection (and a parsing method):
-(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);
if (xmlBlock == CATEGORY){
[self parseXML:webData];
[self requestCurrencies];
}
else if (xmlBlock == CURRENCY){
[self parseXML:webData];
[self requestNominals];
}
else if (xmlBlock == NOMINAL){
[self parseXML:webData];
[self requestProjects];
}
else if (xmlBlock == PROJECT){
[self parseXML:webData];
[self requestRegister];
}
else {
[self parseXML:webData];
HUD.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"37x-Checkmark.png"]];
HUD.labelText = @"Done!";
HUD.mode = MBProgressHUDModeCustomView;
[HUD hide:YES afterDelay:2];
}
}
- (void) parseXML: (NSMutableData *)localWebData {
xmlParser = [[NSXMLParser alloc] initWithData: localWebData];
[xmlParser setDelegate: self];
[xmlParser setShouldResolveExternalEntities:YES];
[xmlParser parse];
}
I don’t think you need to see my xml parsing delegate methods (if you do let me know). My question is, is there a better way to implement this functionality in my app? As in perform the requests one after another while displaying some kind of progress indicator to the user?
Thanks,
Jack
use NSOperation queue, that is make your class a subclass of NSOperation in which you are sending the request to service, and rename of your method to main. then make the property of this class in parent class and add all the request in operation queue. And for the finishing, use keyobserver for your that property of nsopertion subclass