i am upgraded the code then the below code title has 22 objects,in 16 object empty and the like another object is nil.why it happen and i write code like elementame is eqale to item like then it works exactly.but when pass the data from one view controller to another it has issue.
please give solution and in they send the links of each item then the write code for images and discription by using model.
so please help me.
NSURL *url = [NSURL URLWithString:#"http://www.cinejosh.com/rss-feed/4/telugu.html"];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30];
NSURLConnection *urlConnection = [NSURLConnection connectionWithRequest:urlRequest delegate:self];
if(urlConnection){
self.responseData = [NSMutableData data];
}
else
{
NSLog(#"the connection failed");
}
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[self.responseData setLength:0];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[self.responseData appendData:data];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
self.cnnParser = [[NSXMLParser alloc]initWithData:self.responseData];
self.cnnParser.delegate = self;
[self.cnnParser parse];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
[self.homeActivityIndicator stopAnimating];
[self.activityView setHidden:YES];
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:#"Connection Failed" message:nil delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
alertView.delegate = self;
[alertView show];
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
[self.navigationController popToRootViewControllerAnimated:YES];
}
-(void)parserDidStartDocument:(NSXMLParser *)parser
{
titlesTag = NO;
datesTag = NO;
descriptionsTag = NO;
linksTag = NO;
itemsTag = NO;
}
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if([elementName isEqualToString:#"item"])
{
itemsTag = YES;
}
else if([elementName isEqualToString:#"title"])
{
titlesTag = YES;
}
else if([elementName isEqualToString:#"link"])
{
linksTag = YES;
}
else if([elementName isEqualToString:#"description"])
{
descriptionsTag = YES;
}
else if([elementName isEqualToString:#"pubDate"])
{
datesTag = YES;
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if(titlesTag == YES && itemsTag == YES)
{
[titlesArray addObject:string];
NSLog(#"title %lu",[titlesArray count]);
}
else if(linksTag == YES && itemsTag == YES)
{
[self.linksArray addObject:string];
}
else if(descriptionsTag == YES && itemsTag == YES)
{
[self.descriptionsArray addObject:string];
}
else if(datesTag == YES && itemsTag == YES)
{
[self.datesArray addObject:string];
NSLog(#"date %lu",(unsigned long)[datesArray count]);
}
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if([elementName isEqualToString:#"title"])
{
titlesTag = NO;
// itemsTag = NO;
}
else if([elementName isEqualToString:#"link"])
{
linksTag = NO;
}
else if([elementName isEqualToString:#"description"])
{
descriptionsTag = NO;
}
else if([elementName isEqualToString:#"pubDate"])
{
datesTag = NO;
// itemsTag = NO;
}
else if ([elementName isEqual:#"item"])
{
itemsTag=NO;
}
}
Related
I have a NSXML parser that is willing to retrieve data out and put it into NSMutable array. It works when i NSLog the array out. But when i display the array into the table view it fails. Is good if can tell me more specific on which error that i have because there is no error when running.
This is my ViewDidLoad
- (void)viewDidLoad {
[super viewDidLoad];
// output = [[NSMutableArray alloc]initWithObjects:#"red",#"green", nil];
NSLog(#"Response recieved");
output= [[NSMutableArray alloc] init];
feeds = [[NSMutableArray alloc] init];
// NSString *severity = #"Informational";
NSString *soapMessage = #"<?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>"
" <IncidentGetList xmlns=\"https://www.monitoredsecurity.com/\">"
"<Severity></Severity>"
"<SourceOrganization></SourceOrganization>"
"<DestinationOrganization></DestinationOrganization>"
"<MaxIncidents></MaxIncidents>"
"<SourceIP></SourceIP>"
"<Category></Category>"
"<ExcludeCategory></ExcludeCategory>"
"<StartTimeStampGMT></StartTimeStampGMT>"
"<EndTimeStampGMT></EndTimeStampGMT>"
"<CustomerSeverity></CustomerSeverity>"
"</IncidentGetList>"
"</soap:Body>"
"</soap:Envelope>";
NSURL *url = [NSURL URLWithString:#"https://api.monitoredsecurity.com/SWS/incidents.asmx"];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
NSString *msgLength = [NSString stringWithFormat:#"%d", [soapMessage length]];
[theRequest addValue: #"text/xml; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[theRequest addValue: #"https://www.monitoredsecurity.com/IncidentGetList" forHTTPHeaderField:#"SOAPAction"];
[theRequest addValue: msgLength forHTTPHeaderField:#"Content-Length"];
[theRequest setHTTPMethod:#"POST"];
[theRequest setHTTPBody: [soapMessage dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
[connection start];
if(connection)
{
webResponseData = [NSMutableData data] ;
}
else
{
NSLog(#"Connection is NULL");
}
}
This is my NSXMLparser
//Implement the NSXmlParserDelegate methods
-(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:
(NSString *)qName attributes:(NSDictionary *)attributeDict
{
element = elementName;
if ([element isEqualToString:#"SecurityIncidentSummary"]) {
IncidentGetList = [[NSMutableDictionary alloc] init];
Severity = [[NSMutableString alloc] init];
} //NSLog(#"current element: ", elementName);
}
- (void)parserDidStartDocument:(NSXMLParser *)parser{
NSLog(#"File found and parsing started");
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if ([element isEqualToString:#"Severity"]) {
[Severity appendString:string];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:#"SecurityIncidentSummary"]) {
[IncidentGetList setObject:Severity forKey:#"Severity"];
[feeds addObject:[IncidentGetList copy]];
}
[self.datalist reloadData];
}
- (void)parserDidEndDocument:(NSXMLParser *)parser {
NSLog(#"Final Feed : %#",feeds);
//[self.datalist reloadData];
}
This is my tableview
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)
return [feeds count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellId = #"UITableViewCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if(cell == nil){
cell= [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
}
cell.textLabel.text= [[feeds objectAtIndex:indexPath.row]objectForKey:#"Severity"];
//cell.textLabel.text= output[indexPath.row];
return cell;
}
Check out this XMLParser example which I have done.
In your .h file:
#interface RssViewController : UIViewController<NSXMLParserDelegate,UITableViewDataSource,UITableViewDelegate>
{
NSString *element;
NSXMLParser *xml;
NSMutableDictionary *item;
NSMutableString *title;
NSMutableString *link;
NSMutableString *description;
NSMutableArray *arrmute;
}
#property (weak, nonatomic) IBOutlet UITableView *tview;
In .m file:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
arrmute=[[NSMutableArray alloc]init];
NSURL *url=[[NSURL alloc]initWithString:#"http://news.google.co.in/news?cf=all&hl=en&pz=1&ned=in&topic=tc&output=rss"];
xml=[[NSXMLParser alloc]initWithContentsOfURL:url];
xml.delegate=self;
xml.shouldResolveExternalEntities=YES;
[xml parse];
}
NSXMLParser delegates methods :-
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
element = elementName;
if ([element isEqualToString:#"item"])
{
item=[[NSMutableDictionary alloc] init];
title=[[NSMutableString alloc] init];
link=[[NSMutableString alloc] init];
description=[[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if ([element isEqualToString:#"title"])
{
[title appendString:string];
}
else if ([element isEqualToString:#"link"])
{
[link appendString:string];
}
else if ([element isEqualToString:#"description"])
{
[description appendString:string];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:#"item"]) {
[item setObject:title forKey:#"title"];
[item setObject:link forKey:#"link"];
[item setObject:description forKey:#"description"];
[arrmute addObject:[item copy]];
}
}
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
[self.tview reloadData];
}
TableView Methods:-
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return arrmute.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.textLabel.text=[[arrmute objectAtIndex:indexPath.row] objectForKey:#"title"];
cell.textLabel.numberOfLines = 0;
cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
return cell;
}
Hope this will help you...
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"Response recieved");
output= [[NSMutableArray alloc] init];
// NSString *severity = #"Informational";
NSString *soapMessage = #"<?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>"
" <IncidentGetList xmlns=\"https://www.monitoredsecurity.com/\">"
"<Severity></Severity>"
"<SourceOrganization></SourceOrganization>"
"<DestinationOrganization></DestinationOrganization>"
"<MaxIncidents></MaxIncidents>"
"<SourceIP></SourceIP>"
"<Category></Category>"
"<ExcludeCategory></ExcludeCategory>"
"<StartTimeStampGMT></StartTimeStampGMT>"
"<EndTimeStampGMT></EndTimeStampGMT>"
"<CustomerSeverity></CustomerSeverity>"
"</IncidentGetList>"
"</soap:Body>"
"</soap:Envelope>";
NSURL *url = [NSURL URLWithString:#"https://api.monitoredsecurity.com/SWS/incidents.asmx"];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
NSString *msgLength = [NSString stringWithFormat:#"%d", [soapMessage length]];
[theRequest addValue: #"text/xml; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[theRequest addValue: #"https://www.monitoredsecurity.com/IncidentGetList" forHTTPHeaderField:#"SOAPAction"];
[theRequest addValue: msgLength forHTTPHeaderField:#"Content-Length"];
[theRequest setHTTPMethod:#"POST"];
[theRequest setHTTPBody: [soapMessage dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
[connection start];
if(connection)
{
webResponseData = [NSMutableData data] ;
}
else
{
NSLog(#"Connection is NULL");
}
// Menu View
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
// Insert Navigation Bar
// [self insertNavBarWithScreenName:SCREEN_INCIDENT];
//
// CGRect frm = btnDownArrow.frame;
// frm.origin.x = 185;
// frm.origin.y = 42;
// [btnDownArrow setFrame:frm];
// [self.navBarView addSubview:btnDownArrow];
//
//
//
// [self addGestureRecognizersToPiece:self.view];
}
- (void)connection:(NSURLConnection *) connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(#"Response recieved");
[self.webResponseData setLength:0];
}
- (void)connection:(NSURLConnection*) connection didReceiveData:(NSData *)data
{
NSLog(#"Data recieved");
// NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
[self.webResponseData appendData:data];
// NSLog(responseString);
// [response setText:responseString];
//[status setText:#"Response retrieved async"];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSLog(#"Received %lu Bytes", (unsigned long)[webResponseData length]);
NSString *theXML = [[NSString alloc] initWithBytes:
[webResponseData mutableBytes] length:[webResponseData length] encoding:NSUTF8StringEncoding];
NSLog(#"%#",theXML);
//now parsing the xml
NSData *myData = [theXML dataUsingEncoding:NSUTF8StringEncoding];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:myData];
//setting delegate of XML parser to self
xmlParser.delegate = self;
[xmlParser parse];
// Run the parser
#try{
BOOL parsingResult = [xmlParser parse];
NSLog(#"parsing result = %hhd",parsingResult);
}
#catch (NSException* exception)
{
UIAlertView* alert = [[UIAlertView alloc]initWithTitle:#"Server Error" message:[exception reason] delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
return;
}
}
//Implement the NSXmlParserDelegate methods
-(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:
(NSString *)qName attributes:(NSDictionary *)attributeDict
{
//currentElement = elementName;
currentElement = [elementName copy];
strCaptured = [[NSMutableString alloc] init];
if ([currentElement isEqualToString:#"Severity"]) {
item = [[NSMutableDictionary alloc] init];
NSLog(#"Log Output%#",[item objectForKey:#"Severity"]);
}
currentElement = elementName;
//NSLog(#"current element: ", elementName);
}
- (void)parserDidStartDocument:(NSXMLParser *)parser{
NSLog(#"File found and parsing started");
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
[strCaptured appendString:string];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([currentElement isEqualToString:#"Severity "]) {
[output addObject:[item copy]];
} else {
[item setObject:strCaptured forKey:elementName];
}
}
- (void)parserDidEndDocument:(NSXMLParser *)parser {
if (errorParsing == NO)
{
NSLog(#"XML processing done!");
} else {
NSLog(#"Error occurred during XML processing");
}
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)
return [output count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellId = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"UITableViewCell"];
if(cell == nil){
cell= [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellId];
}
cell.textLabel.text= [output objectAtIndex:indexPath.row];
return cell;
}
Make an file in NSObject then use Methods in Parsing
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
}
- (void) parser: (NSXMLParser *) parser parseErrorOccurred: (NSError *) parseError {
}
- (void) parser: (NSXMLParser *) parser didStartElement: (NSString *) elementName
namespaceURI: (NSString *) namespaceURI qualifiedName: (NSString *) qName
attributes: (NSDictionary *) attributeDict{
}
- (void) parser: (NSXMLParser *) parser didEndElement: (NSString *) elementName namespaceURI: (NSString *) namespaceURI
qualifiedName: (NSString *) qName{
if ([elementName isEqualToString:#"webResponseData"])
{
[communication addObject:[currentElement stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
}
currentElement = nil;
}
- (void) parser: (NSXMLParser *) parser foundCharacters: (NSString *) string {
if(!currentElement)
currentElement = [[NSMutableString alloc] initWithString:string];
else
[currentElement appendString:string];
}
Then in connectiondidfinishloading in viewcontroller import parser file and make object of file
example :-
NSString *responseStringCommunication=[[NSString alloc]initWithData:MutableData encoding:NSUTF8StringEncoding];
Parser *parser=[[Parser alloc]init];
NSMutableArray *array=[parser parse:responseStringCommunication];
I am facing a problem in parsing data from a web service response.
I call a web service and get the response as NSLog, but I need to capture the data as NSString.
Here is my sample code:
-(void)connection:(NSURLConnection *) connection didReceiveResponse: (NSURLResponse *) response {
}
-(void)connection:(NSURLConnection *) connection didReceiveData:(NSData *) data {
NSString *strData;
strData = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:data];
[xmlParser setDelegate:self];
[xmlParser parse];
soapResultsString=[[NSMutableString alloc]init];
recordResults =YES;
}
NSString *xmlparserString;
NSMutableString *soapResultsString;
bool recordResults;
-(void)parserDidEndDocument:(NSXMLParser *)parser
{
}
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *) namespaceURI qualifiedName:(NSString *)qName attributes: (NSDictionary *)attributeDict
{
xmlparserString=elementName;
if( [xmlparserString isEqualToString:#"ns:return"])
{
recordResults =YES;
soapResultsString = [[NSMutableString alloc] init];
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if( recordResults )
{
[soapResultsString appendString: string];
NSLog(#"inside%#",string);
}
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if( [elementName isEqualToString:#"ns:return"])
{
NSLog(#"parser==>%#",parser);
NSLog(#"nameSpaceUrL==>%#",namespaceURI);
NSLog(#"qName==>%#",qName);
NSData *data = [soapResultsString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
// NSLog(#"json==>%#",json);
NSArray *planArray = [json objectForKey:#"hello_History"];
NSLog(#"planArrayCount==>%lu",(unsigned long)[planArray count]);
NSMutableArray *dataSource = [NSMutableArray arrayWithCapacity:planArray.count];
for (int i = 0 ; i<[planArray count]; i++)
{
recordResults = NO;
txn_id=[[[json valueForKey:#"hello_History"]valueForKey:#"date"]objectAtIndex:i];
loginId = [[[json valueForKey:#"hello_History"]valueForKey:#"time"]objectAtIndex:i];
}
}
}
the problem is i getting outputupto this method
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
but my parsing method not at called
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
is there any alternate way to capture the string
Iam new to ios development, i need to parse xml data into an array, i tried a tutorial, and i am not getting data, when edited with "hrms.atrity.info/api/people"
XML url ,Parser delegates not working while executing with the above link.Here is my coding, it works with "image.apple.com/main/rss/hotnews/hotnews.rss".How to rectify this probe,
- (void)viewDidLoad
{
[super viewDidLoad];
feeds = [[NSMutableArray alloc] init];
NSURL *url = [NSURL URLWithString:#"http://hrms.atrity.info/api/people"];//NOt Working
NSURL *url = [NSURL
URLWithString:#"http://image.apple.com/main/rss/hotnews/hotnews.rss"];//This Works
xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
[xmlParser setDelegate:self];
[xmlParser setShouldResolveExternalEntities:NO];
[xmlParser parse];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:
(NSInteger)section
{
return feeds.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"
forIndexPath:indexPath];
cell.textLabel.text = [[feeds objectAtIndex:indexPath.row] objectForKey: #"FirstName"];
return cell;
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:
(NSDictionary *)attributeDict
{
element = elementName;
if ([element isEqualToString:#"Users"])
{
item = [[NSMutableDictionary alloc] init];
title = [[NSMutableString alloc] init];
link = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:
(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:#"Users"])
{
[item setObject:title forKey:#"FirstName"];
[item setObject:link forKey:#"LastName"];
[feeds addObject:[item copy]];
NSLog(#"%#",feeds);
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if ([element isEqualToString:#"FirstName"])
{
[title appendString:string];
}
else if ([element isEqualToString:#"LastName"])
{
[link appendString:string];
}
}
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
[self.tableView reloadData];
}
Thanks in Advance.
Using the following code:
xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:[NSURL URLWithString:#"http://hrms.atrity.info/api/people"]];
is resulting in the parser:parseErrorOccurred: being called for the http://hrms.atrity.info/api/people URL. The NSError passed to that delegate shows an error code of 4 which translate to NSXMLParserEmptyDocumentError. This is because the URL is returning JSON instead of XML. You can check this using the following code:
NSError *error;
NSString *data = [[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:#"http://hrms.atrity.info/api/people"] encoding:NSUTF8StringEncoding error:&error];
NSLog(#"%#", data);
You can clearly see in the console in Xcode that the data is JSON. In order to retrieve the data in XML format, you need to specify the Accept header with a value of application/xml. You cannot do this with NSURL alone and will need to use NSMutableURLRequest so that you can set the custom header value, as follows:
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://hrms.atrity.info/api/people"]];
[request setValue:#"application/xml" forHTTPHeaderField:#"Accept"];
NSURLResponse *response;
NSError *error;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
xmlParser = [[NSXMLParser alloc] initWithData:data];
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.