void (refresh) won't refresh - nsxmlparser

I have an iPhone app that uses the method
- (void)refresh
{
self.title = #"Refreshing...";
self.tableView.userInteractionEnabled = NO;
self.tableView.alpha = 0.5;
[self.dataController parse];
}
to refresh and reparse.
The problem is that when I tap the refresh button on the navigationBar, the program just freezes and does not refresh the data. The app pulls data from RSS and pushes it into a tableViewController.
Here's the code for the barButtonItem
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh
target:self
action:#selector(refresh)];
Here's the parse method:
- (void) parse
{
[self parseXMLFileAtURL:#"http://www.baylornotes.org/rss/articles/all"]
}
-(void) parseXMLFileAtURL:(NSString *)URL
{
NSURL *feedURL = [NSURL URLWithString:URL];
parser = [[NSXMLParser alloc] initWithContentsOfURL:feedURL];
[parser setDelegate:self];
[parser setShouldProcessNamespaces:NO];
[parser setShouldReportNamespacePrefixes:NO];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
}
Help!

Related

How to show load bar in ipad app while data is fetching from xml after default png is shown

I am fetching XML data from server i want that when data is loading in progress i show a loading bar with default screen this is code in appDidFinishing
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
RootViewController * rootViewController = [[RootViewController alloc] initWithNibName:#"RootViewController" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
[self.window addSubview:navigationController.view];
self.activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(55, 67, 100, 100)];
[self.activityIndicator startAnimating];
[self.window addSubview:self.activityIndicator];
[self loadXMlTwo];
[self loadXMlMain];
[self performSelectorInBackground:#selector(loadXMlOne) withObject:nil];
[self.activityIndicator removeFromSuperview];
[window makeKeyAndVisible];
return YES;
}
-(void)loadXMlMain{
NSURL*url= [[NSURL alloc]initWithString:#"http://46.137.28.14/app/ipadApplic/working.xml"];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
//Initialize the delegate.
XMLParser *parser = [[XMLParser alloc] initXMLParser];
//Set delegate
[xmlParser setDelegate:parser];
BOOL success = [xmlParser parse];
if(success)
NSLog(#"No Errors");
else
NSLog(#"Error Error Error!!!");
}
-(void)loadXMlOne{
NSURL*url1=[[NSURL alloc] initWithString:#"http://46.137.28.14/app/ipadApplic/rowone.xml"];
NSXMLParser *xmlParserRow = [[NSXMLParser alloc] initWithContentsOfURL:url1];
//Initialize the delegate.
RowOneParser *parser1 = [[RowOneParser alloc] initXMLParser];
//Set delegate
[xmlParserRow setDelegate:parser1];
BOOL success1 = [xmlParserRow parse];
if(success1)
NSLog(#"No Errors");
else
NSLog(#"Error Error Error!!!");
}
-(void)loadXMlTwo{
NSURL*urlRowTwo=[[NSURL alloc] initWithString:#"http://46.137.28.14/app/ipadApplic/rowtwo.xml"];
NSXMLParser *xmlParserRowTwo = [[NSXMLParser alloc] initWithContentsOfURL:urlRowTwo];
//Initialize the delegate.
RowTwoParser *parserRowTwo = [[RowTwoParser alloc] initXMLParser];
//Set delegate
[xmlParserRowTwo setDelegate:parserRowTwo];
BOOL successRow = [xmlParserRowTwo parse];
if(successRow)
NSLog(#"No Errors");
else
NSLog(#"Error Error Error!!!");
}
What you need to do is unblock your main thread while you are doing background fetch of xml data. Easiest way to do that is add your fetch operations in NSOperationQueue. Set up delegates for the class which fetches the xml and handle the response.

xml parsing consumes time need efficent way on iphone

How to call main thread ??? i can parse but i cant display data
- (void)viewDidLoad {
//self.navigationItem.rightBarButtonItem = self.editButtonItem;
self.parentViewController.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"10.png"]];
[super viewDidLoad];
[NSThread detachNewThreadSelector:#selector(startTheBackgroundJob) toTarget:self withObject:nil];
}
- (void)startTheBackgroundJob {
NSUserDefaults *getida = [NSUserDefaults standardUserDefaults];
myIDa = [getida stringForKey:#"AppID"];
NSLog(#"#BOOK MARK ");
NSString *ubook = [[NSString alloc] initWithFormat:#"http://www.wapp=%#&action=show",myIDa];
NSLog(#" bookmark %#",ubook);
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
//NSString *outputString = [[NSString stringWithString:usearch] stringByAppendingString: UserText];
ubook = [ubook stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(#"My string is now = %#", ubook);
NSURL *url = [[[NSURL alloc] initWithString:ubook]autorelease];
//NSURL *url= [NSURL URLWithString:outputString];
NSLog(#" bookmark URL IS %#",url);
NSXMLParser *xmlParser = [[[NSXMLParser alloc] initWithContentsOfURL:url] autorelease];
//Initialize the delegate.
XMLParserbookm *parser = [[[XMLParserbookm alloc] initXMLParser]autorelease];
//Set delegate
[xmlParser setDelegate:parser];
//Start parsing the XML file.
BOOL success = [xmlParser parse];
if(success)
{
NSLog(#" xml parsed suucess");
//[super viewDidLoad];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
//[self searchTableView];
//mytimer4=[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(wipe) userInfo:nil repeats:NO];
}
else{
NSLog(#"eeror");
}
[NSThread sleepForTimeInterval:3];
[self performSelectorOnMainThread:#selector(makeMyProgressBarMoving) withObject:nil waitUntilDone:NO]; // HOW TO CALL MAIN THREAD
[pool release]
}
You can try with
viewDidAppear:, this method is called after you go to a new view. Then at least, you can switch to new view, you should make sure that there is something on the screen in waiting for the xml parsing
Using Thread: You put parsing into another thread and then callback your main thread after you finish, then there will be no block at all

UITabelView reloaded from NSXMLParser (iphone SDK 4.0)

I am creating application that simply reads data from an XML file and displays it in a table view.
I created a "refresh" button when clicked i want it to redownload the xml file and display it again however it seems to crash my application if there is a XML file already downloaded.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
ipb = [[IPB alloc] init];
sectionTitle=[[NSMutableArray alloc]init];
currentURL=#"http://localhost:8888/xml/Sinnergy.xml";
[self reloadTableView];
[window makeKeyAndVisible];
return YES;
}
-(void)reloadTableView
{
pathURL = [NSURL URLWithString:currentURL];
parser = [[NSXMLParser alloc] initWithContentsOfURL:pathURL];
[parser setDelegate:self];
[parser parse];
[mainTableView reloadData];
}
You are leaking the parser, and if its an instance variable it might cause issues. You should go
NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:pathURL];
[parser setDelegate:self];
[parser parse];
[parser release];
Also you are asking the parser to start parsing, but at that point of time you shouldn't be reloading the table, it should be in your
- (void)parserDidEndDocument:(NSXMLParser *)parser
delegate method. Try that and if it still crashes post the crash report

How can I disable a button while NSXMLParser runs, then enable it when it completes?

I have a viewController which imports XMLParser.h as the class xmlParser
I'm passing an NSURL object in my viewController to the xmlParser class with the getXML method below
goButton is the button I tap to call the getXML method below. I disable the button which I tapped to trigger the getXML method, but I'm not sure where to put the code to enable it again once the xmlParser has finished parsing the returned XML.
- (IBAction) getXML {
goButton.enabled = NO;
// allocate and initialize the xmlParser
xmlParser = [[XMLParser alloc] init];
// then generate the URL we are going to pass to it and call the fetchXML method passing the URL.
NSURL *xmlurl = [[NSURL alloc] initWithString:#"http://www.mysite.com/myfile.xml"];
[xmlParser fetchXMLFromURL:xmlurl];
// release objects
[xmlurl release];
[xmlParser release];
}
As per #Squeegy recommendation, I modified my code.
- (IBAction) getXML {
goButton.enabled = NO;
xmlParser = [[XMLParser alloc] init];
[self performSelectorInBackground:#selector(parseInBackground:) withObject:xmlParser];
}
- (void)parseInBackground:(XMLParser*)parser {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSURL *xmlurl = [[NSURL alloc] initWithString:#"http://www.mysite.com/myfile.xml"];
[parser fetchXMLFromURL:xmlurl];
[self performSelectorOnMainThread:#selector(didFinishXMLParsing:) withObject:parser];
[xmlurl release];
[pool drain];
}
- (void)didFinishXMLParsing:(NSXMLParser*)parser {
goButton.enabled = YES;
}
Looks to be working until it gets to the line
[self performSelectorOnMainThread:#selector(didFinishXMLParsing:) withObject:parser];
The compiler complains as follows:
2010-02-17 00:22:20.574 XMLApp[2443:521b] *** -[viewController performSelectorOnMainThread:withObject:]: unrecognized selector sent to instance 0x1285a0
2010-02-17 00:22:20.578 XMLApp[2443:521b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[viewController performSelectorOnMainThread:withObject:]: unrecognized selector sent to instance 0x1285a0'
2010-02-17 00:22:20.583 XMLApp[2443:521b] Stack: (
861696817,
860329709,
861700631,
861203093,
861166272,
18715,
846004025,
845672609,
848189713
)
- (IBAction)getXML {
goButton.enabled = NO;
xmlParser = [[XMLParser alloc] init];
NSURL *xmlurl = [[NSURL alloc] initWithString:#"http://www.mysite.com/myfile.xml"];
[xmlParser fetchXMLFromURL:xmlurl];
[self performSelectorInBackground:#selector(parseInBackground) withObject:xmlParser];
[xmlurl release];
[xmlParser release];
}
- (void)parseInBackground:(NSXMLParser*)parser {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[parser parse];
[self performSelectorOnMainThread:#selector(didFinishXMLParsing:)
withObject:parser
waitUntilDone:NO];
[pool drain];
}
- (void)didFinishXMLParsing:(NSXMLParser*)parser {
goButton.enabled = YES;
}
The trick is to do the processing on a background thread, which allows the UI to do stuff. When parsing is done, you have to make any UI changes back on the main thread.
When the parser finishes parsing, it will call it's delegate's:
- (void)parserDidEndDocument:(NSXMLParser *)parser
In that method, you can re-enable the button. You should probably do so with a performSelectorInMainThread call, since it involves changing a view.

iPhone XML Parser - [c setImage:[attributeDict objectForKey:#"img"]]; WARNING

Hi I am having issues with the following and it crashes the iPhone simulator, while the script has no errors it did bring up one warning in this script.
[c setImage:[attributeDict objectForKey:#"img"]];
The warning is
City may not respond to -setImage:
I am not sure what I have done wrong here is the fill source code.
#import "LocationsParser.h"
#implementation LocationsParser
#synthesize managedObjectContext;
-(id) initWithContext: (NSManagedObjectContext *) managedObjContext
{
self = [super init];
[self setManagedObjectContext:managedObjContext];
return self;
}
- (void)parseXMLFileAtURL:(NSURL *)URL parseError:(NSError **)error
{
// /Applications/MyExample.app/MyFile.xml
NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:URL];
// Set self as the delegate of the parser so that it will receive the parser delegate methods callbacks.
[parser setDelegate:self];
// Depending on the XML document you're parsing, you may want to enable these features of NSXMLParser.
[parser setShouldProcessNamespaces:NO];
[parser setShouldReportNamespacePrefixes:NO];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
NSError *parseError = [parser parserError];
if (parseError && error) {
*error = parseError;
}
[parser release];
}
-(void) emptyDataContext
{
// Get all counties, It's the top level object and the reference cascade deletion downward
NSMutableArray* mutableFetchResults = [CoreDataHelper getObjectsFromContext:#"County" :#"Name" :NO :managedObjectContext];
// Delete all Counties
for (int i = 0; i
use this
[c setImage:(id)[attributeDict objectForKey:#"img"]];
c - what is it? E.g., if it is supposed to be UIImageView, you can do so:
[(UIImageView *)c setImage:[attributeDict objectForKey:#"img"]];