iOS 10 UserNotifications custom sound in background mode
Asked Answered
N

6

12

Since UILocalNotification is deprecated in iOS 10 so I have updated my local notification flow using the UNUserNotification framework.

The app plays custom sound using AVPlayer when the app is in the foreground and it works fine. But in background mode when local notification is triggered, instead of custom sound, a default notification sound is being played.

However, things were working fine in iOS9, using "didReceiveLocalNotification" method app can play custom sound even in background mode.

Update 1:

I'm setting local notification as follows:

let content = UNMutableNotificationContent()
content.title = NSString.localizedUserNotificationStringForKey("reminder!", arguments: nil)
content.body = NSString.localizedUserNotificationStringForKey("Reminder body.", arguments: nil)
if let audioUrl == nil {
    content.sound = UNNotificationSound.defaultSound()
} else {
    let alertSound = NSURL(fileURLWithPath: self.selectedAudioFilePath)
    content.sound = UNNotificationSound(named: alertSound.lastPathComponent!)
}
content.userInfo = infoDic as [NSObject : AnyObject]
content.badge = 1
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 60, repeats: false)
let identifier = "Reminder-\(date)"
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
let center = UNUserNotificationCenter.currentNotificationCenter()
center.addNotificationRequest(request, withCompletionHandler: { (error) in
    if error != nil {
        print("local notification created successfully.")
    }
})

I have already gone through many SO Questions but didn't get the solution.

Any help will be greatly appreciated!

Nunci answered 13/5, 2017 at 11:40 Comment(2)
Please show the code that you have triedGernhard
You got it fixed...but this question may come to use in a near future:Softa
N
10

Found out that alertSound doesn't have the correct file path hence the content.sound sets nothing. I was saving the recorded file in documents directory and the file path retrieve for real device is different as compared to the simulator.

Setting a sound file which is placed in project bundle did the trick

content.sound = UNNotificationSound(named: "out.caf")
Nunci answered 13/5, 2017 at 16:20 Comment(2)
what if i am getting download tune file and how should i mention with path?Tokoloshe
@XcodianSolangi see this gist, created for you, it might help: gist.github.com/UmairSharif/d3281d147607c825c846b345ffd072d7Nunci
S
15

In Swift 4.2 and Xcode 10.1

For local notifications to play sound

let content = UNMutableNotificationContent()
content.title = "Notification Tutorial"
content.subtitle = "from ioscreator.com"
content.body = " Notification triggered"
//Default sound
content.sound = UNNotificationSound.default
//Play custom sound
content.sound = UNNotificationSound(named:UNNotificationSoundName(rawValue: "123.mp3"))

"123.mp3" file needs to be in your Bundle.

Sycophant answered 20/3, 2019 at 10:49 Comment(1)
For me it does not work with .mp3 files. But it works with .caf files. Luckily, there are numerous online converters for that.Unity
N
10

Found out that alertSound doesn't have the correct file path hence the content.sound sets nothing. I was saving the recorded file in documents directory and the file path retrieve for real device is different as compared to the simulator.

Setting a sound file which is placed in project bundle did the trick

content.sound = UNNotificationSound(named: "out.caf")
Nunci answered 13/5, 2017 at 16:20 Comment(2)
what if i am getting download tune file and how should i mention with path?Tokoloshe
@XcodianSolangi see this gist, created for you, it might help: gist.github.com/UmairSharif/d3281d147607c825c846b345ffd072d7Nunci
L
0

In your push notification package you need to include the custom sound you want to play in the background. This sound needs to be included in your application too.

For example, here is how I create a custom notification package in PHP for iOS. Notice in my notification object I have a sound object.

array("to" => $sDeviceID,
                    "data" => array($sMessageType => $sMessage,
                                    "customtitle" => $sMessageTitle,
                                    "custombody" => $sMessage,
                                    "customimage" => "$mIcon") ,
                    "notification" => array("title" => "sMessageTitle",
                                    "text" => $sMessage,
                                    "icon" => "$mIcon",
                                    "sound" => "mySound.mp3"));
Leilaleilah answered 13/5, 2017 at 11:44 Comment(1)
Thanks for your kind reply. But I'm using LocalNotification not push/remote. My app records a sound and save it and then fire a local notification that should be played in background mode. thanksNunci
G
0

Here is how to create a notification using the UserNotifications framework with a custom sound.

If notification is your UNNotificationContent and the name of your custom media file that is in your bundle is a.mp4, just use the following code:

notification.sound = UNNotificationSound(named: "a.mp4")

So, you don't need to use didRecieveLocalNotification.

Gernhard answered 13/5, 2017 at 12:28 Comment(1)
what if i am getting download tune file and how should i mention with path?Tokoloshe
H
0

I understand that

let notificationContent = UNMutableNotificationContent()

...

notificationContent.sound = UNNotificationSound(named: "out.mp3")

is working fine, but:

1) the sound file should not be longer than 30 sec (which is ok, I think)

2) the sound file has to be part of the Bundle.mail files. If it is stored somewhere else the notification will not have access to it, when in background. It works fine in foreground. Apple does not provide permission to access other folders as far as I know.

3) there are restrictions on the sound format. Please refer to Apple guides

4) I'm not sure if sound files in Bundle.main can be changed programmatically. For example: I wrote a routine which extracts 30 sec of a song stored in apple music and chosen by the user... everything works fine, if the info is stored in a different directory, but only in foreground... once locked or in background there is no access to it. I'm not able to change/overwrite a file in Bundle.main. If that would be possible the problem would be solved ... but I think that would be a security issue. I conclude that alert sounds and music are working fine as long as the above is met.

Hayden answered 6/5, 2018 at 18:28 Comment(2)
what if i am getting download tune file and how should i mention with path?Tokoloshe
Yes, that's fine. It would work if the app is in foreground. In background mode you will probably have the same issue mentioned in 4) as the path you stored the downloaded file will be different that Bundle.mainHayden
E
0
let notificationContent1 = UNMutableNotificationContent()
        notificationContent1.title = "Good morning! Would you like to listen to a morning meditation to start the day fresh ? Or maybe a cool relaxing soundscape? Open the app and browse our collection which is updated daily."
        notificationContent1.subtitle = ""
        notificationContent1.body = ""
        notificationContent1.sound = UNNotificationSound(named: UNNotificationSoundName(rawValue: "AlarmSound.wav"))

        var dateComponents1 = DateComponents()
        dateComponents1.hour = 08
        dateComponents1.minute = 00

        let trigger1 = UNCalendarNotificationTrigger(dateMatching: dateComponents1, repeats: true)

        let request1 = UNNotificationRequest(
            identifier: UUID().uuidString,
            content: notificationContent1,
            trigger: trigger1
        )

        let notificationContent2 = UNMutableNotificationContent()
        notificationContent2.title = "Good evening! Hope you had a great day. Would you like to meditate on a particular topic ? Or just some relaxing sleep sounds ? Open the app and pick what you want so you can go to sleep relaxed."
        notificationContent2.subtitle = ""
        notificationContent2.body = ""
        notificationContent2.sound = UNNotificationSound(named: UNNotificationSoundName(rawValue: "AlarmSound.wav"))

        var dateComponents2 = DateComponents()
        dateComponents2.hour = 20
        dateComponents2.minute = 00

        let trigger2 = UNCalendarNotificationTrigger(dateMatching: dateComponents2, repeats: true)

        let request2 = UNNotificationRequest(
            identifier: UUID().uuidString,
            content: notificationContent2,
            trigger: trigger2
        )

        UNUserNotificationCenter.current().delegate = self
        UNUserNotificationCenter.current().add(request1, withCompletionHandler: nil)
        UNUserNotificationCenter.current().add(request2, withCompletionHandler: nil)
Elwell answered 14/11, 2019 at 8:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.