How to schedule events programmatically in ios? - iphone

I have been tasked to write an app that allows a user to schedule emails to be sent out in future.
The user selects a date time from a date picker, composes the message and recipient and then schedules the event. When the date/time occurs the message is sent out.
Can someone guide me to how to get about scheduling lets say a text message. I know how to send a text message. Just was not sure on the scheduling aspect of things.
Any pointers will be much appreciated.

The first response will technically allow you to establish a timer that will fire every 2.5 seconds, however the original poster asked for a solution that would fire at a specific time. For that you need to use the following method of NSTimer:
- (id)initWithFireDate:(NSDate *)date interval:(NSTimeInterval)seconds target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats
The first argument is an NSDate indicating when the timer should fire.
The original poster did not specify, but if this is an iOS app then it is important to understand that timers scheduled to fire at a distant date/time will not fire if your app is not the foreground app. In fact there is no way to schedule such an event to occur when your app is in the background on iOS, so you must take that into account.

Here's a snippet of code which sets a one use timer to call self's imageSavedLabelOff: selector with itself (the timer) as the object parameter to the method. The timer schedules the call to be made in 2.5 seconds.
NSTimer *quickie = [NSTimer scheduledTimerWithTimeInterval:2.5 target:self selector:#selector(imageSavedLabelOff:) userInfo:nil repeats:NO];

You may have already found the answer by now but for future visiters like me I would like to suggest an answer- i.e. EventKit :
https://developer.apple.com/library/ios/documentation/DataManagement/Conceptual/EventKitProgGuide/ReadingAndWritingEvents.html
You can schedule/fetch events for any time and do your stuff accordingly. Hope this helps somebody.

You should be able to achieve this using NSRunLoop. Check out the Threading Programming Guide.

Apart from the use of NSTimer, you should be aware that sending of the E-Mail can fail for several reasons (no network available and others). Then you need to reschedule the request, maybe give up after 3 retries and notify the user about this.

You can use -
[self performSelector:#selector(myFunc:) withObject:nil afterDelay:5.0];

Related

iphone - how to send a sms message at a scheduled time

I am creating an application where user can send an SMS to the Recipient, and it is working fine. But I want to send Message at a scheduled time. For this I have two picker views, from one picker sender we can set date and from other sender can set time as I have shown in the attached screenshot.
How to trigger send button or send the sms at a scheduled time? Can I use an NSTimer?
Any help would be greatly appreciated. Thank you. If someone have any doubt related to question then let me know.
You can use NSTimer to schedule message.
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats
here you can pass target as Your view controller that has sms sending functionality and selector will be your action method that gets called on sms button click.
But problem with NSTimer is that it stops when App is in background.If you have such requirement then NSTimer will not be useful.
You can use NSTimer in background also...
You need to make some changes in appDelegate...
Follow the below link to make your app wait for background task to complete
beginBackgroundTaskWithExpirationHandler
for long time in background try (more than 10 min)
How do I make my App run an NSTimer in the background?

Fire method when a specific nsdate has passed

I want my App to call a method at an setter NSDate (It only needs to happen when the app is active, I'll handle passed events on launch in the app delegate).
I read about some ways to achieve such a behavior: On the one hand to work with performSelector:withObject:afterDelay: (But this doesn't look like a good way for me) or on the other hand to work with an NSTimer.
What is the best way regarding the app performance? One requirement is that you can cancel the event.
Using NSTimer is a simple solution. It has a property called fireDate that tells you when it's going to fire next. And it's a writeable property, so you can set that date to whatever you want.
Cancel the event by invalidating the timer object.

scheduledTimerWithTimeInterval vs performselector with delay with iOS 5.0

i am doing function call with scheduledTimerWithTimeInterval. i am just checking that xml parsing is completed or not for particular web services and invalidating timer in didEndElement method after getting successful response.
timerForStopWebService = [NSTimer scheduledTimerWithTimeInterval:30.0 target:self selector:#selector(stopWS) userInfo:nil repeats:NO];
now i am facing problem with iOS 5.0 and its working fine in other iOS versions. in iOS 5.0, a function stopWS call anytime even if i am invalidating it. let me know if you have solution for that.
and now i am implementing performselector with delay and set boolean variables in stopWS to identify that parsing is completed or not. i just want to know that is there any major difference between this? and does this solution works for my problem?
if other way exists, please suggest me, thanks.
Here are your differences
performSelectorWithObjectAfterDelay
as the name suggests performs a selector after a specified number of seconds. ONCE.
The care that you need to take here is that you need to cancel any previous perform requests before the object that the selector is being performed on is released. For that use the cancelPerformSelector method.
scheduledTimerWithTimeInterval
this method gives you the ability to call a selector after a specified duration too but it also has a parameter [repeats:] that lets you call the same selector REPEATEDLY
You can also pass in invocations to call selectors, which are specially helpful when your selector needs a lot of arguments.
You need to invalidate the timer when its no longer needed. This should do the trick
[myTimer invalidate]; myTimer = nil;
Also this is the most definitive thread on NSTimer, please have a look at it. How do I use NSTimer?
You can use performSelectorWithObjectAfterDelay and then cancelPerformSelector to abort it if no longer needed. I think this is easier than scheduledTimerWithTimeInterval since you don't need to store a reference to the timer. For the most part these two approaches should behave the same though.

iPhone - Get user interaction event and automatic logout

In my iPhone app I want to logout the user if nothing happens till about 2 minutes (e.g. the user puts down the phone). Does anybody has such issue? What is the best way to implement this feature? I think I save the date of last event to NSUserDefaults, then on the next event first I check the current date. If the difference is larger than 2 minutes go to login screen, else refresh the stored date. But how can I get the touch event generally?
Thanks, madik
There's a method in UIApplicationDelegate for that:
- (void)applicationWillResignActive:(UIApplication *)application
{
/*
Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
*/
}
Note that it also will be called when the app is going to background state. That will help you store the data whenever the app is going to inactive state. If you want to check if a certain amount of time has passed, you will have to use a NSTimer and store the last touch event. I think it cannot be done because you can't intercept all the touch events (Maybe it's over an object managed by the system. The status bar is an example). I guess is better to let the system to manage all the activity/inactivity stuff and store your data when necessary.
EDIT: I didn't understand what you mean the first time. Check this accepted answer, it accomplish what you need. Basically you have to subclass UIApplication and override sendEvent method.
'NSTimer'
When you say "how can I get the touch event generally?", if you mean how can you tell if the user is idle or not, you'll have to set up some system to gather all touch events at a higher level in your app. You could update the last touch time you mentioned in NSUserDefaults but that may be inefficient during the run of the app, so you could just post the touch event to your main app delegate and have it save the time of last touch. Which would also be where you could set up the 2 minute timer.
Something like:
- (void) someAppDelegateMethodThatYouCallForAnyUserEvent
{
[self.idleTimer invalidate];
self.lastEvent = [NSDate now];
self.idleTimer = [NSTimer scheduledTimerWithTimeInterval:120 target:self selector:#selector(logoutAndGotoLogin) userInfo:nil repeats:NO];
...
}
You'll also have to do some cleanup in your app delegate methods when the app goes to background etc if you support that behavior.

How to fire 10 messages per second?

Problem: I need to fire values to an object 10 times per second. I must be able to start firing and stop firing.
I've discovered that the delegate of an UIScrollView gets notified in about the same time intervals, no matter how fast the scrolling is. You can easily see that if you NSLog the deltas from the offset changes. There must be a way to start firing a message 10 times per second until something says "stop". But how?
I would look into the NSTimer class. That should allow you to set up a timer with an arbitrary time span (and stop it when desired).
I'm not much of a Cocoa developer, but I'm pretty sure you want NSTimer.
Look into [NSTimer timerWithTimeInterval:invocation:repeats:], [NSTimer invalidate], and NSRunLoop.