Scheduled notifications not working on iOS Flutter - ios

I'm using flutter_local_notifications to schedule notifications at specific times every day.
The user can select different time zones, it works on Android but doesn't work on iOS, as I don't have experience with iOS, I don't know how it handles notifications.
Future<void> _showNotification(
BuildContext? context,
NotificationDetails platformChannelSpecifics,
Prayer prayer,
DateTime dateTime) async {// dateTime is the time in another time zone, and time is the time passed to the zonedScheduled method
var time = _nextInstanceOfPrayer(dateTime);
if (time == null) {
return;
}
await flutterLocalNotificationsPlugin.zonedSchedule(
_getId(time, prayer: prayer.toString()),
prayer.toStr(context!),
_getPrayerText(prayer.toStr(context)),
time,
platformChannelSpecifics,
androidAllowWhileIdle: true,
uiLocalNotificationDateInterpretation:
UILocalNotificationDateInterpretation.absoluteTime,
);}
And this method to get the time:
tzZone.TZDateTime? _nextInstanceOfPrayer(DateTime dateTime) {
final DateTime now = DateTime.now();
//converts time to specific location
tzZone.TZDateTime scheduledDate = tzZone.TZDateTime.from(
dateTime.subtract(now.timeZoneOffset),
tzZone.UTC,
);
if (scheduledDate.toUtc().isBefore(now.toUtc())) {
return null;
}
return scheduledDate;}
What I'm trying is add notification at the time (time) in phone's local time,
for example, the user selects a +5 GMT time zone (5:00PM) and the local time zone is say +2 GMT (2:00PM), I want to add a notification with the local time of (5:00PM +5 GMT) and show it on (5:00 +2 GMT).
I have tried to convert both times to UTC and show the notification on UTC - local time zone (as shown in the second code), the code shows there are pending notifications but when I change the time of the device it doesn't show anything.
Note: when I add a manual time after 5 seconds, it works perfectly
DateTime.now().add(Duration(seconds: 5));

Related

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.
}

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

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.

How to store time and date in plist and compare it with now time iOS 7

I'm trying to develop am iPhone application doing the following tasks:
user stores his movies time and date in plist .
before the movie starts, e.g. 30 minutes before start, the application will give him notification
Now I'm asking for two points:
there is only date field on plist how we can store full time and date at once
how we can keep application compare the current time with movies time on plist even in background
if possible tell me with small example . ( to keep application comparing in background )
example :
Movies.plist
- id
- movie_name
- showing_time
if i have record
id : 1
movie_name: Games B 2
showing_time : 2014-05-22 2:00AM
today is 21-5
i want the application send notification at : tomorrow at 1:00 AM
there is no problem with notification code i know it's like this
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:2];
localNotification.alertBody = msg;
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
the problem is how the application will send the notification in the specific time and date
for your information this things is not only for one record in plist , maybe the user will store 10 movies in different days and time .
another example :
**if i open the application and i go to Save New movies i enter 3 different movies name and showing time
and i click save
all the details will saved in Movies.Plist
and i closed the application . now the application should give me local notification before any of Plist Movies start .
this is whole idea .**
NSDates store the date and the time. For example, the current date and time could be represented as: 2014-05-21 17:19:13 +0000.
As for the background process, it'll be unnecessary. When the user sets the movie time, schedule a notification for 30 minutes before the set time. There won't be any ongoing comparison, the notification will fire when the correct time is hit..
You don't need to store something nor to do some background checks, if you want notify user in specific time - just use UILocalNotification, here's the link to Apple documentation on local notifications UILocalNotification

EKEventEditViewController start date incorrect

I have a EKEvent that I am using with a EKEventEditViewController to add a calendar event in my app. Even though the date is accurate, I get the incorrect time. Can someone help me figure out what I am doing wrong here..
This is the code to generate the event..
EKEvent *addEvent=[EKEvent eventWithEventStore:eventStore];
addEvent.title=event.title;
NSLog(#"Saving Event... %#",[event.date description]);
addEvent.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
addEvent.startDate= event.date;
NSLog(#"Event Date... %#",[addEvent.startDate description]);
addEvent.endDate=[addEvent.startDate dateByAddingTimeInterval:600];
[addEvent setCalendar:[eventStore defaultCalendarForNewEvents]];
addEvent.alarms=[NSArray arrayWithObject:[EKAlarm alarmWithRelativeOffset:-3600]];
My device's timezone is set to 'Port Louis, Mauritius'.
My console output is..
Saving Event... 2012-12-19 20:00:00 +0000
Event Date... 2012-12-19 20:00:00 +0000
But in the EKEventEditViewController, my start date shows Thu,20 Dec 0:00.
This is because the event at "2012-12-19 20:00:00 +0000" (i.e. 8pm GMT) will take place in Maritius at midnight. You're asking the user in Mauritius to add it to their calendar, so it's going to show the event date in the device's local timezone, midnight.
If the event is taking place at 8pm in Mauritius, then your original time is incorrect, because you're saying it's at 8pm GMT. If you're saying that the event is really taking place at 8pm GMT (midnight in Mauritius), then the EKEventEditViewController is just going to show the time according to the local timezone, midnight.
If the user has turned on timezone support, when they pull up the event in the Calendar app, it will show the timezone you specified when you created the even. If they haven't turned on timezone support, it will just show it in the local timezone (adjusting the start time as it should).
Unfortunately, unlike the calendar app, it appears that EKEventEditViewController will not show the timezone but rather displays it in local time, even if the user has turned on timezone support. It does not appear to support this timezone feature, even though it will be correct when they look at their calendar. At least the event is stored with the appropriate timezone information.

iOS - Program method to execute specific code according to time on the phones clock

Is it possible to execute code when a specific time is reached on an iPhone's clock. Would this be able to work after the iPhone is closed (the screen goes black) but the app was left running (the user did not return to the home screen).
For example, would it be possible for a method to be programmed to go off at 1:30:15 PM with no relation to the current time, and are there any restrictions depending on whether the phone is closed or if the app is running in the background?
I found a similar post here How to generate event on a specific time of clock in C#? but this generates a timer based on the current time to run a method later, instead of using the clock without relation to the current time.
I have created a poor way of doing this-
{
time_t rawtime;
struct tm * timeinfo;
time ( &rawtime );
timeinfo = localtime ( &rawtime );
NSLog(#"TESTSTART - TEST START");
// Check
if(timeinfo->tm_hour == 12 && timeinfo->tm_min == 01 && timeinfo->tm_sec == 48)
{
NSLog(#"Run Method");
printf("the time is 12:01:48");
} else {
NSLog(#"ELSE");
[self syncTest];
}
}
This would run a method at 12:1:48, but it is most likely not an acceptable way of doing this. Does anyone know of any better ways to do this and how much strain this way puts on the cpu? Thanks
Use an NSTimer and set the fireDate for whichever date you want the timer to fire on and then catch the notification that it has fired and perform you task.

Resources