问题
Currently I am creating an alarm app that plays custom audio clips from the server. My plan on implementing this is by saving all the audio clips locally and then setting the soundName accordingly.
But I am having a few issues. Currently I am having troubles saving the audio files in the bundle directory and only able to save the files in the document directory. Would it be possible to set the soundName from the document directory instead of the bundle directory?
OR
would it be possible for me to save the audio file from the server to the bundle directory?
var localNotification = UILocalNotification()
localNotification.fireDate = self.timePicker.date
localNotification.alertBody = "Alert Fired"
localNotification.soundName = "fakesound.caf" // File saved in Document Directory
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
Thanks, please let me know if you have any confusion with my question. Or if you can think of another solution on how I could solve this problem.
回答1:
The answer, unfortunately, is no and no.
You can only play sounds from the bundle in a local notification, and the bundle is read-only.
The only sounds you can play from a local notification must be shipped with your app. No other option.
回答2:
Fortunately, it is YES. Vist this link : How do I add a file to the main bundle's /Library/Sounds directory?
Here I have copied the system ringtone to Library/Sounds, likewise you have to copy from your data directory by putting the path as source path and destination as given below, by creating a directory with Sounds name.
// get the list of system sounds, there are other sounds in folders beside /New
let soundPath = "/System/Library/Audio/UISounds/New"
var arrayOFSoundNames = [String] ()
// MARK: - scene setup
func doAnyAdditionalSetup()
{
arrayOFSoundNames = getSoundList()
}
// MARK: - File manager methods
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)")
}
}
// MARK: - tableview methods
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrayOFSoundNames.count
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
copyFileToDirectory(fromPath:soundPath, fileName:arrayOFSoundNames[indexPath.row])
}
You will get your answer, also check the apple document
回答3:
There is one more way, that you can directly save your custom audio file in Library/Sounds rather than saving in the document directory. And then just put the name of the file with extension in the notification payload, it will play your custom audio on local/push notification; provided its not more than 30 seconds.
Refer code if needed:
let libraryDir = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.LibraryDirectory, NSSearchPathDomainMask.UserDomainMask, true)
let directoryPath = "\(libraryDir.first!)/Sounds"
try fileManager.createDirectoryAtPath(directoryPath, withIntermediateDirectories: true, attributes: nil)
Here, you get the path of Library/Sounds in directoryPath variable, using this you can save or do other operations.
来源:https://stackoverflow.com/questions/31150806/uilocalnotification-playing-a-custom-audio-file-saved-in-documents-directory