Is there a way a widget can catch UNUserNotificationCenterDelegate? SWIFT - swift

Please help
UserNotifications
Import UserNotifications
put this in viewDidLoad
func setupNotif() {
UNUserNotificationCenter.current().requestAuthorization(options [.alert,.sound]) {
(granted, error) in
}
let notificationContent = UNMutableNotificationContent()
notificationContent.title = "Push Invitation"
notificationContent.subtitle = "Push subtitle"
notificationContent.body = "Please check notif"
notificationContent.sound = .default
notificationContent.categoryIdentifier = categoryIdentifier
let notificationTrigger = UNTimeIntervalNotificationTrigger.init(timeInterval: timeInterval, repeats: false)
let notificationRequest = UNNotificationRequest.init(identifier: "SampleNotif", content: notificationContent, trigger: notificationTrigger)
UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
UNUserNotificationCenter.current().add(notificationRequest) {(error) in if (error != nil) {} else { }}
}
this is the delegate for UUNotification center
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
}

**My answer, there is no way to do that.. as per apple.. i think this question might pop up in the future..
#available(iOS 10.0, *)
open class UNUserNotificationCenter : NSObject {
// The delegate can only be set from an application
weak open var delegate: UNUserNotificationCenterDelegate?

Related

Why my didRecive and willPresent aren’t working(action buttons do nothing)?

I want to make an actionable notification. It appears only if my app is closed. When I press action button nothing happening
My class of notification
class Notfication : NSObject, UNUserNotificationCenterDelegate {
func request(answer : rope, RopesBas : RopesBase){
let taskCategory = UNNotificationCategory(identifier: "task", actions: [UNNotificationAction(identifier: "done", title: "Done")], intentIdentifiers: [])
UNUserNotificationCenter.current().setNotificationCategories([taskCategory])
print("0 stage")
let content = UNMutableNotificationContent()
content.title = answer.name
content.sound =
UNNotificationSound.default
content.categoryIdentifier = "task"
content.userInfo=["name" : answer.name]
print("1 stage")
// show this notification five seconds from now
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
print("2 stage")
//UNUserNotificationCenter.current().delegate = self
// choose a random identifier
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
print("3 stage")
// add our notification request
UNUserNotificationCenter.current().add(request){ (error : Error?) in
if let theError = error {
print(theError.localizedDescription)
}
}
print("4 stage")
print(UNUserNotificationCenter.current().delegate)
print("ok")
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
print("5 stage")
let userInfo = response.notification.request.content.userInfo
let id = "dad"
print("6 stage")
print(response.actionIdentifier)
switch response.actionIdentifier {
case "done":
base.ropes.removeAll(where: {$0.name == id})
break
case UNNotificationDefaultActionIdentifier,
UNNotificationDismissActionIdentifier:
break
default :
break
}
print(base.ropes.count)
completionHandler()
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
print("q")
completionHandler([.badge,.banner,.sound,.list])
}
}
I’m declaring this class at sheet view
struct Adding: View {
private let publisher = Notfication()
And using it when I press the button in a sheet view
Button(action: {
RopesDB.ropes.append(rope(name: answer.answer))
publisher.request(answer: RopesDB.ropes.last!, RopesBas: RopesDB)
dismiss()
}, label: {
HStack{
Spacer()
Text(answer.answer)
Spacer()
}
I’ve tried to put delegate into
class AppDelegate: NSObject, UIApplicationDelegate{
internal func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
let center = UNUserNotificationCenter.current()
let options : UNAuthorizationOptions = [.alert, .badge, .sound]
center.requestAuthorization(options: options) { granted, error in
if granted{
UNUserNotificationCenter.current().delegate = Notfication()
}
if let error = error {
print(error.localizedDescription)
}
}
return true
}
//
}
And into the class where it comment
What my mistake?
IDE Swiftplaygrounds(iPad 9, iOS 15.5)
Apple states in its documentation that notifications are only shown when the app is in the background. When the app already is in the foreground, the notification will be directly passed into your app:
https://developer.apple.com/documentation/usernotifications/handling_notifications_and_notification-related_actions
You will need to receive the notification in your delegate's userNotificationCenter(_:willPresent:withCompletionHandler:) method and there your app can decide what to actually do with it. E.g. throw the user to a certain view, show a modal etc.
I found out that this thing can’t work on Playgrounds, I suppose

How to handle UserNotification through widget iOS14 to main app in swift?

I have an iOS app with widget iOS 14 where I send UserNotifications from both sides. On main app side all UNUserNotificationCenterDelegate is working fine. On widget side when I fetched events from calendar then UserNotifications are triggered. When I'm received notification in main-app side and click on it, then didReceive response: UNNotificationResponse delegate or other delegates did not called and also did not called in widget side.
here is my code in Widgets
class NotificationCenter: NSObject, ObservableObject {
#Published var dumbData: UNNotificationResponse?
override init() {
super.init()
UNUserNotificationCenter.current().delegate = self
}
}
extension NotificationCenter: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert, .sound, .badge])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
completionHandler()
}
func userNotificationCenter(_ center: UNUserNotificationCenter, openSettingsFor notification: UNNotification?) {
}
func scheduleNotification(at date: Date, identifierUnic : String, body: String, titles:String) {
UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
let triggerWeekly = Calendar.current.dateComponents([.day, .month, .hour,.minute, .year], from: date)
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerWeekly, repeats: true)
let content = UNMutableNotificationContent()
content.title = titles
content.body = body
content.sound = UNNotificationSound.default
content.categoryIdentifier = "todoList2"
let request = UNNotificationRequest(identifier: identifierUnic, content: content, trigger: trigger)
UNUserNotificationCenter.current().delegate = self
UNUserNotificationCenter.current().add(request) {(error) in
if let error = error {
print(" We had an error: \(error)")
}}
}
}
//and fire in
#ObservedObject var notificationCenter: NotificationCenter
func getTimeline(in context: Context, completion: #escaping (Timeline<Entry>) -> ()) {
eventManager.checkPermission { (eventArray) in
print(eventArray)
if eventArray.count > 0{
for item in eventArray{
notificationCenter.scheduleNotification(at: item.startDate ?? Date(), identifierUnic: item.eventIdentifier ?? "", body: item.title, titles: item.title)
}
}
}
var entries: [SimpleEntry] = []
// Generate a timeline consisting of five entries an hour apart, starting from the current date.
let currentDate = Date()
for hourOffset in 0 ..< 5 {
let entryDate = Calendar.current.date(byAdding: .second, value: hourOffset, to: currentDate)!
let entry = SimpleEntry(date: entryDate)
entries.append(entry)
}
let timeline = Timeline(entries: entries, policy: .atEnd)
completion(timeline)
}
On Main App Side
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
print("userInfo \(userInfo)")
}
What is missing in it?
Is it right way to handle UserNotification on two Targets?
Any other way to do this?
Please let me know?
Thank you
I have a similar situation that I still can't figure out how to do... I have a widget that will display calendar events. How can I refresh the widget when calendar changed? I tried to use notificationCenter but don't know where to put it. What I want to do is that when there is a calendar change, my widget should be reloaded (refresh timeline.)
Thank you for your help.

UserNotifications Extension Service UNNotificationAction didReceive action delegate not getting called.

I am creating Notification Service extension for local notification with UNNotificationAction but on tap of it delegate not getting called.
userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void)
here are my 3 actions
// Define Actions
let actionReadLater = UNNotificationAction(identifier: Notification.Action.readLater, title: "Read Later", options: [])
let actionShowDetails = UNNotificationAction(identifier: Notification.Action.showDetails, title: "Show Details", options: [.foreground])
let actionUnsubscribe = UNNotificationAction(identifier: Notification.Action.unsubscribe, title: "Unsubscribe", options: [.destructive, .authenticationRequired])
// Define Category
let tutorialCategory = UNNotificationCategory(identifier: Notification.Category.tutorial, actions: [actionReadLater, actionShowDetails, actionUnsubscribe], intentIdentifiers: [], options: [])
// Register Category
UNUserNotificationCenter.current().setNotificationCategories([tutorialCategory])
to schedule notification I am using
private func scheduleLocalNotification() {
// Create Notification Content
let notificationContent = UNMutableNotificationContent()
// Configure Notification Content
notificationContent.title = "Cocoacasts"
notificationContent.subtitle = "Local Notifications"
notificationContent.body = "In this tutorial, you learn how to schedule local notifications with the User Notifications framework."
notificationContent.userInfo = ["customNumber": 100]
// Set Category Identifier
notificationContent.categoryIdentifier = Notification.Category.tutorial
// Add Trigger
let notificationTrigger = UNTimeIntervalNotificationTrigger(timeInterval: 10.0, repeats: false)
// Create Notification Request
let notificationRequest = UNNotificationRequest(identifier: "exampleNotification", content: notificationContent, trigger: notificationTrigger)
// Add Request to User Notification Center
UNUserNotificationCenter.current().add(notificationRequest) { (error) in
if let error = error {
print("Unable to Add Notification Request (\(error), \(error.localizedDescription))")
}
}
}
My extension is getting displayed but actions are not getting triggered & without extension actions are working fine.
Try something like that:
class NotificationViewController: UIViewController, UNNotificationContentExtension {
#IBOutlet var label: UILabel?
override func viewDidLoad() {
super.viewDidLoad()
// Do any required interface initialization here.
preferredContentSize = CGSize.init(width: self.view.bounds.width / 2, height: self.view.bounds.height / 5)
}
func didReceive(_ notification: UNNotification) {
self.label?.text = "Extension"
}
// Implement this method
func didReceive(_ response: UNNotificationResponse, completionHandler completion: #escaping (UNNotificationContentExtensionResponseOption) -> Void) {
if response.notification.request.content.categoryIdentifier == "yourCategory" {
switch response.actionIdentifier {
case "first":
// Do something
completion(.dismissAndForwardAction)
case "second":
// Do something
completion(.dismissAndForwardAction)
default:
break;
}
}
}
}
You should implement the UNNotificationContentExtension's method:
func didReceive(_ response: UNNotificationResponse, completionHandler completion: #escaping (UNNotificationContentExtensionResponseOption) -> Void) {}
And inside of this block you can check your actions. Hope it helps.

UNUserNotificationCenter Completion Was Never Called Swift

I have the following code blocks in my AppDelagate:
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: #escaping () -> Void) {
if response.actionIdentifier == UNNotificationDismissActionIdentifier {
print ("Message Closed")
}
else if response.actionIdentifier == UNNotificationDefaultActionIdentifier {
print ("App is Open")
}
// Else handle any custom actions. . .
}
func showMessage()
{
let notification = UNMutableNotificationContent()
notification.title = "Test"
notification.subtitle = "This is a test"
notification.body = "I need to tell you something, but first read this."
notification.categoryIdentifier = "TESTAPP"
notification.sound = UNNotificationSound.default()
let notificationTrigger = UNTimeIntervalNotificationTrigger(timeInterval: 0.5, repeats: false)
let request = UNNotificationRequest(identifier: "notification1", content: notification, trigger: notificationTrigger)
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
}
func applicationDidEnterBackground(_ application: UIApplication) {
let center = UNUserNotificationCenter.current()
center.delegate = self
self.showMessage()
}
My notification comes up and when I click on the notification to open the app, the app opens up and the console shows this:
App is Open
2017-07-23 14:48:56.182 Form[3255:198009] Warning:
UNUserNotificationCenter delegate received call to
-userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:
but the completion handler was never called.
So it looks like my print to type out "App is open" it displaying but I am getting the completion handler error right below it.
Add completionHandler() under your code in
userNotificationCenter
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: #escaping () -> Void) {
if response.actionIdentifier == UNNotificationDismissActionIdentifier {
print ("Message Closed")
}
else if response.actionIdentifier == UNNotificationDefaultActionIdentifier {
print ("App is Open")
}
// Else handle any custom actions. . .
completionHandler()
}
You need to make sure you call the completion handler within the method to let the system know you are done processing the notification.
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: #escaping () -> Void) {
if response.actionIdentifier == UNNotificationDismissActionIdentifier {
print ("Message Closed")
}
else if response.actionIdentifier == UNNotificationDefaultActionIdentifier {
print ("App is Open")
}
// Else handle any custom actions. . .
// Execute completion handler
completionHandler()
}

Swift Local push notification action view

I'm trying to create a notification with two possible action buttons like "Quick reply" and "Cancel", but I can't find any code examples for this. Please could someone explain how to do this in Swift 3.
It's difficult to give a precise example of what you are looking for. Here's a quick UNUserNotificationCenter implementation with an action.
import UserNotifications
Define a category ID constant
private let categoryID = "Category"
Setup and register UNUserNotificationCenter
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
// Configure User Notification Center
UNUserNotificationCenter.current().delegate = self
// Define Actions
let actionShowSomething = UNNotificationAction(identifier: "ShowSomething", title: "Show Something", options: [])
// Define Category
let category = UNNotificationCategory(identifier: categoryID, actions: [actionShowSomething], intentIdentifiers: [], options: [])
// Register Category
UNUserNotificationCenter.current().setNotificationCategories([category])
}
Example event for triggering the notification
// MARK: - Actions
#IBAction func sheduleNotification(sender: UIButton) {
// Request Notification Settings
UNUserNotificationCenter.current().getNotificationSettings { (notificationSettings) in
switch notificationSettings.authorizationStatus {
case .notDetermined:
self.requestAuthorization(completionHandler: { (success) in
guard success else { return }
// Schedule Local Notification
self.scheduleLocalNotification()
})
case .authorized:
// Schedule Local Notification
self.scheduleLocalNotification()
case .denied:
print("Application Not Allowed to Display Notifications")
}
}
}
sheduleNotification implementation
// MARK: - Methods
private func scheduleLocalNotification() {
// Create Notification Content
let notificationContent = UNMutableNotificationContent()
// Configure Notification Content
notificationContent.title = "Title"
notificationContent.subtitle = "Subtitle"
notificationContent.body = "Body"
// Set Category Identifier
notificationContent.categoryIdentifier = categoryID
// Add Trigger
let notificationTrigger = UNTimeIntervalNotificationTrigger(timeInterval: 10.0, repeats: false)
// Create Notification Request
let notificationRequest = UNNotificationRequest(identifier: "cocoacasts_local_notification", content: notificationContent, trigger: notificationTrigger)
// Add Request to User Notification Center
UNUserNotificationCenter.current().add(notificationRequest) { (error) in
if let error = error {
print("Unable to Add Notification Request (\(error), \(error.localizedDescription))")
}
}
}
Handle user notification authorization
private func requestAuthorization(completionHandler: #escaping (_ success: Bool) -> ()) {
// Request Authorization
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { (success, error) in
if let error = error {
print("Request Authorization Failed (\(error), \(error.localizedDescription))")
}
completionHandler(success)
}
}
UnUserNotificationDelegate implementation
extension ViewController: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert])
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse, withCompletionHandler
completionHandler: #escaping () -> Void) {
completionHandler()
}
}
Result
You can achieve this by UIMutableUserNotificationAction
for more information look here:-
1) https://nrj.io/simple-interactive-notifications-in-ios-8/
2) http://www.imore.com/interactive-notifications-ios-8-explained