Trying to fire UILocalNotification not working - ios

I'm using the code below to create a notification, but somehow it's not firing. I really just want it to trigger as I open one certain view controller, but nothing is firing so far. What is the problem with my code?
func notify() {
let notification = UILocalNotification()
notification.fireDate = Date()
notification.repeatInterval = .minute
notification.alertBody = "The alert body"
notification.alertAction = "enter text here"
UIApplication.shared.scheduleLocalNotification(notification)
}
I also have this line in the app delegate:
application.registerUserNotificationSettings(UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil))

One reason I believe this would fail is because notification.fireDate = Date() will set the fireDate to the current time, which will be in the past by the time the (separate) process managing UserNotifications is alerted that you want to fire a notification. Consider moving to UNNotifications

I changed the firing date to a certain time in the future (it was 6 PM where I changed it to 06:03 by using calendarComponents, and then it seemed to work. The notification got fired :)

Related

UNNotificationRequest to send local notification daily at a specific time

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.

ANCS : what is the concept of PositiveAction?

I'm trying to work with the Apple Notification Center Service to make interactions between a Bluetooth peripheral and an iOS device.
In the documentation Apple mention the 2 notification actions: EventFlagPositiveAction and EventFlagNegativeAction…
So far, the Negative part works: once the notification is transmitted to the peripheral, this latter one can trigger the negative action, resulting dismissal of the notification.
But I cannot trigger the Positive side of the force... My Notification has a single action button and I want this button to be considered as the positive action... But I don't know how it works: is it implicit ? do all actions have the positive flag ? or should I do something to make it recognized as the positive one ?
This is more a conceptual question about ACNS, but for information, below is the code I'm using:
1st to register for the local notification in the AppDelegate:
let notificationTypes = UIUserNotificationType.Alert.union(UIUserNotificationType.Sound).union(UIUserNotificationType.Badge)
let launchAction = UIMutableUserNotificationAction()
launchAction.identifier = "LAUNCH_ACTION"
launchAction.title = "OK"
launchAction.activationMode = UIUserNotificationActivationMode.Foreground
launchAction.destructive = false
/* this is this UIMutableUserNotificationAction that I want to trigger from my external device, and should be considered as the famous positive action I am looking for */
let notificationCategory = UIMutableUserNotificationCategory()
notificationCategory.identifier = "LAUNCH_NOTIFICATION"
notificationCategory.setActions([launchAction], forContext: .Minimal)
application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: notificationTypes, categories: NSSet(array:[notificationCategory]) as? Set<UIUserNotificationCategory>))
And 2nd, later to create a notification
let localNotification:UILocalNotification = UILocalNotification()
localNotification.alertAction = "Hello"
localNotification.alertBody = "World"
localNotification.fireDate = NSDate(timeIntervalSinceNow: 5)
localNotification.soundName = UILocalNotificationDefaultSoundName
localNotification.hasAction = true
localNotification.category = "LAUNCH_NOTIFICATION"
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
Ok, so then I have had the answer for my question from Apple developer technical Support.
Posting this here, hopefully this will help someone else:
the first thing to understand is that “Positive actions are only wired up for telephony related notifications (incoming call, missed call, and voicemail). There is currently no way to pass through the positive action for an app alert.
Things are easier to understand now…

Repeat Interval is not working correctly for local notifications (Swift) [duplicate]

This question already has answers here:
How to show Notification in Swift more than once?
(2 answers)
Closed 7 years ago.
My repeat interval is going off about every 60 seconds no matter what I have it set to. Here is my code. Also whenever it repeats every 60 seconds, two notifications go off at once. To clarify what I am trying to do, I want my notification to go off once a week to remind the players of my sprite kit game to come back and play.
let localNotification = UILocalNotification() // Creating an instance of the notification.
localNotification.alertTitle = "Title"
localNotification.alertBody = "Body"
localNotification.alertAction = "Launch"
localNotification.repeatInterval = .Hour
localNotification.timeZone = NSTimeZone.defaultTimeZone()
localNotification.soundName = UILocalNotificationDefaultSoundName // Use the default notification tone/ specify a file in the application bundle
localNotification.applicationIconBadgeNumber = 1 // Badge number to set on the application Icon.
localNotification.fireDate = NSDate(timeIntervalSinceNow: 5)
UIApplication.sharedApplication().scheduleLocalNotification(localNotification) // Scheduling the notification.
What happened was that you tried to schedule a invalid repeatInterval unit. The minimum repeat interval unit it is .Minute. So What happened when you tried a valid unit it worked but you were still receiving the first schedule notification that was set by default to repeat every minute.
Just cancel all previous schedule notifications and schedule a new one.
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplication_Class/index.html#//apple_ref/occ/instm/UIApplication/cancelAllLocalNotifications

ios swift local notifications no sound

Iam trying to make a regular UILocalNotification with default sound
this is my function
func makeLocalNotificationForNow(str : String , id : String)
{
let notification = UILocalNotification()
notification.alertBody = str // text that will be displayed in the notification
notification.alertAction = "open" // text that is displayed after "slide to..." on the lock screen - defaults to "slide to view"
notification.fireDate = NSDate(timeIntervalSinceNow: 5) // todo item due date (when notification will be fired)
notification.soundName = UILocalNotificationDefaultSoundName // play default sound
UIApplication.sharedApplication().scheduleLocalNotification(notification)
}
in my didFinishLaunchingWithOptions function I put
let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge , .Sound], categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
Note : I also use parse push notifications
when I make the notification , it appears but without an alert or sound (I need to swipe the from top to see the notification
what's wrong ?!
as far as i know notifications only make a sound when the app is in the background, meaning quit you app, put your phone on locked mode and send a notification through the parse website, then you should hear the sound, if not, check the settings on the app you're making to see if sound alerts are enabled, and last resource, check that your phone is not on vibrate only
it was a stupid mistake , the problem was my phone , I changed the phone and it all worked

How do I properly use cancelLocalNotification?

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

Resources