How to fetch the data from Google news by XML Parsing - iphone

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.

Related

Connection Lost error while using NSURLConnection

I am facing connection lost issue while using NSURLConnection. I am using NSURLConnection for asynch download. I am downloading big file of size around 80MB. I am writing received data in file every time with proper file handling. After sometime I am getting error of connection "Connection Lost" in method of NSURLConnection delegate named didFailWithError. If I execute in simulator on Mac then it will take long time but file gets downloaded successfully without having Connection Lost error. Any suggestion how to avoid this error? or what is the reason behind this error?
Let me know if any detail is required. Please note that I have read similar kind of post but it didnt help me.
Find below code snippet and let me know if more information is required:
-(void) startDownloadFromURL:(NSString*)URLString
{
if(URLString == nil)
{
[delegate DownloadFailed:-1];
return;
}
//self.pstrBaseFilePath = filePath;
URLString = [URLString stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSMutableURLRequest* pRequest = [[NSMutableURLRequest alloc] init];
[pRequest setURL:[NSURL URLWithString:URLString]];
if(gpUserDataManager.pstrSessionID == nil)
return;
[pRequest addValue:[#"ASessionID=" stringByAppendingString:gpUserDataManager.pstrSessionID] forHTTPHeaderField:#"Cookie"];
[pRequest setHTTPMethod:#"GET"];
[pRequest setTimeoutInterval:180];
self.urlConnection = [[NSURLConnection alloc] initWithRequest:pRequest delegate:self];
[urlConnection start];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if([httpResponse statusCode] == 200)
{
}
else
{
//Start.NOODLE-13304
/* NSInteger iResponseCode = [httpResponse statusCode];
NSString* pstrStr = [NSString stringWithFormat:#"%d", iResponseCode];
//pTheConnection = nil;
[[[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Response Error", #"")
message:pstrStr
delegate:nil
cancelButtonTitle:NSLocalizedString(#"OK", #"")
otherButtonTitles:nil] show];
*/
[AUserDataManager ProcessResponseCode:httpResponse.statusCode];
[self.urlConnection cancel];
[delegate DownloadFailed:httpResponse.statusCode];
//End.NOODLE-13304
}
//[self.pRecvdata setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
if(self.recvdData == nil)
{
self.recvdData = [[NSMutableData alloc] init];
}
[self.recvdData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
// bIsResponseOK = FALSE;
//
// [NSThread detachNewThreadSelector: #selector(SpinEnd) toTarget:self withObject:nil];
//
// pTheConnection = nil;
[[[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Connection Error", #"")
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:NSLocalizedString(#"OK", #"")
otherButtonTitles:nil] show];
[self.urlConnection cancel];
[delegate DownloadFailed:-1];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[connection cancel];
[delegate DownloadCompleted:self.recvdData];
}
DownloadRequest *request = [[DownloadRequest alloc] init];
request.delegate = self;
[request startDownloadFromURL:strURL];

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 parse an xml file from view did load method

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

[NSMutableURLRequest released]: message sent to deallocated instance

My app is calling the rqst_run method below in didViewLoad method but I've an error. Debugger reports the following error:
[NSMutableURLRequest released]: message sent to deallocated instance
I don't know where this variable get released
Declared in header file (interface section):
NSMutableString *rqst_error;
NSMutableData *rqst_data;
NSMutableDictionary *listing_items;
and I defined this method in implementation:
- (void)rqst_run
{
rqst_data = [[NSMutableData data] retain];
NSMutableURLRequest *http_request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://www.feedserver.com/request/"]];
[http_request setHTTPMethod:#"POST"];
NSString *post_data = [[NSString alloc] initwithFormat:#"param1=%#&param2=%#&param3=%#",rqst_param1,rqst_param2,rqst_param3];
[http_request setHTTPBody:[post_data dataUsingEncoding:NSUTF8StringEncoding]];
rqst_finished = NO;
[post_data release];
NSURLConnection *http_connection = [[NSURLConnection alloc] initWithRequest:http_request];
[http_request release];
if(http_connection)
{
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
if([rqst_data length]>0)
{
NSString *rqst_data_str = [[NSString alloc] rqst_data encoding:NSUTF8StringEncoding];
SBJsonParser *json_parser = [[SBJsonParse alloc] init];
id feed = [json_parser objectWithString:rqst_data_str error:nil];
listing_items = (NSMutableDictionary *)feed;
[json_parser release];
[rqst_data_str release];
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Feed" message:#"No data returned" delegate:self cancemButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Connection Problem" message:#"Connection to server failed" delegate:self cancemButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[rqst_data setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[rqst_data appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
[rqst_data release];
[connection release];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[rqst_data release];
[connection release];
rqst_finished = YES;
}
Your initialization
NSMutableURLRequest *http_request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://www.feedserver.com/request/"]];
is a convenience constructor that has a built-in autorelease for the object you are initializing using the constructor. So by calling
[http_request release];
you are trying to release something that is auto-released. In other words, you are over-releasing.
You should only call release on objects that you allocate using the keywords,
"New", "Alloc", "Copy". or use "retain"
Line [http_request release]; is unnecessary as your object is autoreleased.
For creation of your NSMutableURLRequest you used method which returns aurora eased instance and you not responsible for it's release. If you use methods which require you perform -alloc, -copy, -retain than you responsible for releasing this instance.

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.