I have a case where a user needs to submit a form everyday before 8am.
When they submit, a confirmation view is overlaid to show the user they have submitted as well as stop them from submitting again.
After 8am, I want to clear the form and have the form view available again by hiding the overlaid view. I want to do this at one point in time at 8am if possible.
I was thinking about accomplishing this with NSTimer. Can I set a timer that will run at 8am that will clear the form and remove the overlay view?
Is there a better way to handle this scenario?
You could use a local push notification. Official doc here
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Introduction.html
Something like that:
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate date]; // Replace me with your "event" date
localNotification.timeZone = [NSTimeZone localTimeZone];
localNotification.repeatInterval = kCFCalendarUnitDay;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
then you can "catch" the notification as the doc says
If your app is frontmost, the application:didReceiveRemoteNotification: or application:didReceiveLocalNotification:method is called on its app delegate If your app is not frontmost or not running you handle the notifications by checking the options dictionary passed to the application:didFinishLaunchingWithOptions: of your app delegate for either the UIApplicationLaunchOptionsLocalNotificationKey or UIApplicationLaunchOptionsRemoteNotificationKey key.
You can't use just a NSTimer, because it will not run when your app is closed, however another solution that involves NSTimer is to create a NSTimer for the event date, and then observe UIApplicationDidEnterBackgroundNotification, here if the timer is running, you'll stop the timer, persisting the timer.fireDate (you can save it in NSUserDefault for example), finally observing UIApplicationDidBecomeActiveNotification, you can recreate the timer (substracting the current time with the value that you saved previously) or just fire the action if the event time already passed on.
If you don't want to use a UILocalNotification you can dynamically define your initial view controller (VC) by:
Programmatically loading the VC in didFinishLoadingWithOptions: in AppDelegate
Or subclass your UINavigationController and set your rootController dynamically
Related
I use UILocalNotification to show alerts.
I need to show two alerts 2 hours apart.
Right now, my code displays two different notifications on lock screen.
Assume, alerts/notifs were not touched by user during this period.
Is it possible for me to
Either remove the first shown notification from lock screen
Or update the first notification with the contents of second alert/notifcation.
To my understanding, you cannot modify a UILocalNotification once it has been scheduled.
To dismiss an already fired UILocalNotification, try calling the [[UIApplication sharedApplication] cancelAllLocalNotifications];
and then re-add those that were not yet fired.
Ciao, tout le monde. In my Swift app, there is a UILocalNotification scheduled in a method that will be called after some time when the UIViewController is loaded, and it is repeating every hour (using repeatInterval = .CalendarUnitHour). I store this UILocalNotification instance in a private property in the UIViewController so that I can cancel it later on. When the user presses a button in the UIViewController, the action method will trigger the cancellation of the notification instance, by which I use this code (the code is also used in the deinit of the UIViewController:
if let notification = notificationProperty {
UIApplication.sharedApplication().cancelLocalNotification(notification)
notificationProperty = nil
}
I use a if-let statement here to prevent accidentally canceling a nil UILocalNotification. But even after it canceled the notification, the notification is still showing up every hour.
So why is it not cancelling properly? Thanks!
The notification that the system have is a copy of the one you are holding as a field. You can't cancel the one that you are holding since it is not a notification instance that is in the system.
You can cancel all the existing notifications by cancelAllLocalNotifications or find the one you want to cancel by iterating over all the existing instances by the scheduledLocalNotifications property.
I have some confusion about the above two app delegation method: I read this link, and it shows that the applicationWillEnterForeground will gets called before applicationDIdBecomeActive gets called. I am not sure about the before means.
If I have a social app: in my applicationWillEnterForeground function, I will check if the there is a current user session; in my applicationDIdBecomeActive, I will reload the content on timelineViewController: Thus, if there is no current user session, the timeline cannot be shown. Suppose a user enter the app from background with no current user session, the applicationWillEnterForeground will show a login page to indicate that there is no user, however, will the next-get-called applicationDIdBecomeActive return back to timeline which are not supposed to show?
If I don't want to modify code in my other viewcontroller, or check user session in applicationDIdBecomeActive. Is there any code I can add in applicationWillEnterForeground function to prevent applicationDIdBecomeActive function running?
Another question: I notice that for some app like Facebook, if I press the home button, turning it to background, but immediately turn it back to screen, the app doesn't show a lot of changes; however, if I let it stay in background for like an hour, it will "freeze" for a while (looks like it is refreshing) when I turn it back to foreground. How does the delegation method design to realize that? Is the system decides which delegation method(the above two) to call basing on the time that the app stayed in background?
BTW, I am using swift as the main programming language of iOS
You can't prevent applicationDidBecomeActive from getting called.
You could set an instance variable in applicationWillEnterForeground which is read later to determine the flow your application uses.
To refresh or initiate VC your app after certain interval like Facebook you can do as follows:
In applicationDidEnterBackground
let app = UserDefaults.standard
let date = Date()
app.set(date, forKey: "activeDate")
In applicationWillEnterForeground
let user = UserDefaults.standard
var interval = 0
if let date = user.object(forKey: "activeDate") as? Date {
interval = Int(Date().timeIntervalSince(date)); print ( "AppDeligate: Inactive interval: \(interval)")
}
if interval > 7200 { // 2hr
// Initiate VC OR Refresh data here
}
if you check time interval in applicationDidBecomeActive, then app get initiate or refresh data when yo view notification from swiping down or swipe up for control center. so applicationWillEnterForeground is the best place to do so.
I am using UILocalNotification to let a user know something. However, it's for a note for him and it doesn't require any actions in my application.
I set:
localNotification setAlertAction:nil];
[localNotification setHasAction: NO];
So, it shows only in the top of Home screen. However, if the user clicks on it, my app got launched.
Is there a way to create a local notification, which won't launch my app, when it's tapped?
If the user clicks on a local notification alert, iOS will launch the associated app. This is the expected behaviour of handling local notification. I don't believe you can change it.
I hope there's an expert out there who can help me with this:
I googled it for hours, but could not find any information if there is any way to keep a running NSTimer active when the app is running in the background ?
The problem scenario is I need to set a countdown timer on button click. Time left is shown (02:34:45) as title of button. how do my timer is keep on running when application enters into background or it is suspended . Please help me how i can maintain the time left for alarm, what are the values selected for alarm ( like 2 hours , 3 minutes )
Thanks for any help!
If you're using it for an alarm, your best bet is to use local notifications. That way you won't need to use any of the background processing modes.
When your app is about to enter the background (in applicationWillResignActive or applicationDidEnterBackground on your app delegate), get how much time is left on your timer. Then schedule a local notification for that far in the future:
NSTimeInterval timeUntilNotification = ...
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
localNotif.fireDate = [[NSDate date] dateByAddingTimeInterval:secondsUntilNotification];
localNotif.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
When your app becomes active again, make sure to cancel all your notifications with cancelAllLocalNotifications.