AppDelegate: call function only if theres a new notification, how? - ios

I've got a problem since my app, evidently, calls the new notification function every time the app finished launching (in AppDelegate). How do I make my newNotification()-function only being called, when it's used for a new notification and not when the app started launching?
Here's the relevant code from appDelegate (mvc = MainViewController):
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound]) { (granted, error) in
}
let generalCategory = UNNotificationCategory(identifier: "GENERAL",
actions: [],
intentIdentifiers: [],
options: .customDismissAction)
center.setNotificationCategories([generalCategory])
let content = UNMutableNotificationContent()
mvc.newNotification()
let contentText = UserDefaults.standard.string(forKey: "contentText")
content.title = NSString.localizedUserNotificationString(forKey: "The Better Life Challenge", arguments: nil)
content.body = NSString.localizedUserNotificationString(forKey: "\(contentText!)", arguments: nil)
var dateInfo = DateComponents()
dateInfo.hour = 4
dateInfo.minute = 0
let trigger = UNCalendarNotificationTrigger(dateMatching: dateInfo, repeats: true)
let request = UNNotificationRequest(identifier: "TBLC", content: content, trigger: trigger)
center.add(request) { (error : Error?) in
if let theError = error {
print(theError.localizedDescription)
}
Appreciate your help!

You do this in method called, didRecieveRemoteNotification...this method fires when you recieve new notification, not didFinishLaunchingWithOptions..

Related

Receiving notifications from default notification center while app in background

In my app, I'm fetching the content of camera-roll with fetchAssets(with:). To receive change messages, I've registered my observer with the photo library’s register(_:) method. My observer is comforting to the PHPhotoLibraryChangeObserver protocol. So when the library is changing, I should get notified about that. The scenario I want to support is while I'm running my app, I go to background, then open the camera app, take a picture, then go back to my app. Is it possible to get the notification of a change that occurred while my app was in background, when it comes back to foreground?
Yes you can create LocalNotificaion and trigger it when app is going in background and coming back in foreground.
func scheduleNotification(timeInter : TimeInterval) {
let content = UNMutableNotificationContent()
let userActions = "User Actions"
content.title = "Title "
content.body = "Body"
content.sound = UNNotificationSound.init(named:
content.categoryIdentifier = userActions
content.userInfo = ["MID" : RANDOM_ID, "timeInterval" : String(timeInter)]
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: timeInter, repeats: false)
let identifier = String(timeInter)
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
print(request.identifier)
notificationCenter.add(request) { (error) in
if let error = error {
}
}
// let snoozeAction = UNNotificationAction(identifier: "Snooze", title: "Snooze", options: [])
let deleteAction = UNNotificationAction(identifier: "Delete", title: "Delete", options: [.destructive])
let category = UNNotificationCategory(identifier: userActions, actions: [deleteAction], intentIdentifiers: [], options: [])
notificationCenter.setNotificationCategories([category])
}

Rich local notification

How can we show the image or any attachment with local notifications as we used to show in rich notifications ?
I am receiving the silent notification and then changing it in local notification.
Yes, you can show it in the local notification also, you have to trigger local notification after you received silent push , I hope in your slient notification payload all require data is there.
Here is the code snippet
let content = UNMutableNotificationContent()
//Configure notification
content.title = "Notification Title"
content.body = "Notification Body"
content.sound = UNNotificationSound.default()
content.categoryIdentifier = "ImageNotification"
//Attach your image local path here (Document dir path)
let attachment = try! UNNotificationAttachment(identifier: "\(NSDate().timeIntervalSince1970 * 1000)", url: localURL, options: [:])
content.attachments = [attachment]
content.userInfo = ["attachmentType": "Media"]
// Create a trigger for fire a local notification
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 0.2, repeats: false)
let request = UNNotificationRequest(identifier: "\(NSDate().timeIntervalSince1970 * 1000)", content: content, trigger: trigger)
// Configure according to version
if #available(iOS 11.0, *) {
let contactCategory = UNNotificationCategory(identifier: content.categoryIdentifier,
actions: [],
intentIdentifiers: [],
hiddenPreviewsBodyPlaceholder: "",
options: .customDismissAction)
let notificationCenter = UNUserNotificationCenter.current()
notificationCenter.setNotificationCategories([contactCategory])
} else {
// Fallback on earlier versions
let contactCategory = UNNotificationCategory(identifier: content.categoryIdentifier, actions: [], intentIdentifiers: [], options: [])
let notificationCenter = UNUserNotificationCenter.current()
notificationCenter.setNotificationCategories([contactCategory])
}
UNUserNotificationCenter.current().add(request) {[weak self] (error) in
guard error == nil else {
return
}
}
After this implement it would be work fine, If you still facing any issue so please let me know.

How Do I Remove The Notification From The Screen After Being Clicked On

For a few months, I have been working on an app which uses local UNNotifications to achieve the grand goal. I coded this app using Swift 4, therefore aiming it towards distribution on the iOS App Store. As I was testing my app out, I noticed that after I clicked on one of the notification actions (which was not "cancel"), or if I just tapped on the notification in general, the app would open up (which is intended), but the notification would remain on the screen. Is there any possible way to remove the notification from the screen after already tapping on one of the actions programmatically? Below is the code where I schedule the notification:
let action1 = UNNotificationAction(identifier: "go", title: "Go", options: [.foreground])
let action2 = UNNotificationAction(identifier: "cancel", title: "Cancel", options: [.destructive])
let actionsCategory = UNNotificationCategory(identifier: "actions.category", actions: [action1, action2], intentIdentifiers: [], options: [])
UNUserNotificationCenter.current().setNotificationCategories([actionsCategory])
//Queue the notification alert
let content = UNMutableNotificationContent()
content.body = "Interesting day notification!"
content.sound = UNNotificationSound.default()
content.setValue(true, forKey: "shouldAlwaysAlertWhileAppIsForeground")
content.categoryIdentifier = "actions.category"
// if (pinNumber.text) != nil{
// }
content.userInfo = ["Name": namePerson.text ?? "", "Pin": Int(pinNumber.text ?? "") != nil ? pinNumber.text! : ""]
//trigger
let triggerDate = Calendar.current.dateComponents([.year,.month,.day,.hour,.minute], from: datePicker.date)
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDate, repeats: false)
//scheduling
let identifier = id // set same id as task
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
center.add(request, withCompletionHandler: {(error) in
if let error = error{
print(error)
}else{
print("saved alert")
}
})
I don't see anything in your code that would cause that behavior. This sounds to me like either an iOS bug, or there is something weird about the notification permissions/settings of the particular device (or simulator) for your app. Go into the notifications sections of the Settings app and see what the settings are for your app.

Swift: Local Notifications not popping up, although request / scheduled seems to works - no errors

I am trying to learn how to use local notifications and currently I am just trying to let a notification pop up when a certain time has passed (for the sake of learning just 5 seconds).
I register the notification in this function, which is used at the end of an onBoarding screen:
func registerNotification() {
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in
if granted {
print("Granted.")
} else {
print("Not granted.")
}
}
}
Now to test the notification I just add the function set() to a button:
set() {
let center = UNUserNotificationCenter.current()
let content = UNMutableNotificationContent()
content.title = "Test Notification"
content.body = "It works!"
content.categoryIdentifier = "alarm"
content.userInfo = ["customData": "fizzbuzz"]
content.sound = UNNotificationSound.default()
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
center.add(request)
}
But when the button is pressed and 5 seconds passed, no notification is shown, but also no error in Xcode, so I suppose this should all work?
What am I missing here? As far as I understand from various sources on the net this is the easiest way to display a local notification?
So to register a UserNotification and call the function at an appropriate
place:
func registerNotification() {
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in
if granted {
print("Granted.")
} else {
print("Not granted.")
}
}
}
This functions sets a notification with a time interval of 5 seconds. When the app is closed the notification will be displayed:
set() {
let center = UNUserNotificationCenter.current()
let content = UNMutableNotificationContent()
content.title = "Test Notification"
content.body = "It works!"
content.categoryIdentifier = "alarm"
content.userInfo = ["customData": "fizzbuzz"]
content.sound = UNNotificationSound.default()
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
center.add(request)
}

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?

Resources