how to implement polling iphone sdk? - ios

I want to know how we can auto refresh a uitableview by using polling. I have a table which contains messages users sent. So when I load the view i use AFTNetworking to get the JSOn response and display it in the uitableview. Now if the user stays on the screen and we get a new message posted it should automatically refresh the uitableview.So far what I can do it to call the url at certain time intervals. Any solutions to that?

Following Timer will invoke "loadNewData" after each 10 seconds
NSTimer *refreshTimer = [NSTimer scheduledTimerWithTimeInterval:10.0f target:self selector:#selector(loadNewData) userInfo:nil repeats:YES];
write your loading code in this method
-(void)loadNewData
{
// write code to fetch Data from Server
}

Related

How to properly handle NSTimer calls?

I am running into a situation where I'm not able to properly handle NSTimer.
In my app, I've an option of user chats (I'm not using XMPP because of a low budget project, but the chat is working through API calls ONLY). I've scheduled a timer at a time interval of 15 seconds. If any new chats available I'll get it and will update chat view.
Here's the working scenario:
As this is a UITabbar based app, a user will come to "Chat" tab.
A User will have a list of persons with whom he can chat.
A User will select any of a user – will push to Chat Screen.
Where all locally saved chats will be visible and an API call will be made for new chats, on success (or error) of API call, a timer will be scheduled to sync chats at a time interval of 15 seconds.
If a user goes back (pops), in viewDidDisappear: method, I'm invalidating the (running) timer.
In my Unit testing, if I'll continuously push & pop to/from Chat screen, there'll be multiple instances of that timer will get scheduled. I suspect, this is WRONG.
I'm not sure what I'm doing is correct or not though I need your help to understand the right and the correct way to get my functionality done. I guess here there's no need of the code for above explanation.
First of all, why are you not exploring option of push notification? Polling server every 15 second is a bad design :-(.
Second, when it comes to NSTimer it is important to start and stop them from the same thread. I would advise you encapsulate your timer start/stop code in below block always ensuring you deal on main thread with your timer.
dispatch_async(dispatch_get_main_queue(), ^{
});
This is the way o usually work with NSTimer. Hope it helps.
#implementation MainViewController{
NSTimer *myTimer
}
- (void)startTimer{
//Prevents multiple timers at the same time.
[myTimer invalidate];
myTimer = [NSTimer scheduledTimerWithTimeInterval:5.0f target:self selector:#selector(update) userInfo:nil repeats:YES];
}
- (void)update
{
//Stops the timer if the view in not on the screen
if (!(self.isViewLoaded && self.view.window)) {
[myTimer invalidate];
}
}
#end

Cancelling Parse retries on bad internet connection

I'm trying to do something quite simple : Stopping a parse.com query after a few seconds, with an NSTimer. I've read after some reasearch it's a good "trick" to use.
Here is how I create my timer :
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:6.0
target:self
selector:#selector(stopRetries:)
userInfo:#{#"query":query}
repeats:NO];
Because i'm running this on a background thread (and outside a viewcontroller class), the timer is inside a dispatch_sync(dispatch_get_main_queue());
But whatever I do, I cannot stop the query, because [query cancel] doesn't do anything. I can't pass it in the userInfo of the timer. Breakpoints show it has an address and is "there" but it looks like junk inside.
What can I be doing wrong and what should I be doing instead?
My main goal is to make the parse.com query stop faster than 30 seconds, and warn the user with an alert.
You can Try this [self performSelector:#selector(abc) withObject:nil afterDelay:6.0];
or
You can Invalidate the timer

Why does my NSTimer double decrement my timer?

I have been staring at my code for hours now so I thought I might try coming here for some fresh eyes. I needed to create a timer so I used the code below to do that. The first line is where I create the timer and the second part is my decrementTime method. This is in Objective C for an IOS app. This is my first time posting on StackOverflow (I usually find the answer I am looking for), so please let me know of any unwritten rules that I am not following.
_timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(decrementTime) userInfo:nil repeats:YES];
- (void)decrementTime{
self.timeLeft--;
}
I'll add here where I invalidate the first timer
-(IBAction)infoClick:(id)sender{
[_timer invalidate];
}
Then here is info message, where I create another timer
- (void)hideInfoMessage {
_secondTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(decrementTime) userInfo:nil repeats:YES];
}
clarification on my code: the order of events starts with my first code block (creating the timer). Then my second code block is called (invalidating the timer). then finally my third code block is called(making a new timer).
I know it is double incrementing because when I run the code I can visually see the timer double incrementing.
It's pretty easy to invoke the code that creates a timer twice. When you do that you actually have 2 timers running concurrently. Each one will decrement your value, so it will get decremented twice per second.
If you create a timer in your viewWillAppear method, for example, then you need to invalidate it in your viewWillDisappear method so you're sure you only have one running.
The same approach applies to other situations where you create a timer. You need to make sure you balance every call that creates a timer with a call that invalidates that timer.
If you use one of the scheduledTimer... methods, you can save a weak pointer to the timer. The run loop will retain it as long as it's running. When you invalidate it, the system run loop will release it and it will be deallocated. When that happens your weak pointer gets zeroed, so you don't even have to test it to see if it's valid/nil in your viewWillAppear method.
EDIT:
You need to instrument your code. In your infoClick method, is the variable _timer nil? What is it's address?
BTW, the target of an NSTimer is supposed to be a method that takes a single parameter, the timer itself. You should change your decrementTime method to look like this:
- (void) decrementTime: (NSTimer *) timer
{
NSLog(#"In method decrementTime, timer = %X", (unsigned long) timer)
self.timeLeft--;
}
Then look at your log and see if your decrementTime method is being called from 2 different timers (I would bet money that it is.)
You might also want to log the address of the timers you get back from your calls to scheduledTimerWithTimeInterval...

iOS bonjour programming - wait for a response

I am pretty new to bonjour/networking with ObjC (although well versed in other areas!) I am asking for a bit of advice - I have an iOS app that will run on multiple iPads, in a store. The apps occasionally have to share some data, and the internet isn't always available so a webservice is not an option, hence I decided on using bonjour.
I have setup the Bonjour/NSNetservices and everything is functioning correctly, the ipads basically form an 'ad-hoc network' and connect automatically at app launch, however I am looking for advice for the following situation:
The app normally shares data in the background, without any user intervention - however there is one function where when a button is pressed on one app, data should be returned from another app remotely. The UI then updates when the data has been received from the other device - however if the connection should be lost to the other device, the data will never reach the users device, and the data will not be displayed. I am wanting to implement some form of timout, but unsure how to do this - any suggestions would be much appreciated!
The process flow for this is something like this:
button press on 'dev 1' > 'dev 1' broadcasts 'dev 2 please send data message' > 'dev 2' responds with requested data [timeout required here] > UI is updated if data is received /[if timeout fires, error message is displayed]
So I really just need a timeout for the last section - and I really cannot think of a way to implement it.
I can post code for this if required.
Thanks!
This solution may work if you have the possibility to manually cancel the request.
I believe you can use a simple NSTimer to cancel the request after a wait. I'm sure it's not the best solution, but it will probably work.
Here's how I would do it.
Create your timer and an NSInteger (to store the timer value) in your class :
NSTimer *timer;
NSInteger timerValue;
Call this method with timer = [self startTimer]; when you fire your request :
- (NSTimer*)startTimer {
timerValue = 30;
return [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(timerTicked:) userInfo:nil repeats:YES];
}
Implement the timerTicked: method :
- (void)timerTicked:(NSTimer*)timer {
timerValue --;
if (timerValue <= 0) {
// Cancel the request
// Show an alert
}
}
You can cancel the timer with [timer invalidate]; but remember this will "destroy" your timer, so it won't fire events ever again.
As you've not indicated how you are currently requesting data from your other device, I have had to make some assumptions.
You can use NSURLRequest with a timeout using requestWithURL:cachePolicy:timeoutInterval:
See NSURLRequest documentation

How to perform an action at a certain time with NSTimer?

I'm trying to perform an action at a certain time of the day.
I don't want to use UILocalNotification as I don't want the users to be away if anything is happening.
My current code is:
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(fire:) userInfo:nil repeats:NO];
You could:
Extract the current local time each time your app starts using [NSDate date] in application:didFinishLaunchingWithOptions method.
Calculate the time left for your alarm time to occur using dateWithTimeInterval:sinceDate.
Start a NSTimer with interval = that_time_difference.
I'm not sure what do you mean by:
"I don't want the users to be away of anything happening."
I am assuming you don't want anything to happen if the app is not running. The only thing I can think of would be push notifications.

Resources