This is my first iOS app so detailed instructions on how to fix would be greatly appreciated. I'm trying to implement a pull to refresh so that my XML table will refresh the data. Currently, the pull to refresh animation works, but the data does not refresh.
The support that i've received so far has not been detailed enough to help. It seems that I'm close to getting the refresh to work but I am officially stumped. An NSLog returns ...2014-02-08 11:24:58.483 MyApp [3186:70b] refreshing. Can someone paste a fix into my code? Thank you!
#import "MasterViewController.h"
#import "DetailViewController.h"
#interface MasterViewController () {
NSXMLParser *parser;
NSMutableArray *feeds;
NSMutableDictionary *item;
NSMutableString *title;
NSMutableString *link;
NSString *element;
}
#end
#implementation MasterViewController
- (void)awakeFromNib {
[super awakeFromNib];
}
// Paste Blog feed here
- (void)viewDidLoad {
[super viewDidLoad];
feeds = [[NSMutableArray alloc] init];
NSURL *url = [NSURL URLWithString:#"http://www.placeholder.xml"];
parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
[parser setDelegate:self];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
UIRefreshControl *refreshControl = [UIRefreshControl new];
[refreshControl addTarget:self
action:#selector(refresh:)
forControlEvents:UIControlEventValueChanged];
refreshControl.attributedTitle =
[[NSAttributedString alloc] initWithString:#"Pull to refresh..."];
self.refreshControl = refreshControl;
}
- (void)refresh:(UIRefreshControl *)sender {
// ... your refresh code
NSLog(#"refreshing...");
NSURL *url = [NSURL URLWithString:#"http://www.placeholder.xml"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
(void)[[NSURLConnection alloc] initWithRequest:request delegate:self];
[sender endRefreshing];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#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:#"title"];
return cell;
}
- (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];
}
}
- (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"];
[feeds addObject:[item copy]];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if ([element isEqualToString:#"title"]) {
[title appendString:string];
} else if ([element isEqualToString:#"link"]) {
[link appendString:string];
}
}
- (void)parserDidEndDocument:(NSXMLParser *)parser {
[self.tableView reloadData];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSString *string = [feeds[indexPath.row] objectForKey:#"link"];
[[segue destinationViewController] setUrl:string];
}
}
#end
This code gets triggered as soon as the user pulls-to-refresh on your tableview:
- (void)refresh:(UIRefreshControl *)sender {
// ... your refresh code
NSURL *url = [NSURL URLWithString:#"http://www.placeholder.xml"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
(void)[[NSURLConnection alloc] initWithRequest:request delegate:self];
[sender endRefreshing];
}
What you're doing here is telling the refresh control to end refreshing immediately after the user has started the refresh.
You shouldn't be invoking -endRefreshing until your URLConnection/parsing/refresh operation has finished.
You can replace your refresh: method with this. It's based on the new NSURLSession method and you should replace the comments in the body of the completion handler with your call to process your xml data and to update your table.
- (void)refresh:(UIRefreshControl *)sender
{
// ... your refresh code
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:#"http://www.placeholder.xml"]
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
// handle response
NSXMLParser *updatedParser = [[NSXMLParser alloc] initWithData:data];
[updatedParser parse];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
}] resume];
[sender endRefreshing];
}
Related
i have 2 screens ,in 1 st when i click a button it should go to 2 nd screen get data from server and display in table view in 2 nd screen.but with following code i am unable to display data in table view
#import "FirstTableViewController.h"
#interface FirstTableViewController ()<NSXMLParserDelegate>
#property(nonatomic,strong)NSXMLParser*xmlparse;
#property(nonatomic,strong)NSMutableString*tempstr;
#property(nonatomic,strong)NSMutableArray*arr;
#end
#implementation FirstTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableURLRequest*req=[[NSMutableURLRequest alloc]init];
NSURL*url=[NSURL URLWithString:#"http://www.thomas-bayer.com/sqlrest/CUSTOMER/"];
[req setURL:url];
[[[NSURLSession sharedSession]dataTaskWithRequest:req completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
// SMXMLDocument *document = [SMXMLDocument documentWithData:data error:&error];
NSString*str=[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
_xmlparse=[[NSXMLParser alloc]initWithData:data];
_xmlparse.delegate=self;
[_xmlparse parse];
}] resume];
[_table reloadData];
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
_tempstr=[[NSMutableString alloc]initWithString:string];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName attributes:(NSDictionary<NSString *, NSString *> *)attributeDict;{
if([elementName isEqualToString:#"CUSTOMER"]){
self.tempstr=[[NSMutableString alloc]init];
}
if([elementName isEqualToString:#"CUSTOMERList"]){
self.arr=[[NSMutableArray alloc]init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName;{
if([elementName isEqualToString:#"CUSTOMER"]){
[_arr addObject:self.tempstr];
self.tempstr=nil;
}
// NSLog(#"arr is %#",self.arr);
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.arr.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cel" forIndexPath:indexPath];
cell.textLabel.text=[self.arr objectAtIndex:indexPath.row];
return cell;
}
#end
do two things
First
- (void)viewDidLoad {
[super viewDidLoad];
arr = [NSMutableArray array]; // initilize the memory of array
NSMutableURLRequest*req=[[NSMutableURLRequest alloc]init];
NSURL*url=[NSURL URLWithString:#"http://www.thomas-bayer.com/sqlrest/CUSTOMER/"];
[req setURL:url];
[[[NSURLSession sharedSession]dataTaskWithRequest:req completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
// SMXMLDocument *document = [SMXMLDocument documentWithData:data error:&error];
NSString*str=[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
_xmlparse=[[NSXMLParser alloc]initWithData:data];
_xmlparse.delegate=self;
[_xmlparse parse];
}] resume];
}
Second
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName;{
if([elementName isEqualToString:#"CUSTOMER"]){
[_arr addObject:self.tempstr];
self.tempstr=#"";
}
if(arr.count >0)
{
dispatch_async(dispatch_get_main_queue(), ^{
[_table reloadData];
});
}
}
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];
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 use SOAP webservices in my app. I make an request with the following statements (.m file):
- (void)viewDidLoad
{
[super viewDidLoad];
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><retLoca xmlns=\"http://www.ctrlbase.nl/cbawebapp>\"><tcUser>112</tcUser></retLoca></soap:Body></soap:Envelope>"];
NSURL *url = [NSURL URLWithString:
#"http://www.ctrlbase.nl/cbawebapp/getLoca.asmx>"];
NSMutableURLRequest *req =
[NSMutableURLRequest requestWithURL:url];
NSString *msgLength =
[NSString stringWithFormat:#"%d", [soapMsg length]];
[req addValue:#"text/xml; charset=utf-8"
forHTTPHeaderField:#"Content-Type"];
[req addValue:#"http://www.ctrlbase.nl/cbawebapp/retLoca>"
forHTTPHeaderField:#"SOAPAction"];
[req addValue:msgLength
forHTTPHeaderField:#"Content-Length"];
[req setHTTPMethod:#"POST"];
[req setHTTPBody: [soapMsg dataUsingEncoding:NSUTF8StringEncoding]];
HUD = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
HUD.dimBackground = YES;
HUD.labelText = #"Ophalen van gegevens";
HUD.delegate = self;
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:req delegate:self];
if( theConnection )
{
webData = [NSMutableData data];
}
else
{
NSLog(#"theConnection is NULL");
}
}
-(void) connection:(NSURLConnection *) connection
didReceiveResponse:(NSURLResponse *) response {
[webData setLength: 0];
}
-(void) connection:(NSURLConnection *) connection
didReceiveData:(NSData *) data {
[webData appendData:data];
}
-(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( xmlParser )
{
}
xmlParser = [[NSXMLParser alloc] initWithData:webData];
[xmlParser setDelegate:self];
[xmlParser setShouldResolveExternalEntities:YES];
[xmlParser parse];
[HUD hide:YES];
}
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ( [elementName isEqualToString:#"retLocaResponse"] ) {
NSLog(#"Log Output%#",[attributeDict objectForKey:#"retLocaResult"]);
NSString *strValue= [attributeDict objectForKey:#"retLocaResult"];
if(strValue != (NSString*)[NSNull null])
{
[chunks addObject:[attributeDict objectForKey:#"retLocaResult"]];
}
else
{
}
recordResults = YES;
}
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:
(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if ( [elementName isEqualToString:#"retLocaResponse"] ) {
NSLog(#"Log array%#",chunks);
[[self tableView]reloadData];
recordResults = NO;
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [chunks count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"UITableViewCell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"UITableViewCell"];
}
cell.textLabel.text =[chunks objectAtIndex:indexPath.row];
return cell;
}
But I don't get the Location names into an UITableView. What do I wrong or what can I do to let this work. Please help me so I can finish my application.
Thanks a lot!
EDIT for Samkit Jain: Crashes with the 'init' for the array.
LOG:
2013-08-09 00:12:31.631 Ctrlbase[776:c07] request finished
2013-08-09 00:12:31.904 Ctrlbase[776:c07] DONE. Received Bytes: 381
2013-08-09 00:12:31.904 Ctrlbase[776:c07] 0640. Home5 Cash & Carry
2013-08-09 00:12:32.028 Ctrlbase[776:c07] Log Output(null)
2013-08-09 00:12:32.159 Ctrlbase[776:c07] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
-
Server request:
<?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>
<retLoca xmlns="http://www.ctrlbase.nl/cbawebapp">
<tcUser>string</tcUser>
</retLoca>
</soap:Body>
</soap:Envelope>
Server response:
<?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>
<retLocaResponse xmlns="http://www.ctrlbase.nl/cbawebapp">
<retLocaResult>string</retLocaResult>
</retLocaResponse>
</soap:Body>
</soap:Envelope>
Initialize chunks in viewDidLoad
- (void)viewDidLoad
{
chunks = [[NSMutableArray alloc] init];
//same code here
}
If this does not work.
Give me the complete log of your data coming from server and data from xml also.
Edit for Rick de Jong:
There is some problem in your getting data from server.
If you are not getting data from server, data can't be saved in array.
So, get your data properly from server.
When data will come properly from server :
-(void) connectionDidFinishLoading:(NSURLConnection *) connection {
NSLog(#"DONE. Received Bytes: %d", [webData length]);
NSString *theXML = [[NSString alloc]
initWithBytes: [webData mutableBytes]
length:[webData length]
encoding:NSUTF8StringEncoding];
NSLog(#"Xml is :-----------%#",theXML); // This line should print your xml coming from from server
}
Give me that output, I will surely give you solution after that.
One more thing, when you are parsing data. your required data is coming in tags not as attribute of xml, as per your Soap. So you should use :
if ( [elementName isEqualToString:#"retLocaResult"] ) {
// code to save data and add to array
}
in didStartElement and didEndElement to get proper result.
One more error in your code remove >
in following code :
NSURL *url = [NSURL URLWithString:
#"http://www.ctrlbase.nl/cbawebapp/getLoca.asmx"];
Finally I got the output :
Use this :
.h file
{
NSMutableData *webData;
NSXMLParser *xmlParser;
NSMutableArray *chunks;
BOOL recordResults;
NSMutableString *strCaptured;
}
.m file
- (void)viewDidLoad
{
[super viewDidLoad];
chunks = [[NSMutableArray alloc] init];
NSString *temp = #"112";
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><retLoca xmlns=\"http://www.ctrlbase.nl/cbawebapp\"><tcUser>%#</tcUser></retLoca></soap:Body></soap:Envelope>",temp];
// 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><retLoca xmlns=\"http://www.ctrlbase.nl/cbawebapp\"><tcUser>112</tcUser></retLoca></soap:Body></soap:Envelope>"];
NSURL *url = [NSURL URLWithString: #"http://www.ctrlbase.nl/cbawebapp/getLoca.asmx"];
NSMutableURLRequest *theRequest = [[NSMutableURLRequest alloc] initWithURL:url];
NSString *msgLength = [[NSString alloc ]initWithFormat:#"%d",[soapMsg length]];
[theRequest addValue:#"text/xml" forHTTPHeaderField:#"Content-Type"];
[theRequest addValue:msgLength forHTTPHeaderField:#"Content-Length"];
[theRequest setHTTPMethod:#"POST"];
[theRequest setHTTPBody:[soapMsg dataUsingEncoding:NSUTF8StringEncoding]];
//[theRequest addValue:#"http://www.ctrlbase.nl/cbawebapp/retLoca>" forHTTPHeaderField:#"SOAPAction"];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if( theConnection )
{
webData = [[NSMutableData alloc] init];
}
else
{
NSLog(#"theConnection is NULL");
}
}
-(void) connection:(NSURLConnection *) connection
didReceiveResponse:(NSURLResponse *) response {
[webData setLength: 0];
}
-(void) connection:(NSURLConnection *) connection
didReceiveData:(NSData *) data {
[webData appendData:data];
}
-(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(#"Xml is :-----------%#",theXML);
if( xmlParser )
{
}
xmlParser = [[NSXMLParser alloc] initWithData:webData];
xmlParser.delegate = self;
[xmlParser setShouldResolveExternalEntities:YES];
[xmlParser parse];
}
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
strCaptured = [[NSMutableString alloc]init];
}
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
[self.tableView reloadData];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
recordResults = false;
[strCaptured setString:#""];
if ([elementName isEqualToString:#"retLocaResult"]) {
recordResults = true;
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
recordResults = false;
if ([elementName isEqualToString:#"retLocaResult"]){
[chunks addObject:strCaptured];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if (recordResults
) {
[strCaptured appendString:string];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [chunks count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"UITableViewCell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"UITableViewCell"];
}
cell.textLabel.text =[chunks objectAtIndex:indexPath.row];
return cell;
}