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

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.

Related

void (refresh) won't refresh

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!

iPhone .ipa file goes blank after opening splash screen?

I have created Map application and it is running on my mac machine with xcode. But when I created its ipa file and sync with my iPhone device it does not open. Only splash screen
get open and getting close. I have my developer and distribution certificate sign with device UDID. My client also could not able to run the application remotely....thanks in advance for your help. plz suggest what I am missing here??
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//sleep(0.5);
arrayNo = [[NSMutableArray alloc] init]; //pickerview radius array
[arrayNo addObject:#"5km"];
[arrayNo addObject:#"10km"];
[arrayNo addObject:#"15km"];
[window addSubview:[viewController view]];
[window makeKeyAndVisible];
return YES;
}
Upadated: with leaks problems
I am also checking the possibility with memory leaks and using instrument tool I am getting 100% leaks at the time of launching the application. Its NSPlaceholderString leaks on following code...
CLLocationCoordinate2D location;
NSString *url = [NSString stringWithFormat:#"..myurl......lat=%f&lng=%f&radius=5",locationManager.location.coordinate.latitude,locationManager.location.coordinate.longitude];
radiusinurl.text = #"5km";
NSURL *URL = [NSURL URLWithString:url];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:URL];
//Initialize the delegate.
**XMLParser *parser = [[XMLParser alloc] initXMLParser];** //5.3% leaks
//Set delegate
[xmlParser setDelegate:parser];
//Start parsing the XML file.
**BOOL success = [xmlParser parse];** //0.2% leaks
[xmlParser release];
[parser release];
if(success)
{
NSLog(#"show me [appDelegate.markers count] %d",[appDelegate.markers count]);
annobjs = [[NSMutableArray array] retain];
if([appDelegate.markers count] == 0)
{ //99% leaks on below line where I am calling another method
**[self performSelector:#selector(showingThreeResultsOnCurrentLocation) withObject:nil];** //99% leaks
}
else
{//some logic
}
}
else
{
//logic
}}}}
I have commented leaks at the end of line. Can you correct my code. Thanks in advance...
Initialize view controller first
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; //This is for autoresize when in phone call mode(which does not work yet)
[dict setObject:#"trigger" forKey:#"frame"];
[[NSNotificationCenter defaultCenter] postNotificationName:#"trigger"
object:self
userInfo:dict];
arrayNo = [[NSMutableArray alloc] init]; //pickerview radius array
[arrayNo addObject:#"5km"];
[arrayNo addObject:#"10km"];
[arrayNo addObject:#"15km"];
viewController = [[UIViewController alloc] initWithNibName:#"UIViewController" bundle:nil];
UINavigationController *nav = [[UINavigaitonController alloc] initWithRootViewController:nav];
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
self.window.rootViewController = nav;
[self.window makeKeyAndVisible];
return YES;
}

UITabelView doesn't get updated with new content from server side

I have an app which has an UITabelView which gets its content from a server side.In my app i read the content from the server each 30 seconds....for that I use a NSTimer.
This NSTimer gets initialized when I load the view which contains the UITableView and it is invalidated when I leave this view.
My problem is this:
if on the server side the content for the UITableView is updated with new item and the JSON received in the iphone app as a response to a request to the server contains that item....the UITableView that appears on the screen is still not updated.
Here is how I did it:
//the timer is started when this view is loaded and the method repeatServerRequest is called
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
if(playlistTimer == nil)
playlistTimer = [NSTimer scheduledTimerWithTimeInterval:30.0 target: self selector: #selector(repeatServerRequest) userInfo: nil repeats: YES];
}
//the method repeatServerRequest starts a new thread in the background which does a request //to server for downloadeding the content
- (void) repeatServerRequest{
[NSThread detachNewThreadSelector:#selector(backgroundThinking) toTarget:self withObject:nil];
}
- (void) backgroundThinking{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSURL *url = [NSURL URLWithString:#"a link to server"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[request startAsynchronous];
[pool release];
}
///when the response from server comes in these methods are called:
- (void)requestFinished:(ASIHTTPRequest *)request
{
[self performSelectorOnMainThread:#selector(didFindAnswer:) withObject:request waitUntilDone:YES];
}
- (void)requestFailed:(ASIHTTPRequest *)request
{
NSError *error = [request error];
NSLog(#"the value of error %#", error);
}
- (void) didFindAnswer:(ASIHTTPRequest *) request{
NSLog(#"update tabel");
SBJSON *parser = [[SBJSON alloc] init];
NSString *responseString = [request responseString];
NSArray *statuses = [parser objectWithString:responseString error:nil];
streams = [statuses valueForKey:#"_playLists"];
[parser release];
playList = [[NSMutableArray alloc] init];
idList = [[NSMutableArray alloc] init];
int ndx;
for (ndx = 0; ndx<streams.count; ndx++) {
NSDictionary *stream = (NSDictionary *)[streams objectAtIndex:ndx];
[playList addObject:[stream valueForKey:#"name"]];
[idList addObject:[stream valueForKey:#"id_playlist"]];
}
NSLog(#"playList %#", playList);
oneview = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 480, 320)];
tableViewPlaylist =[[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) style:UITableViewStylePlain];
tableViewPlaylist.bounces=NO;
tableViewPlaylist.backgroundColor=[UIColor clearColor];
[tableViewPlaylist setDelegate:self];
[tableViewPlaylist setDataSource:self];
}
So when I update the content on server side, the JSON thet I get as a response on server side is updated but the UITAbelView is not, UNLESS I RUN AGAIN MY APP.Any idea why?
Two main problems:
You are creating a new UITableView every time the server updates. This is unnecessary.
Even if you wanted a new tableView, you are not adding it as a subview of the main view.
What you should do instead is don't create a new tableView at all. After you've updated the data model call [tableView reloadData] on the main thread. Your table will update and all is good. Assuming you have everything configured correctly and it sounds like you do if you see the expected data when you launch the app.

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

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.