Check if the current time has just passed 12 o'clock in BACKGROUND - ios

I want to check if the current time (24 hours or 12 hours am/pm) has just passed 12 o'clock.
I did something like that in a view, but in this case I checked if it was not yet 12 in the morning:
let date = Date()
let calendar = Calendar.current
let hora = calendar.component(.hour, from: date)
let minutos = calendar.component(.minute, from: date)
if hora < 12 && minutos <= 59 { ... }
I don't know if I explained it well... I was wondering if I can check if the time has passed in AppDelegate, always in background, and execute a function when 12 am has passed. It is possible?

I don't think you will achieve at least in iOS framework.
Apple won't allow you to execute code at a certain time interval in background. Because it's almost similar what some malwares do.
Additional: But if you don't want to execute code in background rather when in your app's foreground then it's possible using timer.

Depending on what you're trying to do, Local Notifications might be of use to you:
https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/SchedulingandHandlingLocalNotifications.html#//apple_ref/doc/uid/TP40008194-CH5-SW1
You can schedule them and they will be delivered to the user even when your app is in the background or not running. The user may then launch your app with a particular action on the notification.

Related

iOS: OperationQueue.schedule(after: Date) that cannot be triggered by date change

Problem
I need to get a callback when at least X amount of time has passed since the date for the callback has been set.
Example 1:
This would have worked great, but it's possible to trigger an execution of the block by setting the date earlier than the correct time right now:
let responseDate = Date().advanced(by: 60) // 1 min
OperationQueue.current.schedule(after: .init(responseDate), {
print("the time is now!") // possible to set the current date 1 min before
}
On the other hand, the solution for getting a current uptime from this answer works great, but it requires timer constantly running to check if we're close to date.
Is it possible to combine these two approaches and somehow "attach" a callback to KERN_BOOTTIME, so that the OS will call my method when the boottime reaches a certain value?
I'm looking as well to alternative engineering solutions that satisfy two criterias:
It should not be possible to trigger the callback by resetting the device date to some arbitrary value in the past
If the device has been put to sleep (e.g. by pressing the on/off side button), the clock should still be "ticking", so that the method will be called back while the app is running in the background.
More details:
Backgrounding / app termination is out of scope
The main point is to prevent a bypass by switching the date backwards in the settings.

Why is my user still able to manipulate the app's time when I'm fetching the time from a server?

I'm trying to fetch the time of my app from the firebase servers using FirebaseFirestore.Timestamp() so that my users are unable to change the device time and fool the app into giving out daily credits sooner than they should get them.
To that end, I have used the following code, but this still returns the time on the device itself.
What I want to achieve is that whenever a button is pressed, getTime() gets called and prints the time as per the Firestore server, and not as per the device on which the app is installed.
My code is as below:
func getTime() {
let time = FirebaseFirestore.Timestamp()
print(time)
// Prints <FIRTimestamp: seconds=1586518212 nanoseconds=6677150>
let RequestedDate = time.dateValue()
print("\(RequestedDate) CHECKHERE")
// Prints 2020-04-10 11:30:12 +0000 CHECKHERE, which is the wrong date I set using the device itself.
let calendar = Calendar.current
let componentsss = calendar.dateComponents([.day, .hour], from: RequestedDate)
print(componentsss)
// Prints the components of the device time.
}

30 Minute Post Delay Not Working With Swift

How do I create my program that will only allow users to post every 30 minutes using swift? This delay time only works if the app is running, besides that it will not work or restart the time running every time the app launches. I need a way to have them wait for only 30 minutes. My code right now is:
DispatchQueue.global(qos: .background) .async {
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1800)) {
UserDefaults.standard.set(false, forKey: "PostTimeLimit")
}
}
Any tips or solutions would be very helpful. Thanks!
Instead of storing whether or not the user is allowed to post, store their last post time and compare it to the current time.

Local Notification every 24 hours in Swift

I'm looking for a way to fire a local notification once every 24 hours from a certain time.
For example:
I have a date picker.
I set the date picker time to 3.02pm.
The next time it's 3.02pm fire a local notification.
Repeat this over and over.
I have managed to successfully call a local notification at a time chosen by a date picker but how do I go about repeating this every 24 hours?
You can repeat a local notification using the repeatInterval property.
To repeat a local notification every day, add this line to your code
myLocalNotification.repeatInterval = NSCalendarUnit.CalendarUnitDay
UILocalNotification is deprecated in iOS 10. Use UNNotificationRequest instead.
myNotificationRequest.trigger = UNTimeIntervalNotificationTrigger(timeInterval: 60*60*24, repeats: false)
In Swift 3
myLocalNotification.repeatInterval = NSCalendar.Unit.day

iOS Local Notifications Testing

In testing my local notifications, for some reason setting the date and time on my iOS device does not trigger my local notification to appear. My notification's fire date is set to be several days in the future. If I do wait a few days then I will see my local notification.
Why am I not seeing my local notification by setting the date and time on my device?
Below is a sample:
playNotification.FireDate = DateTime.Now.AddHours(71.67f);
playNotification.AlertAction = "Alert text";
playNotification.AlertBody = "Alert body";
playNotification.SoundName = UILocalNotification.DefaultSoundName;
playNotification.ApplicationIconBadgeNumber = badgeCount;
UIApplication.SharedApplication.ScheduleLocalNotification(playNotification);
I should mention that I changed 'AddHours' to 'AddSeconds' and tested this by waiting the specified number of seconds, and the notifications fired as expected. But somehow changing the date and time on my device does not.
You need to set the timeZone of the notifications. By default, the timeZone is set according to your location so it does not affect if you manually change your date and time. To achieve this, you need to set the timeZone to systemTimeZone().
Like this:
notification.timeZone = NSTimeZone.systemTimeZone()
I know this is in swift, but I know very little objective-c.
Hope this helps. :)

Resources