Local Notification not working in iOS 10.3.1 - ios

I have an app which will send a local notification for specific location change when the app is in background or not running. Im using region monitoring to get location changes and create notification request if needed. My problem is the notification is not working in iOS 10 where as it is working fine in iOS 11 & 12. Below is the code to create a notification request.
func getRequest() {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]) { (granted, error) in
if granted {
DispatchQueue.main.async {
self.scheduleNotification()
}
}
}
}
func scheduleNotification() {
let timeTrigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 15.0, repeats: false)
let center = UNUserNotificationCenter.current()
let content = UNMutableNotificationContent.init()
content.title = "Notification works!"
content.sound = UNNotificationSound.default
let request = UNNotificationRequest.init(identifier: "LocalNotification", content: content, trigger: timeTrigger)
center.add(request) { (error) in
print(error?.localizedDescription ?? "No Error")
}
}
Is there anything I miss here that must be included for iOS 10? Why is it not working in iOS 10 alone?

After spending some hours on stack over flow, thanks to this answer in another post. We should also mention the content.body. This should not be empty in iOS 10. For some reason the notification works without body in iOS 11 & 12.

Related

Calling removeAllPendingNotificationRequests() in applicationWillTerminate not working on iPad

I set up a dummy project to reproduce the issue I'm seeing. In my ContentView, I schedule some repeating notifications.
struct ContentView: View {
var body: some View {
VStack {
Button("Schedule notifications") {
let content = UNMutableNotificationContent()
content.title = "Title"
content.body = "body"
content.sound = UNNotificationSound.default
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 60, repeats: true)
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
}
Button("Request Permission") {
let current = UNUserNotificationCenter.current()
current.requestAuthorization(
options: [.sound, .alert],
completionHandler: { completed, wrappedError in
guard let error = wrappedError else {
return
}
})
}
}
}
}
Then in my AppDelegate, I attempt to cancel those repeating notifications before the app terminates.
func applicationWillTerminate(_ application: UIApplication) {
UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
print("============== removing all notifications")
}
What I'm finding is that my scheduled notifications are still delivered, even though I can see my print statement in the Xcode console. But if I run the same test on an iPhone, my notification is not delivered, as expected.
Am I doing something wrong, or is this a bug? I'm using 13.4.1 on iPad, and 13.3.1 on iOS
I am also facing the same problem. Found out that applicationWillTerminate method has approximately five seconds to perform any tasks and return. And removeAllPendingNotificationRequests returns immediatly but removes scheduled notification asynchronously in secondary thread.
I think 5 seconds are more than necessary to clear notification.

iOS local notifications showing in Simulator but not device

I have a Firebase listener that launches a notification when it fires like so:
chat.ref.child("lastMessage").observe(.value, with: { snapshot in
let lastMessage = snapshot.value as! String
chat.lastMessage = lastMessage
self.tableView.reloadData()
chat.lastMessageText = "New Message!"
let content = UNMutableNotificationContent()
content.title = "You have a new Message!"
content.subtitle = chat.title
content.body = chat.lastMessage
content.badge = 1
let trigger = UNTimeIntervalNotificationTrigger (timeInterval: 1, repeats: false)
let request = UNNotificationRequest(identifier: "timerDone", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
}
Also have:
override func viewDidLoad() {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge], completionHandler: {didAllow, error in })
}
The problem I am having is, although the HomeScreen notifications are working in the simulator, they are not showing on the device. All permissions are granted on the device. Reading some questions here I found some answers that suggested I add the following in the app delegate:
application.beginBackgroundTask(withName: "showNotification", expirationHandler: nil)
but this actually disabled notifications on the simulator too. The notifications did work on the device before but stopped very suddenly. Any thoughts?

Is UNUserNotification have option to show notification only on apple watch?

I am developing apple watch app which have the functionality to show a notification to User after every 2 or 3 or 5 min.
I have achieved this functionality through iOS UNUserNotification and its works perfectly.
But what I want here is User can see all notifications only on Apple watch not on iPhone.
Right now it's showing on both iPhone & Apple watch.
Is it possible to show notifications only on the Apple watch?
I have implemented the below code for UserNotification.
func scheduleNotification(at date: Date) {
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: (1*60), repeats: true)
let content = UNMutableNotificationContent()
content.title = "Test Reminder"
content.body = "Show More detail in Body!"
content.sound = UNNotificationSound.default()
content.categoryIdentifier = "myCategory"
if let path = Bundle.main.path(forResource: "logo", ofType: "png") {
let url = URL(fileURLWithPath: path)
do {
let attachment = try UNNotificationAttachment(identifier: "logo", url: url, options: nil)
content.attachments = [attachment]
} catch {
print("The attachment was not loaded.")
}
}
let request = UNNotificationRequest(identifier: "textNotification", content: content, trigger: trigger)
UNUserNotificationCenter.current().delegate = self
UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
UNUserNotificationCenter.current().add(request) {(error) in
if let error = error {
print("Uh oh! We had an error: \(error)")
}
}
}
Thanks in Advance!
No, this is not possible.
The system decides automatically where to show the notifications, developers have no control over this.
The notification will be displayed on the Apple Watch if the paired iPhone is locked and the Watch is worn by the user. In any other case, the notification will be displayed on the iPhone.
See Notifications on your Apple Watch
Yes, you can make the notification appear only on watch if you will trigger the Local notification from WatchKit Extension.
Please see the corresponding documentation: https://developer.apple.com/documentation/watchkit/notifications/taking_advantage_of_notification_forwarding?changes=__5

Apple watch local notification not working when the watch isn't worn

We are using the UNUserNotification framework provided by WatchOS 3.0 to create local notification to notify user at a predefined moment. However, the notification is not shown when the watch is not being worn on the wrist. It does work well when someone is wearing it.
We cannot find this description on any documentation. Is that normal? If yes, how to help the user to avoiding missing some notifs ?
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in
// Enable or disable features based on authorization.
if granted {
let content = UNMutableNotificationContent()
content.title = title
content.body = body
content.sound = UNNotificationSound.default()
content.userInfo = userInfo
let trigger = UNTimeIntervalNotificationTrigger.init(
timeInterval: interval,
repeats: false)
let identifier = stringWithUUID()
let request = UNNotificationRequest.init(
identifier: identifier,
content: content,
trigger: trigger
)
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
completion?(true, nil)
}
else {
completion?(false, error)
}
}
This is normal, Apple Watch automatically locks when you take it off your wrist and notifications go to your iPhone instead.

How to display a message on top?

I'm new to WatchKit development. I would like to display a message regardless of what app is currently being used or whether the watch is active or not, like how the built-in Timer app shows the label "Timer Done". The user should then be able to click an "OK" button and dismiss the message.
I have tried using both alerts and modal views, but showing them programmatically still requires my app to be active. Using the notifications system is not a viable solution because that would rely on an iPhone.
I've been stuck on this for many hours, any insight would be helpful, thanks.
You need to ask permission in your iOS App first:
UNUserNotificationCenter.current().requestAuthorization(options: [.alert,.badge,.sound])
{ (granted, error) in
if !granted
{
print("User did not give permissions to send notitications...")
}
}
Then in your watchOS App you can create a notification for some time in the future, make sure you give it a UUID (this may be a bug in watchOS3):
let content: UNMutableNotificationContent = UNMutableNotificationContent()
content.title = "Title"
content.subtitle = "Subtitle"
content.body = "message"
content.sound = UNNotificationSound.default()
content.categoryIdentifier = "aCategory"
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: duration, repeats: false)
let id: String = WatchNotify.getUUID()
let request = UNNotificationRequest.init(identifier: id,
content: content,
trigger: trigger)
UNUserNotificationCenter.current().add(request)
{
(error) in // ...
}
....
class func getUUID() -> String
{
let uuidObj = CFUUIDCreate(nil)
let uuidString = CFUUIDCreateString(nil, uuidObj)!
return uuidString as String
}

Resources