2

Not sure, what's missing, but I'm stuck with a weird problem!!!

Notification sounds, but isn't displayed.

I have registered the app to only display alerts and sounds, and strangely it never is displayed. I can see that the notification is added successfully. But, there seems to be something trivial that I'm not able to comprehend.

Even removing the notification works.

import Foundation
import NotificationCenter
import UserNotifications

class NotificationManager: NSObject {

    private let categoryIdentifier = "notificationCategory"

    private var toDateComponents = NSDateComponents()

    private enum actionIdentifier : String {
        case openApp = "openApp"
        case playMusic = "playMusic"
    }

    // MARK: - Register for notifications

    func registerForNotifications(application: UIApplication) {
        if #available(iOS 10.0, *) {
            UNUserNotificationCenter.currentNotificationCenter().getNotificationSettingsWithCompletionHandler { notificationSettings in
                switch notificationSettings.authorizationStatus {
                case .NotDetermined:
                    UNUserNotificationCenter.currentNotificationCenter().requestAuthorizationWithOptions([.Alert, .Sound]) { (granted, error) in
                        // Enable or disable features based on authorization
                        if granted {
                            print("Access requested and was granted for sending notifications")
                            UNUserNotificationCenter.currentNotificationCenter().setNotificationCategories([])
                            UNUserNotificationCenter.currentNotificationCenter().delegate = self
                            self.setupNotificationActions()
                        } else {
                            print("Access requested and was denied for sending notifications")
                            print(error?.localizedDescription)
                        }
                    }
                case .Denied:
                    print("Notifications are turned off!!")
                break // nothing to do, pointless to go on
                case .Authorized:
                    self.setupNotificationActions()
                }
            }
        } else {
            // Nothing to do here
            print("iOS 9 says, Let's get started...")
            self.setupNotificationActions()
        }
    }

    // MARK: - Setup notification actions

    private func setupNotificationActions() {

        // Initialize and specify the notification actions
        if #available(iOS 10.0, *) {
            let openAppAction = UNNotificationAction(identifier: actionIdentifier.openApp.rawValue, title: "Open App", options: [.AuthenticationRequired, .Foreground])
            let playMusicAction = UNNotificationAction(identifier: actionIdentifier.playMusic.rawValue, title: "Play Music", options: [])
            let notificationCategory = UNNotificationCategory(identifier: categoryIdentifier, actions: [openAppAction, playMusicAction], intentIdentifiers: [], options: [.CustomDismissAction])

            UNUserNotificationCenter.currentNotificationCenter().setNotificationCategories([notificationCategory])
        } else {
            // Specify the notification actions
            let openAppAction = UIMutableUserNotificationAction()
            openAppAction.identifier = actionIdentifier.openApp.rawValue
            openAppAction.title = "Open App"
            openAppAction.activationMode = UIUserNotificationActivationMode.Foreground
            openAppAction.destructive = false

            let playMusicAction = UIMutableUserNotificationAction()
            playMusicAction.identifier = actionIdentifier.playMusic.rawValue
            playMusicAction.title = "Play Music"
            playMusicAction.activationMode = UIUserNotificationActivationMode.Background
            playMusicAction.destructive = false
            playMusicAction.authenticationRequired = false

            // Specify the category related to the above actions
            let notificationCategory = UIMutableUserNotificationCategory()
            notificationCategory.identifier = categoryIdentifier
            notificationCategory.setActions([openAppAction, playMusicAction], forContext: UIUserNotificationActionContext.Default)
            notificationCategory.setActions([playMusicAction], forContext: UIUserNotificationActionContext.Minimal)

            let notificationSettings = UIUserNotificationSettings(forTypes: [.Alert, .Sound], categories: NSSet(object: notificationCategory) as? Set<UIUserNotificationCategory>)
//            if (notificationSettings.types != UIUserNotificationType.None){
                UIApplication.sharedApplication().registerUserNotificationSettings(notificationSettings)
//            }
        }
    }

And, in AppDelegate...

private let notificationManager = NotificationManager()

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    notificationManager.registerForNotifications(application)
}
Rajan Maheshwari
  • 14,465
  • 6
  • 64
  • 98
Shyam
  • 561
  • 5
  • 22
  • Is your app in foreground when you are testing notification? – prabodhprakash Sep 29 '16 at 16:44
  • Nope. It isn't. – Shyam Sep 29 '16 at 16:45
  • Try doing this: clear all existing delivered notifications and then showing the new one. – prabodhprakash Sep 29 '16 at 16:47
  • @prabodhprakash It's the same!! :( – Shyam Sep 29 '16 at 16:52
  • @matt. I'm checking. let me see. – Shyam Sep 29 '16 at 16:53
  • @matt. Before I delve more into your code. Is it okay, if I use a single instance of `UNUserNotificationCenter.currentNotificationCenter()` throughout the app? – Shyam Sep 29 '16 at 17:00
  • @matt. I've gone through your code, and implemented quite a bit of logic from yours. But, there is no difference. Actually after the updated code found above, I don't get an alert at all. No display, no sound. But, I can see that there is a notification added to the `UNUserNotificationCenter.currentNotificationCenter` – Shyam Sep 30 '16 at 04:38
  • @matt. crossed messages!! But, thanks for getting back. Also, I picked up a few code writing etiquettes from your example! :) – Shyam Sep 30 '16 at 04:38
  • Is there a way that I can only download your local notification example from GitHub? I don't see a way of doing it – Shyam Sep 30 '16 at 04:41
  • Thanks @matt. I was able to download your project, and run it on my device. And, was able to then tweak mine accordingly, and make it work finally!! :) Thanks again.. – Shyam Sep 30 '16 at 05:25
  • This seems to be a delegate issue. But, I still can't comprehend the issue of only the sound going off!! – Shyam Sep 30 '16 at 05:26
  • @matt, although this is unrelated, I'd want you to ask a question. Based on your example, I tried implementing `NotificationContentExtension`. But, as I'm still on `Swift 2.3`, I'm having a problem. `Type 'NotificationViewController' does not conform to protocol 'UNNotificationContentExtension'` Can't this live side-by-side with `Swift 2.3` ? – Shyam Sep 30 '16 at 14:56
  • @matt The original problem is solved, thanks to your simple example. And, I'm able to implement a media attachment to my notification, as well. However, no luck with the NotificationContentExtension. :( – Shyam Sep 30 '16 at 15:21
  • No worries. Was wondering if you had an answer, because you might have already worked on Swift 2.2/2.3.. refrained from posting an answer, as I'm still curious about how only the alert sound went off but wasn't displayed!! – Shyam Sep 30 '16 at 15:45
  • http://stackoverflow.com/questions/39713605/getting-local-notifications-to-show-while-app-is-in-foreground-swift-3 – Sanju Oct 05 '16 at 04:38
  • @matt. This is related to your example you've suggested. I can see that your image in the notification comes off good. I'm not mentioning the content extension, its the one in the original notification. In my case, I use artwork from music library, and no matter what resolution I use, its the same cropped picture. How can I have the full image? – Shyam Oct 12 '16 at 05:48

2 Answers2

4

Whenever are you sending rich notification be sure about payload, must contain "mutable-content": 1,

payload like,

{
  "aps": {
    "alert": "Test Rich Notification",
    "mutable-content": 1,
    "badge": "1"
  },
  "mediaUrl": "https://www.awaragroup.com/wp-content/uploads/2015/05/it-specialist.jpg",
  "mediaType": "jpg"
}
Tamojit Pal
  • 111
  • 1
  • 4
1

Delegate should be assigned correctly. Although, I wasn't able to zero in on why this happened, below changes ensured that notifications went through.

AppDelegate,

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

    private let notificationManager = NotificationManager()

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    UNUserNotificationCenter.currentNotificationCenter().delegate = self
    notificationManager.registerForNotifications()

    }
}

Insert the delegate methods in AppDelegate, itself.

Shyam
  • 561
  • 5
  • 22