calling a method using self results in error - ios

I'm writing an App that is parsing Data from an XML-Doc on the web. So when it finishes loading it is supposed to call the Parsing Method as follows.
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
[self startParsingData];
}
This should work in theory, right? Problem is I'm getting this error:
Reciever type 'ffwDetailViewController' for instance message does not declare a method with selector 'startParsing Data'
I take it, that xCode thinks this method doesn't exist., but it does.
-(void)startParsingData{
NSXMLParser *dataParser = [[NSXMLParser alloc] initWithData:recievedData];
dataParser.delegate = self;
[dataParser parse];
}
I don't know what to do. I would really appreciate any help.
Switching their Position did the trick. Unfortunately, now the app crashes on pressing the Button. Here's the full code. I hope you can help me.
- (IBAction)getMissions:(id)sender {
if (recievedData) {
recievedData = nil;
}
_einsaetze.text=#"Pasing Data...";
NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://oliverengelhardt.de/ffw_app/test.xml"]]
cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
//Start loading Data
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection) {
recievedData = [NSMutableData data];
}else{
[_einsaetze setText:#"connection failed"];
}
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
[recievedData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
if (recievedData) {
[recievedData appendData:data];
}
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
_einsaetze.text=#"connnection failed";
}
-(void)startParsingData{
NSXMLParser *dataParser = [[NSXMLParser alloc] initWithData:recievedData];
dataParser.delegate = self;
[dataParser parse];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
[self startParsingData];
}
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
if ([elementName isEqualToString:#"element"]) {
NSString *myData = [NSString stringWithFormat:#"%#", [attributeDict objectForKey:#"myData"]];
_einsaetze.text = myData;
}
}

If -(void)startParsingData is not declared in the #interface section of the class (either in the .h or in an extension in the .m file) then -(void)startParsingData needs to be physically before -(void)connectionDidFinishLoading in the .m file.
What order are they in your .m file?

Related

When iOS GCD threading is applied, parsing of xml stops working

I'm working on an app where user sends data to a central database using a web service. The web service sends back an XML file with the primary key from the central database so the local database on the app is updated with this primary key. When I don't use GCD, everything works perfectly. As soon as I introduce threading, I don't seem to get the XML file to parse. It seems like the code sends the XML to the web service, but nothing happens thereafter. Is there something wrong with the way i implement threading? Here's the code sample:
-(void) viewDidLoad
{
dispatch_queue_t saveCentralDB = dispatch_queue_create("Writing Database", NULL);
dispatch_async(saveCentralDB, ^ {
NSLog(#"Created NEW THREAD to send info to CENTRAL DB");
NSString *soapMsg = [NSString stringWithFormat:
#"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
"<soap12:Envelope "
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" "
"xmlns:soap12=\"http://www.w3.org/2003/05/soap-envelope\">"
"<soap12:Body>"
"<InsertPurchase xmlns=\"http://tempuri.org/\">"
"<RequestObject xsi:type = \"SpazaPurchaseRequest\">"
"<PurchaseID>%#</PurchaseID>"
"<RemoteSpazaPurchaseID>%#</RemoteSpazaPurchaseID>"
"<UserID>%d</UserID>"
"<RetailerID>%#</RetailerID>"
"<ItemID>%#</ItemID>"
"<CostPrice>%#</CostPrice>"
"<Longitude>%#</Longitude>"
"<Latitude>%#</Latitude>"
"<DatePurchased>%#</DatePurchased>"
"<Barcode>%#</Barcode>"
"<BasketID>%#</BasketID>"
"</RequestObject>"
"</InsertPurchase>"
"</soap12:Body>"
"</soap12:Envelope>",#"0",pklPurchaseID1,fklUserID,fklRetailerID1,fklItemID1, lCostPrice1, sLongitude1, sLatitude1,dtPurchase1,sBarcode1,fklBasketID1];
//---print of the XML to examine---
NSLog(#"%#", soapMsg);
NSURL *url = [NSURL URLWithString:#"http://www.myapp.com/purchases/ProviderWS.asmx?op=InsertPurchase"];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
NSString *msgLength = [NSString stringWithFormat:#"%d", [soapMsg length]];
[req addValue:#"text/xml; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[req addValue:msgLength forHTTPHeaderField:#"Content-Length"];
[req setHTTPMethod:#"POST"];
[req setHTTPBody: [soapMsg dataUsingEncoding:NSUTF8StringEncoding]];
conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];
if (conn)
{
webData = [NSMutableData data];
}
});
}
I then implement the following methods to deal with the response from the Web Service.
/************************Processing the feedback XML returned by webservice*****************/
-(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];
//---prints the XML received---
NSLog(#"%#", theXML);
xmlParser = [[NSXMLParser alloc] initWithData: webData];
[xmlParser setDelegate: self];
[xmlParser setShouldResolveExternalEntities: YES];
[xmlParser parse];
}
The normal delegate methods are then implemented:
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
NSLog(#"XML Parsing Method: didStartElement");
//This is the first node that we search for. The information we want is contained within this node.
if ([elementname isEqualToString:#"ResponseMessage"])
{
currentCentralDBPurchase = [parsingCentralDBPurchaseXML alloc];
//Flag to indicate that we are within the ResponseMessage node/tag.
isStatus = YES;
}
}
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
NSLog(#"XML Parsing Method: foundCharacters");
currentNodeContent = (NSMutableString *) [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if (isStatus)
{
if ([elementname isEqualToString:#"PurchaseID"])
{
currentCentralDBPurchase.centralPurchaseID = currentNodeContent;
}
if ([elementname isEqualToString:#"RemotePurchaseID"])
{
currentCentralDBPurchase.localPurchaseID = currentNodeContent;
}
}
if ([elementname isEqualToString:#"ResponseMessage"])
{
//Update local database with the PurchaseID from the central database. This is how we will identify records that must still be sent to the central database.
//Now update the local database with purchases that have been sent to central database
// Get the DBAccess object;
DBAccess *dbAccess = [[DBAccess alloc] init];
[dbAccess UpdateCentralPurchaseID: [currentCentralDBPurchase.localPurchaseID integerValue] :[currentCentralDBPurchase.centralPurchaseID integerValue] ];
// Close the database because we are finished with it
[dbAccess closeDatabase];
currentCentralDBPurchase = nil;
//Clear the currentNodeContent node so we are ready to process the next one.
currentNodeContent = nil;
}
}
NSURLConnection initWithRequest: should be called on the main thread in this situation.
dispatch_async(dispatch_get_main_queue(), ^{
conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];
if (conn)
{
webData = [NSMutableData data];
}
});
It relies on RunLoop and Runloop is automatically working on the main thread. You can call initWithRequest on the other thread but you should execute RunLoop on the thread. However it is kind of difficult on a dispatch queue, thus using the main queue is helpful for the situation.

How to get the string value of xml format after parsing by the xml parser

The below given code is an example of webservice project which giving the symbol name of elements in periodic table. When I ran this project I didn't get the string value from xml parser.
-(IBAction)action:(id)sender
{
NSString *soapFormat = [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"
"<GetElementSymbol xmlns=\"http://www.webserviceX.NET/\">\n"
"<ElementName>%#</ElementName>\n"
"</GetElementSymbol>\n"
"</soap:Body>\n"
"</soap:Envelope>\n",txtcelsius.text];
NSLog(#"connextion:%#",soapFormat);
NSURL *locationofWebservice=[NSURL URLWithString:#"http://www.webservicex.net/webservices/periodictable.asmx"];
NSMutableURLRequest *theRequest=[[NSMutableURLRequest alloc]initWithURL:locationofWebservice];
NSLog(#"sopa len=%d",[soapFormat length]);
NSString *msgLength=[NSString stringWithFormat:#"%d",[soapFormat length]];
[theRequest addValue:#"text/xml" forHTTPHeaderField:#"Content-type"];
[theRequest addValue:#"http://www.webserviceX.NET/GetElementSymbol" forHTTPHeaderField:#"SOAPAction"];
[theRequest addValue:msgLength forHTTPHeaderField:#"Content-Length"];
[theRequest setHTTPMethod:#"POST"];
//the below encoding is used to send data over the net
[theRequest setHTTPBody:[soapFormat dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *connection=[[NSURLConnection alloc]initWithRequest:theRequest delegate:self];
if (connection)
{
webData=[[NSMutableData alloc]init];
}
else
{
NSLog(#"No connection");
}
}
-(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
{
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"Webservice" message:[error localizedFailureReason] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"DONE. Received Bytes: %d", [webData length]);
xmlParser= [[NSXMLParser alloc]initWithData:webData];
[xmlParser setDelegate:self];
[xmlParser parse];
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
NSLog(#"string in parse=%#",string);
nodeContent=[[NSMutableString alloc]init];
[nodeContent appendString:[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
NSLog(#"string in parse node=%#",nodeContent);
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if([elementName isEqualToString:#"GetElementSymbol"])
{
// finaldata=nodeContent;
NSLog(#"node content=%#",nodeContent);
txtft.text=nodeContent;
}
}
The code is an example of webservice project which giving the symbol of periodic table element. The response from the host side is in the below format:
<string xmlns="http://www.webserviceX.NET">
<NewDataSet> <Table> <Symbol>H</Symbol> </Table> </NewDataSet>
</string>
How can I convert this into string and display it into a textfield?
If you want to parse XML data, look into XMLDictionary. This is an easier way to parse the information and even easier to get at it.
It is an easy framework that easily parses your data into a neat and ordered hierarchy of NSDictionaries and NSArrays and all the data will appear as NSStrings.
https://github.com/nicklockwood/XMLDictionary

Calling NSXMLParser from static method does not parse

I'm trying to build a nice little class with NSXMLParser for my needs.
I'm calling the class this way:
ViewController.m:
[IDAN_XML_Parser setXmlString:soapMsg];
[IDAN_XML_Parser setStringToFind:#"userID"];
[IDAN_XML_Parser setHeader:kAPP_PASSWORD andHeaderValue:kAPP_HEADER];
[IDAN_XML_Parser setSetupXml:kWEB_SERVICE_URL];
[IDAN_XML_Parser prepareParsingAndGetResponse];
NSString *answer = [IDAN_XML_Parser getResponse];
NSLog(#"Response: %#", answer);
And my class is this:
.h file:
#import <Foundation/Foundation.h>
#interface IDAN_XML_Parser : NSObject <NSXMLParserDelegate, NSURLConnectionDelegate>
+ (void)setXmlString:(NSString *)theXML;
+ (void)setStringToFind:(NSString *)stringToFind;
+ (void)setSetupXml:(NSString *)webServicesURL;
+ (void)setHeader:(NSString *)headerKey andHeaderValue:(NSString *)headerValue;
+ (BOOL)prepareParsingAndGetResponse;
- (NSInteger)startParsing;
+ (BOOL)isParsingOK;
+ (IDAN_XML_Parser *)sharedXML;
+ (NSString *)getXMLString;
+ (NSString *)getResponse;
#end
.m file
#import "IDAN_XML_Parser.h"
#implementation IDAN_XML_Parser
NSString *matchingElement;
NSString *xmlString;
NSMutableData *webData;
NSURLConnection *conn;
NSString *soapHeader_key;
NSString *soapHeader_value;
NSURL *url;
BOOL isHeader = NO;
NSInteger didGetError = 0;
BOOL elementFound;
NSMutableString *soapResults;
NSString *returnedString;
NSXMLParser *xmlParser;
NSString *exceptionReason;
NSString *resultXML;
#pragma mark - Setup Parsing
+ (IDAN_XML_Parser *)sharedXML
{
static IDAN_XML_Parser *theParser;
#synchronized(self) {
if (!theParser)
theParser = [[self alloc] init];
}
return theParser;
}
+ (void)setXmlString:(NSString *)theXML
{
xmlString = theXML;
NSLog(#"\n\nXML TO SEND: %#", xmlString);
}
+ (void)setStringToFind:(NSString *)stringToFind
{
matchingElement = stringToFind;
}
+ (void)setHeader:(NSString *)headerKey andHeaderValue:(NSString *)headerValue
{
isHeader = YES;
soapHeader_key = headerKey;
soapHeader_value = headerValue;
}
+ (void)setSetupXml:(NSString *)webServicesURL
{
url = [NSURL URLWithString:webServicesURL];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
NSString *msgLength = [NSString stringWithFormat:#"%d", [xmlString length]];
[req addValue:#"text/xml; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[req addValue:msgLength forHTTPHeaderField:#"Content-Length"];
[req setHTTPMethod:#"POST"];
[req setHTTPBody: [xmlString dataUsingEncoding:NSUTF8StringEncoding]];
if (isHeader) {
[req setValue:soapHeader_value forHTTPHeaderField:soapHeader_key];
}
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
{
didGetError = 1;
NSLog(#"\n\nConnection Error: %#", error);
}
-(void) connectionDidFinishLoading:(NSURLConnection *) connection
{
resultXML = [[NSString alloc] initWithBytes:[webData mutableBytes]
length:[webData length]
encoding:NSUTF8StringEncoding];
didGetError = 0;
NSLog(#"\n\nRESPONSE XML: %#", resultXML);
}
+ (BOOL)prepareParsingAndGetResponse
{
NSInteger isParsingOK;
isParsingOK = [[self sharedXML] startParsing];
if (isParsingOK == 1) {
return YES;
} else {
return NO;
}
}
- (NSInteger)startParsing
{
#try {
xmlParser = [[NSXMLParser alloc] initWithData:webData];
[xmlParser setDelegate:self];
[xmlParser setShouldResolveExternalEntities:YES];
[xmlParser parse];
}
#catch (NSException *exception) {
didGetError = 1;
exceptionReason = exception.reason;
NSLog(#"Exception Reason: %#", exception.reason);
}
if (didGetError != 1) {
didGetError = 0;
}
return didGetError;
}
+ (NSString *)getXMLString
{
return resultXML;
}
+ (BOOL)isParsingOK
{
if (didGetError == 1) { // We have error
return 1;
} else { // We don't have error
return 0;
}
}
+ (NSString *)getResponse
{
return returnedString;
}
#pragma mark - Start Parsing
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
NSLog(#"START PARSING!");
if ([elementName isEqualToString:matchingElement]) {
if (!soapResults) {
soapResults = [[NSMutableString alloc] init];
}
elementFound = YES;
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if (elementFound) {
[soapResults appendString:string];
NSLog(#"\n\nsoapResults: %#", soapResults);
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:matchingElement]) {
returnedString = soapResults; // Save the element we found
elementFound = NO;
}
}
#end
I manage to send and get back the correct xml but it's actually doesn't start the parsing.
Any idea how can I solve it?
You are initiating an asynchronous NSURLConnection and then immediately starting the parsing process. You need to defer the initiation of the parsing until connectionDidFinishLoading, or you should do a synchronous NSURLConnection (but obviously, not from the main queue). Thus, while you're eventually getting a response, the parsing is undoubtedly initiated before the response has been received.

Get the entire XML downloaded data

I have an outdated application which use to download an XML document and parse it on the iPhone app, I used the NSURLConnection for that purpose:
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
//NSLog(#"Response :%#",response);
responseData = [[NSMutableString alloc] init];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSString *str = [[NSString alloc] initWithData:data
encoding:NSASCIIStringEncoding];
[responseData appendString:str];
[str release];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"DATA : %#",responseData);
if (responseData != nil) {
[self startParsing:responseData];//Parse the data
[responseData release];
}
}
Since moving to use NSXMLParserDelegate with AFXMLRequestOperation, I cannot figure out a way to get xml data properly:
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
[responseData appendString:elementName];
[responseData appendString:namespaceURI];
[responseData appendString:qName];
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
[responseData appendString:string];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
[responseData appendString:elementName];
[responseData appendString:namespaceURI];
[responseData appendString:qName];
}
-(void) parserDidEndDocument:(NSXMLParser *)parser{
[SVProgressHUD showSuccessWithStatus:#"Downloading completed"];
NSLog(#"DATA : %#",responseData);//not properly appended, tags delimeters are missing
if (responseData != nil) {
[self startParsing:responseData];
[responseData release];
}
}
How to append all the data received from the server in the responseData mutable string ? I debugged the data received after finishing downloading and the xml is missing tags delimeters <>. I think I ma missing the way to get the xml data.
P.S: Please note it's important that I get the xml in a NSMutableString object.
#Fermi
I used AFURLConnectionOperation as you recommended, it works fine with my purpose, but I noticed that my received data is not catched by the delegate methods, instead I can get the data in a completion block:
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:API_URL]];
AFURLConnectionOperation *operation = [[AFURLConnectionOperation alloc] initWithRequest:request];
operation.completionBlock = ^{
NSLog(#"Complete: %#",operation.responseString);//responseString is my data
};
[operation start];
[SVProgressHUD showWithStatus:#"Downloading files"];
wo since NSURLConnection delegate methods are not called, how can I manage failure, etc? Thanx.
AFXMLRequestOperation is explicitly intended to be used to return you an NSXMLDocument instance, NOT a raw XML string.
If you want the XML string use AFURLConnectionOperation and build the NSMutableString the same way you do with NSURLConnection.

call SOAP request in iOS [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I want to call SOAP request in iphone. But I do not know how to do it. Please give me some code of calling SOAP request in iphone as below code?
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<soap:Header>
<wsse:Security
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" soap:mustUnderstand="1">
<wsse:UsernameToken
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:Username>cbrown</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">welcome</wsse:Password></wsse:UsernameToken>
</wsse:Security>
</soap:Header>
<soap:Body xmlns:ns1="http://xmlns.oracle.com/bpel/aubi/mobile/Worklist">
<ns1:WorklistRetrievalREQ>
<ns1:WorklistType>HR_OFFER</ns1:WorklistType>
<ns1:Status>TODO</ns1:Status>
<ns1:Mode/>
</ns1:WorklistRetrievalREQ>
</soap:Body>
</soap:Envelope>
This is how you can call SOAP web services :
In your .h file declare :
NSMutableData *webPortFolio;
NSMutableString *soapResultsPortFolio;
NSURLConnection *conn;
//---xml parsing---
NSXMLParser *xmlParserPortFolio;
BOOL elementFoundPortFolio;
NSMutableURLRequest *req;
NSString *theXMLPortFolio;
NSString *strSoapMsg;
UIAlertView *alertView;
In your .m file use the following code:
-(void)loadPortfolioData
{
strSoapMsg = [[NSString alloc] initWithFormat:
#"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
"<soap12:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap12=\"http://www.w3.org/2003/05/soap-envelope\">"
"<soap12:Body>"
"<GetPortfolioList xmlns=\"http://tempuri.org/\">"
"<EmailID>%#</EmailID>"
"<Password>%#</Password>"
"<TradingGameID>%d</TradingGameID>"
"</GetPortfolioList>"
"</soap12:Body>"
"</soap12:Envelope>",gameUserName,gamePassword,gameid];
//---print it to the Debugger Console for verification---
NSLog(#"soapMsg..........%#",strSoapMsg);
NSURL *url = [NSURL URLWithString:#"http://www.abc.sirus/Process/process.asmx"];
req = [NSMutableURLRequest requestWithURL:url];
//---set the headers---
NSString *msgLength = [NSString stringWithFormat:#"%d",[strSoapMsg length]];
[req addValue:#"application/soap+xml; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[req addValue:#"http://tempuri.org/GetPortfolioList" forHTTPHeaderField:#"SOAPAction"];
[req addValue:msgLength forHTTPHeaderField:#"Content-Length"];
//---set the HTTP method and body---
[req setHTTPMethod:#"POST"];
[req setHTTPBody: [strSoapMsg dataUsingEncoding:NSUTF8StringEncoding]];
// [activityIndicator startAnimating];
conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];
if (conn)
{
webPortFolio = [[NSMutableData data] retain];
}
}
And to handle the response you can use following functions :
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[webPortFolio setLength:0];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[webPortFolio appendData:data];
}
-(void) connection:(NSURLConnection *) connection didFailWithError:(NSError *) error
{
NSLog(#"error...................%#",[error description]);
[webPortFolio release];
[connection release];
}
-(void) connectionDidFinishLoading:(NSURLConnection *) connection
{
//Check the request and returns the response.
NSLog(#"DONE. Received Bytes: %d", [webPortFolio length]);
theXMLPortFolio = [[NSString alloc]
initWithBytes: [webPortFolio mutableBytes]
length:[webPortFolio length]
encoding:NSUTF8StringEncoding];
//---shows the XML---
NSLog(#"shows the XML %#",theXMLPortFolio);
[theXMLPortFolio release];
if(xmlParserPortFolio)
{
[xmlParserPortFolio release];
}
xmlParserPortFolio = [[NSXMLParser alloc] initWithData: webPortFolio];
[xmlParserPortFolio setDelegate: self];
[xmlParserPortFolio setShouldResolveExternalEntities:YES];
[xmlParserPortFolio parse];
[webPortFolio release];
[connection release];
}
//---when the start of an element is found---
-(void) parser:(NSXMLParser *) parser
didStartElement:(NSString *) elementName
namespaceURI:(NSString *) namespaceURI
qualifiedName:(NSString *) qName
attributes:(NSDictionary *) attributeDict
{
if( [elementName isEqualToString:#"GetPortfolioListResult"])
{
if (!soapResultsPortFolio)
{
soapResultsPortFolio = [[NSMutableString alloc] init];
}
elementFoundPortFolio = TRUE;
NSLog(#"Registration...%#",soapResultsPortFolio);
}
else if([elementName isEqualToString:#"your_tag_name"])
{
elementFoundPortFolio = TRUE;
}
else if([elementName isEqualToString:#"your_tag_name"])
{
elementFoundPortFolio = TRUE;
}
else if([elementName isEqualToString:#"your_tag_name"])
{
elementFoundPortFolio = TRUE;
}
}
-(void)parser:(NSXMLParser *) parser foundCharacters:(NSString *)string
{
if (elementFoundPortFolio)
{
[soapResultsPortFolio appendString: string];
}
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
NSLog(#"Parser error %# ",[parseError description]);
}
//---when the end of element is found---
-(void)parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:#"GetPortfolioListResult"])
{
NSLog(#"display the soap results%#",soapResultsPortFolio);
}
else if([elementName isEqualToString:#"your_tag_name"])
{
//Perform required action
}
else if([elementName isEqualToString:#"your_tag_name"])
{
//Perform required action
}
else if([elementName isEqualToString:#"your_tag_name"])
{
//Perform required action
}
[soapResultsPortFolio setString:#""];
elementFoundPortFolio = FALSE;
}
If the number of soap calls in your project increases, I can recommend using the tool wsdl2objc. It will generate an Objective C service plus model definition. The tools is not updated recently and it does not use Arc, but it's still ok. http://code.google.com/p/wsdl2objc/wiki/UsageInstructions

Resources