我希望我错了,但我认为这是不可能的。在本地和推送通知编程指南中,在“准备自定义警报声音”下它说“声音文件必须在客户端应用程序的主包中”。
如果您无法写入主包,那么如何让用户生成的录音(例如,使用 AVAudioRecorder)作为警报声音播放?
一方面这似乎是不可能的,但另一方面我认为那里有应用程序可以做到这一点(我会寻找那些)。
我希望我错了,但我认为这是不可能的。在本地和推送通知编程指南中,在“准备自定义警报声音”下它说“声音文件必须在客户端应用程序的主包中”。
如果您无法写入主包,那么如何让用户生成的录音(例如,使用 AVAudioRecorder)作为警报声音播放?
一方面这似乎是不可能的,但另一方面我认为那里有应用程序可以做到这一点(我会寻找那些)。
我通过将系统声音文件复制到 ~/Library/Sounds 目录并将其命名为 notification.caf 来解决这个问题。服务器警报负载将此指定为要播放的声音的名称。每当用户选择另一个声音时,该声音将被复制到同一文件夹并覆盖旧声音。
有效载荷:
{
"aps": {
"sound": "notification.caf"
}
}
// get the list of system sounds, there are other sounds in folders beside /New
let soundPath = "/System/Library/Audio/UISounds/New"
func getSoundList() -> [String] {
var result:[String] = []
let fileManager = NSFileManager.defaultManager()
let enumerator:NSDirectoryEnumerator = fileManager.enumeratorAtPath(soundPath)!
for url in enumerator.allObjects {
let string = url as! String
let newString = string.stringByReplacingOccurrencesOfString(".caf", withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
result.append(newString)
}
return result
}
// copy sound file to /Library/Sounds directory, it will be auto detect and played when a push notification arrive
class func copyFileToDirectory(fromPath:String, fileName:String) {
let fileManager = NSFileManager.defaultManager()
do {
let libraryDir = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.LibraryDirectory, NSSearchPathDomainMask.UserDomainMask, true)
let directoryPath = "\(libraryDir.first!)/Sounds"
try fileManager.createDirectoryAtPath(directoryPath, withIntermediateDirectories: true, attributes: nil)
let systemSoundPath = "\(fromPath)/\(fileName)"
let notificationSoundPath = "\(directoryPath)/notification.caf"
let fileExist = fileManager.fileExistsAtPath(notificationSoundPath)
if (fileExist) {
try fileManager.removeItemAtPath(notificationSoundPath)
}
try fileManager.copyItemAtPath(systemSoundPath, toPath: notificationSoundPath)
}
catch let error as NSError {
print("Error: \(error)")
}
}
推送通知声音可能有问题,但我必须重新启动手机,然后声音才能可靠地为每个通知播放。