Updating UIView after some time interval? - iphone

I want to create Custom Views that call webservice after some time and update themself..The data should be updated even when the application is not in active state.. so What is the best way for doing this ??

Use NSTimer, but data will not update when application is in background mode. After application became active NSTimer will continue working.

you can use NSTimer for that. Add your code in your custom method and call that method like bellow..
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:3.0f target:self selector:#selector(yourMethodName:) userInfo:nil repeats:YES];
Here in scheduledTimerWithTimeInterval Parameter you can set the time in seconds so your method which passes in selector Parameter is called after every 3 seconds..
See one Example and tutorial of NSTimer From this link nstimer-tutorial-creating-clockstopwatchtimer-iphoneipad
UPDATE:
If you want to call webservice then you can use NSThread like bellow...
- (void) runTimer
{
[NSThread detachNewThreadSelector:#selector(updateAllVisibleElements)toTarget:self withObject:nil];
}
- (void) updateAllVisibleElements {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
if(service == nil)
{
service = [[WebService alloc] init];
}
[service getlocationID:currentLatitude andlongitude:currentLongitute];
[pool release];
}
See the link Here

You'll be able to track the location, but you'll not be able to connect to your web-services when the app is in the background.

Related

NSTimer in Objective C when Click on Home Button

I have NSTimer in ViewController Class.. And all the methods for NStimer are in that class.. My NSTimer is working properly for play and pause... When i press home button on iPhone also the timer is working properly(it starts running from the time where the application enters into background when the application enters into foreground)... In my application i am rising an alert quickly when my application enters into foreground(UIAlertview in application didEnterForeGround). Here my NSTimer is running when the alert is on the screen(didn't give response to alert).. I want stop the NSTimer Upto the User responding to my alert... After that I want to start the NSTimer... How Can i do that...? Please help me... Thanks in Advance... I want call the NSTimer methods from Appdelegate.m file... Iam calling these methods properly... And the methods in ViewController are called.. But the action is Not Performing... For the Same method when call from viewController class it is working...
enter code here
ViewController.h
+(ExamViewController *)evcInstance;
ViewController.m
ExamViewController *evc = nil;
#implementation ExamViewController
+(ExamViewController *)evcInstance
{
if(!evc)
{
evc = [[ExamViewController alloc] init];
}
return evc;
}
- (void)onStartPressed
{
stopwatchtimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(updateTimer:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:stopwatchtimer forMode:NSRunLoopCommonModes];
resume.hidden = YES;
resume.enabled=NO;
pause.hidden = NO;
pause.enabled=YES;
}
- (void)onStopPressed
{
[stopwatchtimer invalidate];
stopwatchtimer = nil;
pause.hidden = YES;
pause.enabled=NO;
resume.hidden = NO;
resume.enabled=YES;
}
Appdelegate.m
- (void)applicationWillEnterForeground:(UIApplication *)application
{
[[ExamViewController evcInstance] onStopPressed];
NSLog(#"applicationWillEnterForeground");
if(viewCalled ==YES)
{
UIAlertView *alertview=[[UIAlertView alloc]initWithTitle:#"" message:#"DO! You Want To continue" delegate:self cancelButtonTitle:#"YES" otherButtonTitles:#"NO", nil];
[alertview show];
[alertview release];
}
/*
Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
*/
}
a few things:
1) It looks like an incomplete singleton design. If you really want a singleton, refer to a post like this one.
2) No need to add stopwatchtimer to the current run loop. The scheduledTimerWithTimeInterval method schedules it for you.
3) I don't see where you declare stopwatch timer, but be sure to declare it as a retained property (or strong in ARC).
4) To stop the timer, just call [stopwatchtimer invalidate]; To restart it, re-instantiate and overwrite the old one using the same scheduledTimerWithTimeInterval class method that you called originally.
5) To do anything when an alert view completes, implement the delegate method:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
So you can invalidate the timer before presenting the alert, then rebuild it when you get notified the alert is finished.

NSTimer scheduledTimerWithTimeInterval: repeats:NO selector method calls multiple times

I am using NSThread along with NSTimer.
My code is like this
-(void) checkForRecentAlarm
{
if ([self.alarmThread isFinished])
{
[self.alarmThread cancel];
}
self.alarmThread = [[NSThread alloc] initWithTarget:self selector:#selector(startTimerForRecentAlarm) object:nil];
[self.alarmThread start];
//[NSThread detachNewThreadSelector:#selector(startTimerForRecentAlarm) toTarget:self withObject:nil];
}
-(void)startTimerForRecentAlarm
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
self.recentAlarmTime = [NSDate date];
self.dbObject = [[RADataBaseModelManager alloc] init];
self.recentAlarmTime = [self.dbObject getMostRecentAlarmTimeFromDB];
if (self.recentAlarmTime) {
NSTimeInterval timeIntervalToAlarm = [self.recentAlarmTime timeIntervalSinceNow];
NSRunLoop* runLoop = [NSRunLoop currentRunLoop];
//Fire timer every second to updated countdown and date/time
self.RATimer = [NSTimer scheduledTimerWithTimeInterval:timeIntervalToAlarm target:self selector:#selector(timerFireMethod:) userInfo:nil repeats:NO];
[runLoop run];
}
[pool release];
}
- (void)timerFireMethod:(NSTimer*)theTimer
{
[self.RATimer invalidate];
[theTimer invalidate];
self.RATimer = NULL;
theTimer = NULL;
[self playAlarm];
UIAlertView *alarmAlert = [[UIAlertView alloc] initWithTitle:#"Alarm" message:#"" delegate:self cancelButtonTitle:#"Close" otherButtonTitles:#"Snooze", nil];
[alarmAlert show];
[alarmAlert release];
alarmAlert = nil;
}
Now the problem is, my alertbox comes twice for one call in the
startTimerForRecentAlarm
method. So that the alert comes consequently twice and my view get stuck.
What will be problem here?
I am trying to implement an alarm with multiple alarm option using a single NSTimer.
Please help.
When I debug this, I can find many simultaneous threads are running on same code(UIAlertView).
I can't see any obvious reason why that would be called twice, but it does seem like an overly complex way of doing what you need to do.
Have you thought about using local notifications?
If you don't want to do that, you could refactor your code so it works like this:
1. Add a new event
2. If there's no timer or the time to the event is shorter than the time on the timer, then set the timer for this event.
3. When a timer fires, check for the next event and set a timer for that event (if there is one).
This does seem really complex. My general observation is that if you get two timer firings it's because you have two timers for some reason.
If you have multiple threads doing UIAlertView, you have another problem, because you can only (reliably) do UI from the main thread.

How to call NSThread repeatedly?

I am working on an application where i have to call a thread repeatedly. In that thread we have to parse an XML and i have to get updated data from that xml. now please guide me how to call that thread repeatedly? if my thread is in working and my code calls it again, then i think it will have a crash on it.
Separate the code into a new method
-(void) thisMethodWillRunAsASeparateThread
{
//Threads need their own pool.
NSAutoreleasePool *pool = [NSAutoreleasePool new];
while (thisThreadShouldRun)
{
// run xml parsing code
}
[pool release];
}
and to start the thread:
[NSThread detachNewThreadSelector:#selector(thisMethodWillRunAsASeparateThread) toTarget:self withObject:nil];
To call any code repeatedly you must NSTimer like:
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.10f target:self
selector:#selector(methodName) userInfo:nil repeats:YES];
you should to invalidate the timer after use. while if you wan to execute the code using background thread you must this code but this will not repeat multiple times.
[NSThread detachNewThreadSelector:#selector(methodName:) toTarget:self withObject:objName,nil]];

Background repeated job

I have a question about multithreading in xcode. I have searched for numerous web sites but still cannot get my app to work. I want to do a repeated job every 5sec even the Home button is pressed i.e. continue to time in background. The following is my code:
- (void)viewDidLoad {
[super viewDidLoad];
[NSThread detachNewThreadSelector:#selector(test) toTarget:self withObject:nil];
}
In test.m,
-(void)test {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:#selector(sayYeah) userInfo:nil repeats:YES];
[pool release];
}
in sayYeah.m,
-(void)sayYeah {
NSLog(#"yeah");
}
What I expect is "yeah" will continue to pop up every 5sec even the home button is pressed. But it didnt, can anyone have an idea how the multithread should be implemented? Thanks!
You can't unless your app fall is the category VOIP, audio playback or location update.
And you can't use timers.

iPhone-SDK:Call a function in the background?

Is it possible to call my function in the background after certain interval programmatically in iPhone SDK development? I want to call one particular function in the background for certain time intervals(may be every 10 mins) during my app in on running..
Could you please share your ideas.
thanks.
Clave/
Easiest way is to schedule a NSTimer on the main threads run-loop. I suggest that the following code is implemented on your application delegate, and that you call setupTimer from applicationDidFinishLaunching:.
-(void)setupTimer;
{
NSTimer* timer = [NSTimer timerWithTimeInterval:10 * 60
target:self
selector:#selector(triggerTimer:)
userInfo:nil
repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}
-(void)triggerTimer:(NSTimer*)timer;
{
// Do your stuff
}
If your stuff here takes a long time, and you can not hold up the main thread then either call your stuff using:
[self performSelectorInBackground:#selector(myStuff) withObject:nil];
Or you could run the NSTimer on a background thread by with something like this (I am intentionally leaking the thread object):
-(void)startTimerThread;
{
NSThread* thread = [[NSThread alloc] initWithTarget:self
selector:#selector(setupTimerThread)
withObject:nil];
[thread start];
}
-(void)setupTimerThread;
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSTimer* timer = [NSTimer timerWithTimeInterval:10 * 60
target:self
selector:#selector(triggerTimer:)
userInfo:nil
repeats:YES];
NSRunLoop* runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer:timer forModes:NSRunLoopCommonModes];
[runLoop run];
[pool release];
}
-(void)triggerTimer:(NSTimer*)timer;
{
// Do your stuff
}
You can have a timer, look into NSTimer for that that will fire off every 10 minutes, in order to make i t happen i n the background you have a few options ill name two.
First of note that any UI work should not be done in another thread since UIKit is not thread safe.
You can subclass NSThread and use it to do you process in the background
You can use NSObjects performSelectorInBackground method which basically creates a thread and executes the method. Heres a reference http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/performSelectorInBackground:withObject:
NSThread reference here http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSThread_Class/Reference/Reference.html
NSTimer reference here
http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSTimer_Class/Reference/NSTimer.html
To call the function on the main thread, use an NSTimer.
To call it on another thread, create an NSOperation and set up an NSOperationQueue to call it.