iOS:从通知扩展播放远程音频文件
Posted
技术标签:
【中文标题】iOS:从通知扩展播放远程音频文件【英文标题】:iOS: play remote audio file from notification extension 【发布时间】:2018-01-22 10:46:03 【问题描述】:我正在尝试通过通知扩展播放远程音频文件
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void)
//...
let url = URL(string: "https://firebasestorage.googleapis.com/v0/b/XXX.appspot.com/o/XXXXXXX?alt=media&token=XXXXXXX")
let item = AVPlayerItem(url: url!)
NotificationCenter.default.addObserver(self, selector: #selector(playerDidFinishPlaying), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: item)
let player = AVPlayer(playerItem: item)
player.play()
但是什么也没发生。
在应用程序的功能中,我启用了以下后台模式:“音频、AirPlay 和 PiP”、“后台获取”、“远程通知”
我需要在通知到达时播放声音而无需用户交互。 此外,媒体附件不是一个选项,因为 ios 10 支持是强制性的。
UPD:我试过了
func download(url: URL)
URLSession.shared.downloadTask(with: url, completionHandler: _, _, error in
if let error = error
print(error)
self.play(url: url)
).resume()
func play(url: URL)
let player = try! AVAudioPlayer(contentsOf: url)
player.prepareToPlay()
player.volume = 1.0
player.play()
什么也没发生
【问题讨论】:
我不知道你所说的“从通知扩展播放远程音频文件”是什么意思,但你应该使用 URLSessionDownloadTask。 @ElTomato 我刚才试过了,不行 【参考方案1】:iOS 13 现在可以做到这一点。我将在此处复制消息的内容,以防它被删除。 https://forums.developer.apple.com/thread/118404Correct
KevinE 于 2019 年 7 月 30 日下午 5:11 回答
您的应用应该如何工作的细节会有很大的不同 取决于您的具体用例和应用程序设计,但我们一般 对一键通应用程序的建议是您转向使用 标准推送通知而不是 PushKit 用于消息传递。 更具体地说,在接收方您的通知服务 扩展程序应下载相关音频并将该声音附加到 您的特定信息。
为了支持这种方法,从 iOS 13 开始,系统会寻找 应用程序组容器中可能的声音文件以及 预先存在的搜索位置。文档没有更新 为此尚未(),但有头文件文档描述 "UNNotificationSound.h" 中 "soundNamed:" 的 cmets 中的详细信息:
// 通知播放的声音文件。声音必须是 在应用程序数据容器的 Library/Sounds 文件夹中或 应用组数据容器的 Library/Sounds 文件夹。如果文件是 在容器中找不到,系统将在应用程序包中查找。
详细分解,我们在下面查找声音文件 顺序和地点:
“库/声音”中的应用直接容器。您的应用组 名为“Library/Sounds”的目录中的目录 您的应用程序包 这里要记住的主要事项:
目录 #2 是“库/声音”,而不仅仅是“声音”。你需要 创建一个“库”目录,其中包含“声音”目录,而不是 只是一个“声音”目录。应用程序直接容器仍然是 首先我们会看,所以你需要小心你如何 命名您的文件。我建议使用组目录 对于所有声音或遵循两种不同的命名约定 位置,使它们永远不会发生碰撞。您的网络服务扩展 看不到目录#1的内容,所以不知道是否 不会有一个特定的名称发生冲突。
【讨论】:
【参考方案2】:感谢TALE的回答,我已经实现了
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler
self.receivedRequest = request;
self.contentHandler = contentHandler;
self.bestAttemptContent = [request.content mutableCopy];
if (request.content.userInfo != nil && request.content.userInfo[@"audioUrl"] != nil)
NSURL* audioUrl = [NSURL URLWithString:request.content.userInfo[@"audioUrl"]];
NSString* audioName = audioUrl.lastPathComponent;
[[[NSURLSession sharedSession] downloadTaskWithURL:audioUrl completionHandler: ^void (NSURL* location, NSURLResponse* response, NSError* error)
if (location == nil)
contentHandler(self.bestAttemptContent);
NSLog(@"%@", error);
return;
NSFileManager* fileMan = [NSFileManager defaultManager];
NSString* containerPath = [fileMan containerURLForSecurityApplicationGroupIdentifier:@"group.com.example"].path; // Put your app group id here
NSString* soundDir = [containerPath stringByAppendingString:@"/Library/Sounds"];
NSError* errorOut;
if (![fileMan fileExistsAtPath:soundDir])
[fileMan createDirectoryAtPath:soundDir withIntermediateDirectories:YES attributes:nil error:&errorOut];
else
// Delete old files
NSArray<NSString*>* oldFiles = [fileMan contentsOfDirectoryAtPath:soundDir error:&errorOut];
if (oldFiles != nil)
for (NSString* oldFileName in oldFiles)
NSString* oldFilePath = [soundDir stringByAppendingString:oldFileName];
[fileMan removeItemAtPath:oldFilePath error:&errorOut];
NSString* soundPath = [soundDir stringByAppendingString:[@"/" stringByAppendingString:audioName]];
NSURL* soundUrl = [NSURL fileURLWithPath:soundPath];
[fileMan copyItemAtURL:location toURL:soundUrl error:&errorOut];
UNNotificationSound* sound = [UNNotificationSound soundNamed:audioName];
self.bestAttemptContent.sound = sound;
contentHandler(self.bestAttemptContent);
] resume];
return;
// Your logic for non-audio notification
self.contentHandler(self.bestAttemptContent);
如果您需要 Swift 版本,请随时发表评论
【讨论】:
【参考方案3】:我认为,根据我之前的经验,我们可以在收到通知时播放捆绑声音文件。这意味着,我们必须将声音文件放在应用程序包中,并且声音文件是应用程序的预定义资源。
如果您想播放不同的声音,请在应用程序包中添加所有声音文件并使用通知有效负载密钥识别/播放。
例如,如果您想播放带有相关通知的 ABC 文件,则使用 Notification Payload 设置适当的逻辑/密钥并识别它。
请告诉我你的想法。快乐编码:)
其他参考: Play notification sound using URL
如果您想使用 URL 播放声音。然后你可以下载这个文件,也可以在缓冲特定文件后播放:
How to play mp3 audio from URL in ios swift
【讨论】:
请阅读问题标题。它清楚地写着“远程音频文件”。现在它被硬编码用于测试,但后来它会是音频消息,所以我不能把它们放在 bundle 中 是的,我已经仔细阅读了。我已经告诉过您,无法直接使用带有通知的 url 播放音频文件。有两种解决方案 1.您需要下载文件然后才能播放。请查看此网址:***.com/questions/34563329/…。 2.将 Predifine 文件与 app bundle 一起使用。 @DimaRostopira 嗨亲爱的。我需要你的帮助。 @EktaPadaliya 怎么了? @DimaRostopira 我想在推送接收时流式传输音频。那我该怎么做呢?以上是关于iOS:从通知扩展播放远程音频文件的主要内容,如果未能解决你的问题,请参考以下文章