I have being wondering these days how can I subtract 3, 10 and 20 minutes from selected time from time picker in Swift 3. So for example when the user selects the start time of an event, to be able to receive notification 3, 10 or 20 minutes before the selected from the picker time value. I have tried
let value:TimeInterval = 1187.5
let periodComponents = startTimePicker.date.addingTimeInterval(-value)
for the 20 minutes earlier,
but I'm getting the value 2 hours behind(may be the console is showing me the GTM time only). Is it possible to schedule notification from "periodComponens" to repeat every week on the selected time on specific day of the week? Or I should use other subtracting method?
Use the built-in Calendar class:
let threeMinutesEarlier = Calendar.current.date(byAdding: .minute, value: -3, to: myPicker.date)
There is nothing wrong with your code.
The xcode console just prints out GMT date time by default. If you use NSDateFormatter to convert your NSDate into NSString and print it out, the result will be as you expected
If you use UILocalNotification and wish to schedule it to fire weekly you can set its provided property repeatInterval to NSCalendarUnitWeekOfYear.
For example:
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
NSDate *fireTime; // Your desired date time.
localNotif.fireDate = fireTime;
localNotif.repeatInterval = NSCalendarUnitWeekOfYear;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
Related
I'm trying to figure out how I can make an alert popup once the user has reached their goal. However, I only want it to show once a day after it's been triggered. Apologies in advance. if my logic is off with tackling this issue.
// Check to see if hydration goal has been reached
if (waterCups >= dailyHydrationGoal) {
// User has reached goal
if (alert has not been fired yet today) {
// alert pop up you reached your goal!
}
}
How would I go about ensuring it only launches once per day?
You can use isDateInToday: method to check whether the given date is in “today.”
NSDate *lastAlertDate = (NSDate *)[[NSUserDefaults standardUserDefaults] objectForKey:#"lastAlertDate"];
if(![[NSCalendar currentCalendar] isDateInToday:lastAlertDate]){
//Show alert
NSDate *today= [NSDate date];
[[NSUserDefaults standardUserDefaults] setObject:today forKey:#"lastAlertDate"];
}
Do you have a persistence store? (NSUserDefaults, core data etc...)
You can store a time stamp (NSDate) of the last time an alert was shown then check if the last time it was shown is today. How to determine if an NSDate is today?
If an alert has not been shown today, pop an alert and record a new time stamp.
I'm a newbie in swift language. I am using UILocalNotification to make a local notification. In Objective-C, I can sent repeatInterval to not repeat by assigning it to 0.
UILocalNotification* alarm = [[UILocalNotification alloc] init];
alarm.repeatInterval = 0;
But when I assign 0 to repeatInterval in Swift I got an error.
let alarm : UILocalNotification = UILocalNotification()
alarm.repeatInterval = 0
If you have any idea to fix it, please tell me.
You could likely set it to zero like this:
alarm.repeatInterval = NSCalendarUnit(rawValue: 0)
This way you are properly casting the value.
Is it possible to have an action from a button a) do an NSDate store when tapped, and then b) for that method to do a date comparison with an if statement?
So, for instance, if the stored NSDate was less than 12 hours ago, the user could not press the button again?
Haven't come across a tip on this from my research.
Sure. You can get current date by code
[NSDate date]
Then save him into NSUserDefaults
And check a current date with saved date on button press.
How
if ( [[NSDate date] timeIntervalSinceDate: savedDate] >= 12*60*60) // 12 hours
{
// do your steps
}
I'm working with an app that processes device motion events and updates interface in 5 second increments. I would like to add an indicator to the app that would display the total time the app has been running. It seems that a stopwatch-like counter, like the native iOS Clock app is a reasonable way to count time that the app has been running and display it to the user.
What I'm not sure of is the technical implementation of such a stopwatch. Here's what I'm thinking:
if I know how long between interface updates, I can add up seconds between events and keep a count of seconds as a local variable. Alternatively, a 0.5 second interval scheduled timer can provide the count.
If I know the start date of the app, I can convert the local variable to date for each interface update using [[NSDate dateWithTimeInterval:(NSTimeInterval) sinceDate:(NSDate *)]
I can use a NSDateFormatter with a short time style to convert the updated date to a string using stringFromDate method
The resulting string can be assigned to a label in the interface.
The result is that the stopwatch is updated for each "tick" of the app.
It appears to me that this implementation is a bit too heavy and is not quite as fluid as the stopwatch app. Is there a better, more interactive way to count up time that the app has been running? Maybe there's something already provided by iOS for this purpose?
If you look in the iAd sample code from Apple in the basic banner project they have a simple timer:
NSTimer *_timer;
_timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(timerTick:) userInfo:nil repeats:YES];
and the the method they have
- (void)timerTick:(NSTimer *)timer
{
// Timers are not guaranteed to tick at the nominal rate specified, so this isn't technically accurate.
// However, this is just an example to demonstrate how to stop some ongoing activity, so we can live with that inaccuracy.
_ticks += 0.1;
double seconds = fmod(_ticks, 60.0);
double minutes = fmod(trunc(_ticks / 60.0), 60.0);
double hours = trunc(_ticks / 3600.0);
self.timerLabel.text = [NSString stringWithFormat:#"%02.0f:%02.0f:%04.1f", hours, minutes, seconds];
}
It just runs from start up, pretty basic.
Almost what #terry lewis suggested but with an algorithm tweak:
1) schedule a timer
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(timerTick:) userInfo:nil repeats:YES];
2) when the timer fires, get the current time (that's the tweak, don't count ticks because if there is wobble in the timer, tick counting will accumulate the error), then update the UI. Also, NSDateFormatter is a simpler and more versatile way to format time for display.
- (void)timerTick:(NSTimer *)timer {
NSDate *now = [NSDate date];
static NSDateFormatter *dateFormatter;
if (!dateFormatter) {
dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = #"h:mm:ss a"; // very simple format "8:47:22 AM"
}
self.myTimerLabel.text = [dateFormatter stringFromDate:now];
}
I'm working on app that sets an UILocalNotification. This is the first time I use it and I'd like to have some explanations to use it efficiently and in the best way.
Which is the bast way to countdown to the time of notification expiration? I'd like to show to the user an UILabel with the missing time, this UILabel updates every second and when I reopen my app it must show the timer.
I've done this in this way:
When I reopen my app or the recall the view that has to show the timer I check if there is a UILocalNotification with the userInfo I've setted previously then I subtract to its NSDate
the current time so I get the difference, and update the UILabel. I know it shows time in seconds but if this procedure it's good I will convert it into time.
Is there any best way to do this?
Here is my code:
UILocalNotification *countDownNotificationSetted;
NSArray *scheduledNotificationArray = [[UIApplication sharedApplication] scheduledLocalNotifications];
for (int i = 0; i<[scheduledNotificationArray count]; i++)
if ([[[[scheduledNotificationArray objectAtIndex:i] userInfo] objectForKey:#"ID"] isEqualToString:#"ParkNotification"]) {
countDownNotificationSetted = [scheduledNotificationArray objectAtIndex:i];
break;
}
NSDate *expringDate = [countDownNotificationSetted fireDate];
NSTimeInterval timeLeftToNotification = [expringDate timeIntervalSinceNow];
if(timeLeftToNotification == 0){
[countDownTimer invalidate];
}
datePicker.countDownDuration = timeLeftToNotification;
_countDownLabel.text = [NSString stringWithFormat:#"%.0f", timeLeftToNotification];
NSLog(#"%.0f", timeLeftToNotification);
I think it would be better if you would update your label with a timer as you already do , when you close the app, store that time locally in a file or user defaults and when the app launches again read from that file the time. Or if you want the time passed since the first openning of the app, just write the time in appDidFinishLaunching and get it from there every time . I don't see the benefit of the local notification here.
Hope this helps.
Cheers!