Swift Date Picker date - ios

How can I make something happen in a specific hour in the Date Picker?
I am just learning Swift I would appreciate any orientation. Thank you!
I can grab the time the user select when he click a button, but how can I make something happen when we arrive to that time and the app is active?
(I am not looking for localNotifications, I want something happen WHEN THAT APP IS ACTIVE)
I put this inside ViewController.swift > class ViewControler: UIViewController:
let now = NSDate()
#IBAction func button(sender: AnyObject) {
// grab the selected date from the date picker
let wakeUpTime = datePicker.date
}

If you want something to happen when the app is active, do the following:
Grab the user-selected date from the picker. Save it to user
defaults.
Calculate the number of seconds from now until the user-specified
date:
let seconds = userDate.timeIntervalSinceReferenceDate() -
NSDate().timeIntervalSinceReferenceDate()
Create a one-shot timer that fires in that many seconds.
Done.
If you want your app to work correctly if the user switches your app to the background and then back, kill the timer on the way to the background.
When you get launched or return to the foreground, read the saved date, and repeat the above. (After checking to see if the saved date has already passed.)

Related

Background refresh data

I'm making an app that displays text from an array and I need to background refresh the text depending on the date at midnight. How can I background fetch this at exactly 12:00am so it shows the new text? I turned on background fetching on the file and it refreshes at about 2pm or 3pm the next day but I don't know the code to do this at exactly midnight, I'm new to all this.

Update every day (my code working?)

I want to update the the code inside viewDidLoad() every new day - even if the app is not running - closed or in background.
let Date = NSDate()
let Calendar = NSCalendar.currentCalendar()
var Days = 20
var Hours = 5
var Difference = 0
override func viewDidLoad() {
let FireDate = userCalendar.components(NSCalendarUnit.Hour, fromDate: Date)
if (FireDate.hour == 7) {
days--
Difference = (Days / Hours)
}
}
This code does not work how I want it to.
If that code is run at 7 then the check will succeed. That is, 7 on the device it's running on, considering the users timezone settings.
This code won't automatically run each day. You don't show where the code is but nothing will automatically run an iOS app at a set time each day. Possibly you could send a silent push as a trigger but you should really plan for the app to work when the user opens it instead of autonomously. Any time sensitive offline processing should be done by a server...
You could also look at using func applicationSignificantTimeChange(_ application: UIApplication) so that the application is told when the day has changed, in combination with your general processing in application:didFinishLaunchingWithOptions:.
viewDidLoad is called once and once only: When your view controller gets loaded. Trying to call this multiple times is going to get you into trouble.
Usually you set up some things in viewDidLoad (things that should be set up exactly once), and others in viewDidAppear or viewWillAppear (things that might be set up in different ways if your view appears multiple times).
Create a new method that does your setup that would usually be in viewDidAppear or viewWillAppear, making sure there are no problems if this code is called multiple times. Change viewDidAppear or viewWillAppear to call this method. Then in viewDidLoad create a timer that will call this at the right time, and in dealloc invalidate the timer.
If your app is in the background, even if the view is not loaded, there is no need for this to happen. Nobody will notice anyway. The timer will be called immediately when your app comes to the foreground (if it was due to be called), and if your app was closed, viewDidAppear is going to be called.

Why can't I cancel a repeating UILocalNotification?

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.

NSTimer UIDatePicker dealing with only time

In an iOS app I have a view with a UIDatePicker which only selects time (hour, minute, and am/pm). Then based upon the time of the UIDatePicker, sets an NSTimer. This timer is supposed to launch daily at the time specified on the UIDatePicker. Is there anyway to set up an NSTimer with a specified hour, minute, then either am or pm without having to take the date into consideration? Being able to do this would allow me to remove a huge amount of conditional statements regarding month's, day's and years.
If this isn't possible is there a recommended approach?
Thanks!
Check out UILocalNotification:
https://developer.apple.com/library/ios/documentation/iPhone/Reference/UILocalNotification_Class/

Confusion about applicationDidBecomeActive and applicationWillEnterForeground

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.

Resources