I am trying to add a reminder to an iphone with my app. I can add the reminder with an alarm that will ring at the specified time but it wont show up as a reminder in the phones pull down list like adding a reminder in siri does.
here is the code I have so far:
public void AddReminder()
{
EKReminder reminder = EKReminder.Create(eventStore);
reminder.Title = "Do something awesome!";
// an error for the reminders and calendars
NSError e = new NSError();
// an alarm time
EKAlarm timeToRing = new EKAlarm();
timeToRing.AbsoluteDate = NSDate.Now.AddSeconds(61);
reminder.AddAlarm(timeToRing);
reminder.Notes = "do something noteworthy";
//reminder.Calendar = calendar;
reminder.Calendar = eventStore.DefaultCalendarForNewReminders;
eventStore.SaveReminder(reminder, true, out e);
}
I have a button the the main page of the form that will call this function. And I have all of the setup for the event store to get the permission and so forth.
Related
I'm working on a Xamarion iOS app. I want to display a local notification when an event occurs in my app, Like Outlook does when an email is received.
I'm using the following code, after having received the right to send notification from the user, of course:
var content = new UNMutableNotificationContent();
if (!string.IsNullOrWhiteSpace(value: mySoundFile))
{
content.Sound = UNNotificationSound.GetCriticalSound(mySoundFile);
}
if (!string.IsNullOrEmpty(myChannelDescription))
{
content.ThreadIdentifier = myChannelDescription;
}
content.Title = "MyTitle";
content.Body = "MyText";
var trigger = UNTimeIntervalNotificationTrigger.CreateTrigger(0.1, false);
var request = UNNotificationRequest.FromIdentifier(notification.Id.ToString(), content, trigger);
var center = UNUserNotificationCenter.Current;
center.AddNotificationRequest(request, null);
But the notification is not displayed.
Any help appreciated.
The reason for not displaying the notification could be several things. Try the following solutions:
Make sure that the application has the required rights to send notifications and that the user has enabled them.
Check if the sound file is valid and located in the application package. It may also be necessary to add it to the Info.plist file.
Check if the thread identifier is valid and not repeatable.
Check if the trigger time is valid. Setting 0.1 seconds is very short and may not be enough to display the notification.
If the above solutions do not work, it is worth using debugging tools to more closely examine why the notification is not displayed.
On iOS, you must request permission to use notifications before attempting to schedule them. Just like this, you can try to check if the following code is added to your project:
UNUserNotificationCenter.Current.RequestAuthorization(UNAuthorizationOptions.Alert, (approved, err) =>
{
...
});
You can change your AddNotificationRequest as follows to see if there is an error in the notification:
center.AddNotificationRequest(request, (err) =>
{
if (err != null)
{
throw new Exception($"Failed to schedule notification: {err}");
}
});
For more details, you can refer to the following documents to check some permission issues:
Enhanced User Notifications in Xamarin.iOS | Microsoft
Asking permission to use notifications | Apple Developer
UpDate: If your app is in the foreground. You could try implementing the delegate userNotificationCenter(_:willPresent:withCompletionHandler:) which will be called when a notification arrives while the app is in the foreground. Refer to the following code:
UNUserNotificationCenter.Current.Delegate = new TestDelegate();
public class TestDelegate: UNUserNotificationCenterDelegate
{
public override void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action<UNNotificationPresentationOptions> completionHandler)
{
completionHandler(UNNotificationPresentationOptions.Alert);
}
}
Since UILocalNotification was deprecated in iOS10, I'm having trouble understanding how to update the following code to the UNNotificationRequest framework. Im basically letting a user schedule a daily notification at a time of their choosing. For example, if they want to get a notification everyday at 11:00AM. The below code works for iOS versions below iOS10 but since UILocalNotification is deprecated, it no longer works. Any help is greatly appreciated.
let notification = UILocalNotification()
notification.fireDate = fixedNotificationDate(datePicker.date)
notification.alertBody = "Your daily alert is ready for you!"
notification.timeZone = TimeZone.current
notification.repeatInterval = NSCalendar.Unit.day
notification.applicationIconBadgeNumber = 1
UIApplication.shared.scheduleLocalNotification(notification)
You can use UNCalendarNotificationTrigger for creating a notification that fires repeatedly using UNUserNotificationCenter. You can do something like this. The trick is to only have the time component in the Trigger date.
let center = UNUserNotificationCenter.current()
let content = UNMutableNotificationContent()
content.title = "Attention!"
content.body = "Your daily alert is ready for you!"
content.sound = UNNotificationSound.default
let identifier = "com.yourdomain.notificationIdentifier"
var triggerDate = DateComponents()
triggerDate.hour = 18
triggerDate.minute = 30
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDate, repeats: true)
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
center.add(request, withCompletionHandler: { (error) in
if let error = error {
// Something went wrong
print("Error : \(error.localizedDescription)")
} else {
// Something went right
print("Success")
}
})
You can't schedule a notification that repeats daily. That notification would happen only once, and then you would have to schedule it again, which means that you would have to open the app again.
There is BGTask API introduces in iOS 13, that can be used to perform some background tasks, but not this one, you can not schedule the task for specific time.This API last only works when app is in the background, not when it is killed. You can only set some time interval that the system will use as a guiding point to determine when to perform you app's code. But in my experience it is pretty unreliable.
The only way to achieve this is to implement remote push notifications. Push notifications also work even when the app is killed.
I am working on alarm application, i need to schedule alarm on specific time, I use scheduleLocalNotification for scheduling alarms and it's working fine as i want. BUT I need to run to a request to my API server before triggering alarm. In that request I want to check some parameters returning from API server, If that satisfies some condition.
If any one have a method that run on a particular date - time in swift
Please help me for that
func addAlarm (newAlarm: Alarm) {
// Create persistent dictionary of data
var alarmDictionary = NSUserDefaults.standardUserDefaults().dictionaryForKey(ALARMS_KEY) ?? Dictionary()
// Copy alarm object into persistent data
alarmDictionary[newAlarm.UUID] = newAlarm.toDictionary()
// Save or overwrite data
NSUserDefaults.standardUserDefaults().setObject(alarmDictionary, forKey: ALARMS_KEY)
scheduleNotification(newAlarm, category: "ALARM_CATEGORY")
scheduleNotification(newAlarm, category: "FOLLOWUP_CATEGORY")
}
/* NOTIFICATION FUNCTIONS */
func scheduleNotification (alarm: Alarm, category: String) {
let notification = UILocalNotification()
notification.category = category
notification.repeatInterval = NSCalendarUnit.Day
switch category {
case "ALARM_CATEGORY":
notification.userInfo = ["UUID": alarm.UUID]
notification.alertBody = "Time to wake up!"
notification.fireDate = alarm.wakeup
notification.timeZone = NSTimeZone.localTimeZone()
notification.soundName = "loud_alarm.caf"
break
case "FOLLOWUP_CATEGORY":
notification.userInfo = ["UUID": alarm.followupID]
notification.alertBody = "Did you arrive yet?"
notification.fireDate = alarm.arrival
notification.timeZone = NSTimeZone.localTimeZone()
notification.soundName = UILocalNotificationDefaultSoundName
break
default:
print("ERROR SCHEDULING NOTIFICATION")
return
}
print("Notification=\(notification)")
// For debugging purposes
if alarm.isActive {
UIApplication.sharedApplication().scheduleLocalNotification(notification)
}
}
Waking up an app through a local notification is not possible, this is available only for remote notifications. According to the Notification Programming Guide:
When a remote notification arrives, the system handles user
interactions normally when the app is in the background. It also
delivers the notification payload to the
application:didReceiveRemoteNotification:fetchCompletionHandler:
method of the app delegate in iOS and tvOS
But there is still a catch; even then it is not guaranteed that the app will be launched since, according to didReceiveRemoteNotification:fetchCompletionHandler: documentation:
However, the system does not automatically launch your app if the user
has force-quit it. In that situation, the user must relaunch your app
or restart the device before the system attempts to launch your app
automatically again.
I don't think there is a guaranteed way to schedule a block for execution in some later moment, independently from the state of the app at that time. Depending on your specific requirements and frequency, you could perhaps register for the fetch background mode and implement application:performFetchWithCompletionHandler: to opportunistically fetch and validate server data. Last note: make sure that you are a responsible background app (from my experience Apple takes this requirement seriously)
I believe I am using cancelLocalNotification improperly.
I have a recurring notification that runs conditionally, which was created using the following code:
let localNotification: UILocalNotification = UILocalNotification()
localNotification.alertAction = "Inactive Membership"
localNotification.alertBody = "Our system has detected that your membership is inactive..."
localNotification.fireDate = NSDate(timeIntervalSinceNow: 5)
localNotification.repeatInterval = .Minute
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
This notification successfully runs every single minute (for testing purposes). Obviously, I'd like a way to conditionally remove these notifications, so I've tried to use cancelLocalNotification to do so.
How I think cancelLocalNotification works
My intuition is that cancelLocalNotification will remove all the notifications for that specific notification object. Here's how I'm using it.
UIApplication.sharedApplication().cancelLocalNotification(localNotification)
What actually happens
I've stepped through my function and verified that the cancelLocalNotification code does get called. However, I keep getting my notification every minute.
My Question
How do I properly cancel a UILocalNotification that has been scheduled?
Full code:
static func evaluateMemberStatusNotifications() {
let userDefaults = Global.app.userDefaults
let localNotification: UILocalNotification = UILocalNotification()
print("evaluating profile notifications")
// is the user active? if so no notification
let isActive : Bool = userDefaults.valueForKey("ActiveMember") as! Bool // false == inactive
print("is the user active?")
if !isActive {
print("user is not active, checking if notification code has run")
// if userDefaults is nil for this value, we'll set it to false
if (userDefaults.valueForKey("ProfileNotificationHasRun") == nil) {
print("nil! setting ProfileNotificationHasRun to 'false'")
userDefaults.setValue(false, forKey: "ProfileNotificationHasRun")
}
let statusNotification = userDefaults.valueForKey("ProfileNotificationHasRun") as! Bool
// has this code been run? If not run it
if !statusNotification {
print("running notification code")
// we schedule a notification
localNotification.alertAction = "Inactive Membership"
localNotification.alertBody = "Our system has detected that your membership is inactive."
localNotification.fireDate = NSDate(timeIntervalSinceNow: 5)
localNotification.category = "status"
localNotification.repeatInterval = .Day
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
userDefaults.setValue(true, forKey: "ProfileNotificationHasRun")
} else {
print("notification code has already run, time interval has been set")
}
} else {
print("member is active, remove Inactive notification")
// if the member is active, we remove the notification so the user doesn't
// keep getting notified
UIApplication.sharedApplication().cancelLocalNotification(localNotification)
userDefaults.setValue(false, forKey: "ProfileNotificationHasRun")
}
}
You're creating a new UILocalNotification (line 3 of your gist) and then cancelling it. That new notification was never scheduled. You need to get the existing, scheduled notification object and cancel that.
You can access your existing, scheduled notifications through the UIApplication.sharedApplication().scheduledLocalNotifications array.
Or you could just cancel all scheduled local notifications by calling UIApplication.sharedApplication().cancelAllLocalNotifications().
UPDATE
Each call to evaluateMemberStatusNotifications creates a new instance of UILocalNotification, then (depending on the ActiveMember value) either configures and schedules that new notification, or tries to delete the new (unscheduled) notification.
Instead, you should just create a new notification in the !isActive branch where you want to schedule it.
In the other branch, you need to find the existing notification in the scheduledLocalNotifications array and (if you find it) cancel that existing notification.
Since you say you have other notifications that you don't want to mess with, you should use the userInfo property of the notification to identify it. For example, when configuring the notification before scheduling it:
localNotification.alertAction = "Inactive Membership"
localNotification.alertBody = "Our system has detected that your membership is inactive. You may continue using this application though some features may not be available to you until your membership is reinstated."
localNotification.fireDate = NSDate(timeIntervalSinceNow: 5)
localNotification.category = "status"
localNotification.repeatInterval = .Day
// *** NEW
localNotification.userInfo = [ "cause": "inactiveMembership"]
And when you want to cancel the existing notification:
let maybeNotification = UIApplication.sharedApplication().scheduledLocalNotifications?.filter({ (notification: UILocalNotification) -> Bool in
notification.userInfo?["cause"] as? String == "inactiveMembership"
}).first
if let notification = maybeNotification {
UIApplication.sharedApplication().cancelLocalNotification(notification)
}
I used the following code to `private static void CreateAlarm(double time)
{
var alarm = new Alarm("MyAlarm")
{
Content = "You have a meeting with your team now.",
Sound = new Uri("/Sounds/preview.mp3", UriKind.Relative),
BeginTime = DateTime.Now.AddSeconds(time)
};
ScheduledActionService.Add(alarm);
}`
to create an alarm clock for Windows Phone 7.As Alarm starts ,it gives "snooze" and "dismiss" option.When I click the snooze button,it takes me to my first page but I want to set snooze for 9min always.Someone told me that we cannot control snooze button but I think its very simple and there would be someway to do it.
You cant do this. However, in Mango (WP7.5) the snooze is already 9 minutes.