【发布时间】:2022-01-10 19:02:25
【问题描述】:
在我的 ios 设备而非模拟器中使用调试功能时没有问题。 (例如,e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"TASK_IDENTIFIER"])
但是当不使用调试功能时,按照我的代码,它将在进入后台 60 秒后播放音乐。但是设备中没有发生任何事情。
如何测试不使用调试功能的设备?
import UIKit
import BackgroundTasks
import os.log
import AVFoundation
private let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "AppDelegate")
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
let bgTaskIdentifier = "com.hakjun.bgTest.playMusic"
var alarmTime : Int = 0
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
BGTaskScheduler.shared.register(forTaskWithIdentifier: bgTaskIdentifier, using: nil) { task in
self.handleAppRefresh(task: task as! BGAppRefreshTask)
print("test bg")
}
return true
}
func scheduleAppRefresh(time : Double) {
let request = BGAppRefreshTaskRequest(identifier: bgTaskIdentifier)
request.earliestBeginDate = Date(timeIntervalSinceNow: time)
do {
try BGTaskScheduler.shared.submit(request)
print("schedule app refresh")
} catch {
print("Could not schedule app refresh task \(error.localizedDescription)")
}
}
func handleAppRefresh(task : BGAppRefreshTask){
scheduleAppRefresh(time: 60)
let queue = OperationQueue()
queue.maxConcurrentOperationCount = 1
let appRefreshOperation = BlockOperation {
Singleton.sharedInstance.play()
}
// queue.addOperation(appRefreshOperation)
task.expirationHandler = {
print("expire background")
queue.cancelAllOperations()
}
let lastOperation = queue.operations.last
lastOperation?.completionBlock = {
task.setTaskCompleted(success: !(lastOperation?.isCancelled ?? false))
}
print("background handle")
queue.addOperation(appRefreshOperation)
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
func applicationDidEnterBackground(_ application: UIApplication) {
print("test bg os log2")
logger.log("App did enter background")
scheduleAppRefresh(time: 60)
}
}
class Singleton {
static let sharedInstance = Singleton()
private var player: AVAudioPlayer?
func play() {
let audioSession = AVAudioSession.sharedInstance()
guard let url = Bundle.main.url(forResource: "alarm2", withExtension: "mp3") else { return }
do {
try audioSession.setCategory(.playback, mode: .default, options: [])
} catch let error as NSError {
print("audioSession 설정 오류 : \(error.localizedDescription)")
}
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback)
try AVAudioSession.sharedInstance().setActive(true)
player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.mp3.rawValue)
guard let player = player else { return }
player.play()
} catch let error {
print(error.localizedDescription)
}
}
func stop() {
player?.stop()
}
}
【问题讨论】:
-
此音乐仅用于诊断目的吗?我问,因为这不是
BGAppRefreshTaskRequest的用途。首先,它的运行时间由操作系统自行决定(可能要等到很久很久以后)。其次,这不是在后台播放音乐的正确工具。这只会使应用程序在最终触发时在后台运行几秒钟/几分钟。 -
第三,如果我没看错你的代码,看起来你是在开始歌曲后立即结束后台任务。这是你的意图吗?这似乎不对。或者您是否打开了背景音乐播放作为背景功能?
-
感谢您的评论,我正在制作一个闹钟应用程序,实际上音乐应该在设置为闹钟的时间播放。以上代码写成bgtaskschedular示例代码,进入后台1分钟后生成了BGAppRefreshTaskRequest。在闹钟应用程序中,它将是设置为闹钟的时间。那我应该用BG Processing Task在后台特定时间播放音乐吗?
-
那么,
BGAppRefreshTask肯定不是正确的工具。请参阅下面的答案。
标签: swift iphone bgtaskscheduler