how to parse an xml file from view did load method - iphone

In my application I have a login page were the user can log in.
Once the user has logged-in to his account, he should go to his dashboard page(home page).
On the dashboard page there are three buttons add, edit and logout but in a dashboard page I call the URL to read the XML file from viewDidLoad method before pressing any button.
I want to parse the XML file and save its value on the same page.
I have tried to parse the XML file on save page and I am using the value of the XML file on same page but I am not able to use that string value in another function on same page.
but I am not able to use the string user_login_xml in the above method which is on the same page.. instead I get an error exc_bad_access
- (void)viewDidLoad
{
NSString *EditProfileID=Dataid;
NSString* result = [EditProfileID stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSString *urlAsString =[NSString stringWithFormat:#"http://www.mybusinesscentral.co.uk/mobile/iphone_profile_id.php?id="];
urlAsString=[urlAsString stringByAppendingString:result];
NSURLRequest *req = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:urlAsString]];
urlCon = [[NSURLConnection alloc] initWithRequest:req delegate:self];
if (urlCon)
{
NSMutableData *mutableData = [[NSMutableData alloc] init];
self.receivedData=mutableData;
[mutableData release];
}
else //connection failed.
{
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:NSLocalizedString(#"Error", #"Error")
message:NSLocalizedString(#"Error connecting to remote server", #"Error connecting to remote server")delegate:self cancelButtonTitle:NSLocalizedString(#"Ok", #"Ok") otherButtonTitles:nil];
[alert show];
[alert release];
}
[req release];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[receivedData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data1
{
[receivedData appendData:data1];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
[connection release];
self.receivedData = nil;
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Error"
message:[NSString stringWithFormat:#"Connection failed! Error - %# (URL: %#)", [error localizedDescription],[[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]]
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alert show];
[alert release];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString *receivedDataAsString = [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding];
[receivedDataAsString release];
xmlParser = [[NSXMLParser alloc] initWithData:receivedData];
[xmlParser setDelegate:self];
[xmlParser parse];
[connection release];
self.receivedData = nil;
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementName isEqualToString:#"details"])
{
NSString *user_login = [attributeDict objectForKey:#"user_login"];
user_login_xml = [NSString stringWithFormat:#"%#",user_login];
}
}
-(IBAction)Btn_AddNew:(id)sender
{
if ([user_login_xml length]==0)
{
AddNew *addnew = [[AddNew alloc]initWithNibName:#"AddNew" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:addnew animated:YES];
}
else
{
SubmitYourListing_Active *SubmitListing=[[SubmitYourListing_Active alloc] initWithNibName:#"SubmitYourListing_Active" bundle:[NSBundle mainBundle]];
SubmitListing.UserID=Dataid;
[self.navigationController pushViewController:SubmitListing animated:YES];
}
}

I am using TouchXMl, you can download from
https://github.com/TouchCode/TouchXML
and installation guide Click here
This is the easiest way to parse xml file, only few lines of code required.

I am not sure it's useful to you, but it's very useful to me check out the TouchXML

Related

How to parse XML file from a server?

I've already searched a lot but none of the tutorials and sample codes helped. I am trying to parse a very simple XML data, which will be always the same with just one result, the xml is code bellow:
<Books>
<Book id="1">
<title>USERS ALREADY EXISTS</title>
</Book>
</Books>
So, how can I parse such a file using NSXMLParser or another way you know?
Well I parse xml some different way than others and being frank I really do not know which technique it is but I assure you it works fine for me and I have implemeted it successfully in so many projects. Have a look at my code where I load tweets from some profile
This is the function where I make call for parser.
-(void)loadtweet
{
#try
{
NSString *urlString = [NSString stringWithFormat:#"https://api.twitter.com/1/statuses/user_timeline.xml?screen_name=SrBachchan&count=5"];
NSLog(#"fetching data from--------> : %#",urlString);
NSString* escapedUrlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSMutableURLRequest *request1 = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:escapedUrlString]];
NSURLConnection *con=[[NSURLConnection alloc] initWithRequest:request1 delegate:self];
if(con)
truckData=[[NSMutableData data]retain];
}
#catch (NSException *exception)
{
UIAlertView *v = [[UIAlertView alloc] initWithTitle:#"ERROR" message:#"Please Try Again Later." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[v show];
[v release];
}
}
And these are the NSURLConnection delegate methods:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[truckData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[truckData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[tweets removeAllObjects];
#try
{
// [app.trucks removeAllObjects];
NSString *thexml=[[NSString alloc] initWithBytes:[truckData mutableBytes] length:[truckData length] encoding:NSUTF8StringEncoding];
NSArray *array=[thexml componentsSeparatedByString:#"<status>"];
NSLog(#"%d",[array count]);
for(int i=1;i<[array count];i++)
{
NSString *str=[array objectAtIndex:i];
NSArray *arr1=[str componentsSeparatedByString:#"<text>"];
NSString *data=[arr1 objectAtIndex:1];
NSRange ranfrom=[data rangeOfString:#"</text>"];
// nt.truckName=[data substringToIndex:ranfrom.location];
[tweets addObject:[data substringToIndex:ranfrom.location]];
}
}
#catch (NSException *exception)
{
UIAlertView *v = [[UIAlertView alloc] initWithTitle:#"ERROR" message:#"Please Try Again Later." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[v show];
[v release];
}
}
I have used some string functions to separate tags and stored the values in Array.

How to fetch the data from Google news by XML Parsing

I want to fetch Google news data by XML parsing and save it into an array. The XML is like this
http://news.google.co.in/news?pz=1&cf=all&ned=in&hl=en&output=rss
Well I parse xml some different way than others and being frank I really do not know which technique it is but I assure you it works fine for me and I have implemeted it successfully in so many projects. Have a look at my code where I load tweets from some profile
This is the function where I make call for parser.
-(void)loadtweet
{
#try
{
NSString *urlString = [NSString stringWithFormat:#"https://api.twitter.com/1/statuses/user_timeline.xml?screen_name=SrBachchan&count=5"];
NSLog(#"fetching data from--------> : %#",urlString);
NSString* escapedUrlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSMutableURLRequest *request1 = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:escapedUrlString]];
NSURLConnection *con=[[NSURLConnection alloc] initWithRequest:request1 delegate:self];
if(con)
truckData=[[NSMutableData data]retain];
}
#catch (NSException *exception)
{
UIAlertView *v = [[UIAlertView alloc] initWithTitle:#"ERROR" message:#"Please Try Again Later." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[v show];
[v release];
}
}
And these are the NSURLConnection delegate methods:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[truckData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[truckData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[tweets removeAllObjects];
#try
{
// [app.trucks removeAllObjects];
NSString *thexml=[[NSString alloc] initWithBytes:[truckData mutableBytes] length:[truckData length] encoding:NSUTF8StringEncoding];
NSArray *array=[thexml componentsSeparatedByString:#"<status>"];
NSLog(#"%d",[array count]);
for(int i=1;i<[array count];i++)
{
NSString *str=[array objectAtIndex:i];
NSArray *arr1=[str componentsSeparatedByString:#"<text>"];
NSString *data=[arr1 objectAtIndex:1];
NSRange ranfrom=[data rangeOfString:#"</text>"];
// nt.truckName=[data substringToIndex:ranfrom.location];
[tweets addObject:[data substringToIndex:ranfrom.location]];
}
}
#catch (NSException *exception)
{
UIAlertView *v = [[UIAlertView alloc] initWithTitle:#"ERROR" message:#"Please Try Again Later." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[v show];
[v release];
}
}
I have used some string functions to separate tags and stored the values in Array.
This is where you can start: NSXMLParser class reference.

Asynchronous connection not getting called

I want to create two connections in a single view controller class. I am using NSOperationQueue for this purpose. The two connections are created in two functions and push inside the queue .The problem is delegates are not called. Please help me out. Thanks you in advance
- (void)viewDidLoad {
[super viewDidLoad];
NSOperationQueue *queue=[[NSOperationQueue alloc] init];
NSInvocationOperation *invOperation1 = [[NSInvocationOperation alloc] initWithTarget:self selector:#selector(createConnection1) object:nil];
NSInvocationOperation *invOperation2 = [[NSInvocationOperation alloc] initWithTarget:self selector:#selector(createConnection2) object:nil];
NSArray *ops=[[NSArray alloc] initWithObjects:invOperation1,invOperation2,nil];
[queue addOperations:ops waitUntilFinished:YES];
}
-(void) createConnection1{
//create connection
NSLog(#"Create Connection 1");
url1 =[[NSMutableString alloc] initWithFormat:#"http://www.google.com/ig/api?weather=New Delhi"];
NSURLRequest *theRequest1=[NSURLRequest requestWithURL:[NSURL URLWithString:url1]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
theConnection1=[[NSURLConnection alloc] initWithRequest:theRequest1 delegate:self];
if (theConnection1) {
connectionCreated1=YES;
receivedData1 = [[NSMutableData data] retain];
NSLog(#"received data 1 %#",receivedData1);
//[theConnection1 setDelegate:self];
}
}
-(void) createConnection2{
//create connection
NSLog(#"Create Connection 2");
url2 =[[NSMutableString alloc] initWithFormat:#"http://www.google.com/ig/api?weather=Chennai"];
NSURLRequest *theRequest2=[NSURLRequest requestWithURL:[NSURL URLWithString:url2]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
theConnection2=[[NSURLConnection alloc] initWithRequest:theRequest2 delegate:self];
if (theConnection2) {
connectionCreated2=YES;
receivedData2 = [[NSMutableData data] retain];
//[theConnection2 setDelegate:self];
NSLog(#"received data 2 %#",receivedData2);
}
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
if (connectionCreated1==YES) {
[receivedData1 setLength:0];
}
else if (connectionCreated2==YES) {
[receivedData2 setLength:0];
}
else {
NSLog(#"did not receive response");
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
if (connectionCreated1==YES) {
[theConnection1 release];
xmlParser1 = [[NSXMLParser alloc] initWithData:receivedData1];
[xmlParser1 setDelegate:self];
[xmlParser1 parse];
}
else if(connectionCreated2==YES){
[theConnection2 release];
xmlParser2 = [[NSXMLParser alloc] initWithData:receivedData2];
[xmlParser2 setDelegate:self];
[xmlParser2 parse];
}
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"connection failed" message:#"" delegate:self cancelButtonTitle:#"ok" otherButtonTitles:nil];
[alert show];
[alert release];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
if (connectionCreated1==YES) {
[receivedData1 appendData:data];
}
else if(connectionCreated2==YES) {
[receivedData2 appendData:data];
}
else {
NSLog(#"data not received");
}
}
The URL you have given in the first link seems to be borken ... look at this "http://www.google.com/ig/api?weather=New Delhi".. there is space between new delhi. try this instead http://www.google.com/ig/api?weather=New+Delhi

NSMutableArray populated but data lost somehow

I start process of getting data from viewDidLoad and populate NSMutableArray with that data. But when I want to populate UIPicker I cant because there is no more data in that array. How did I lost that??? Please help :(
#synthesize activityIndicator;
#synthesize pckCountries;
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
countriesList = [[NSMutableArray alloc] initWithCapacity:20];
[self getCountriesList];
NSLog(#"%#", [countriesList count]);
[super viewDidLoad];
}
- (void)dealloc {
[activityIndicator release];
[xmlParser release];
//[soapResults release];
[super dealloc];
}
- (void) getCountriesList{
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>"
"<getCountries xmlns=\"http://www.smsbug.com/api/\" />"
"</soap:Body>"
"</soap:Envelope>"
];
NSURL *url = [NSURL URLWithString:
#"http://www.smsbug.com/api/webservice.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.smsbug.com/api/getCountries"
forHTTPHeaderField:#"SOAPAction"];
[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] retain];
}
}
-(void) connection:(NSURLConnection *) connection
didReceiveResponse:(NSURLResponse *) response {
[webData setLength: 0];
}
-(void) connection:(NSURLConnection *) connection
didReceiveData:(NSData *) data {
[webData appendData:data];
NSLog(#"%#", webData);
}
-(void) connection:(NSURLConnection *) connection
didFailWithError:(NSError *) error {
[webData release];
[connection release];
}
-(void) connectionDidFinishLoading:(NSURLConnection *) connection {
NSLog(#"DONE READING WEATHER WEB SERVICE. Received Bytes: %d", [webData length]);
NSString *theXML = [[NSString alloc]
initWithBytes: [webData mutableBytes]
length:[webData length]
encoding:NSUTF8StringEncoding];
//---shows the XML to test---
NSLog(theXML);
[theXML release];
// stop activity indicator animation
[activityIndicator stopAnimating];
//-----------------------------------------------------------------
// start parsing received XML message
//-----------------------------------------------------------------
if (xmlParser)
{
[xmlParser release];
}
xmlParser = [[NSXMLParser alloc] initWithData: webData];
[xmlParser setDelegate:self];
[xmlParser setShouldResolveExternalEntities:YES];
[xmlParser parse];
// clear memory
[connection release];
[webData release];
}
-(void) parser:(NSXMLParser *) parser
didStartElement:(NSString *) elementName
namespaceURI:(NSString *) namespaceURI
qualifiedName:(NSString *) qName
attributes:(NSDictionary *) attributeDict {
//NSLog(elementName);
if ([elementName isEqualToString:#"Country_Name"])
{
countryFound = YES;
}
}
-(void)parser:(NSXMLParser *) parser foundCharacters:(NSString *)string
{
if([string isEqualToString:#"Data Not Found"])
{
errorOccured = YES;
}
else if(countryFound == YES)
{
//NSLog(string);
[countriesList addObject:string];
}
else
{
[soapResults appendString: string];
}
}
-(void)parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
{
if(errorOccured == YES)
{
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"No Data!"
message:#"Sorry"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
[soapResults setString:#""];
errorOccured = FALSE;
}
else
{
if ([elementName isEqualToString:#"Country_Name"])
{
countryFound = FALSE;
}
}
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
return countriesList.count;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
return [countriesList objectAtIndex:row];
}
[super viewDidLoad] should be the first invocation in a viewDidLoad method.
There's a leak - you should invoke [countriesList release] in a dealloc method.
NSURLRequest is asynchronous. As well as NSXMLParser. So all picker delegate methods will be called before downloading/parsing is finished. Thus, in all delegate methods you should check if countriesList is equal to nil.
When parsing is finished (implement parserDidEndDocument: method to receive this message) you should explicitly call [picker reloadAllComponents].

Adding a new row in a UITableView

HI Everyone,
It is my first post here and this is my problem:
I am trying to get some data from a REST API call and show then in a UITableView.
This s what I am doing:
in the viewDidLoad: 1) here I initialize my array of things to show in the Table (that is empty at the beginning) 2) the table is loaded (with 0 rows) and 3) then the HTTP async call is issued.
Done this I do my stuff with the HTTP Response and when ready I call the reloadData on my table. Here the strange happens.
numberOfRowsInSelection returns me the correct number of rows
but
tableView:cellForRowAtIndexPath:indexPath for the indexPath.row always returns me zero!
so no new row is added to the table.
- (void)doJSONRequest{
responseData = [[NSMutableData data] retain];
NSString *addr = [[NSString alloc] initWithFormat:#"http://localhost:8080/blabla/v1/items?count=10"];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:addr]];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[addr release];
}
- (void)doJSONRequestWithURL:(NSString *)url{
responseData = [[NSMutableData data] retain];
NSString *addr = [[NSString alloc] initWithFormat:url];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:addr]];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[addr release];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
//NSLog(#"[%#] connection:didReceiveResponse %#",[self class], response);
[responseData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
//NSLog(#"[%#] connection:didReceiveData %#",[self class], data);
[responseData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(#"[%#]",[NSString stringWithFormat:#"Connection failed: %#", [error description]]);
UIAlertView *alert = [[UIAlertView alloc] init];
[alert setTitle:#"NETWORK ERROR!"];
[alert setMessage:#"App will close"];
[alert setDelegate:self];
[alert addButtonWithTitle:#"Close"];
[alert show];
[alert release];
[alert show];
[alert release];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
//NSLog(#"[%#] connectionDidFinishLoading %#",[self class], connection);
[connection release];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
[responseData release];
NSDictionary *res = [NSDictionary dictionaryWithDictionary:[responseString JSONValue]];
NSDictionary *tmp = [res valueForKey:#"reviews"];
tmp = [tmp valueForKey:#"reviews"];
NSEnumerator *e = [tmp objectEnumerator];
NSDictionary *tmp_review;
int i=0;
while (tmp_review = [e nextObject]) {
//NSLog(#"tmp_review %#", tmp_review);
//NSLog(#"count %d", i++);
MyObject r = [... doing my staff...]
[reviews addObject: r];
[r release];
};
[reviewListTableView reloadData];
[responseString release];
}
- (void)viewDidLoad {
//- (void)initUI {
//review is the array where I put my data
//it is empty at the beginning
reviews = [[NSMutableArray alloc] initWithObjects:nil];
[super viewDidLoad];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [reviews count]
}
Sounds like you may not have properly implemented numberOfSectionsInTableView:. You should log indexPath.section in tableView:cellForRowAtIndexPath:indexPath to see what section value you are passing. You will have multiple indexPath.row values of zero because there is a zero row for each section.
add new object in the array and [mytableview reloadData];
Implement following data source return number of section to be present in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
In tableView:cellForRowAtIndexPath:indexPath check section number and do your operation.
Note: If you don't need sections you can remove it.