how to test in ios device about bgtaskscheduler function not using debug function

i have no problem when using debug function in my iphone not simulator. (ex, e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"TASK_IDENTIFIER"] )

but when do not using debug function, follow my code,

it will be play the music after 60 seconds when going to background the app in my iphone.

however nothing to happen in the device.

how do i test the device not using debug function?

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)
    }
   
    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()
    }
}

it will be play the music after 60 seconds when going to background the app in my iphone.

What high-level goal are you trying to achieve here?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I'm making an alarm app. The code written above is a bgtaskschedular function test code, and following the code, the music will operate 60 seconds after entering the background. I confirmed that music plays immediately when I got test using the debug function on my phone. (ex, e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"TASK_IDENTIFIER"] )

However without using debug function, I entered the background of the app in my iphone and waited for a minute, the music is not playing. Is there problem?

I'm making an alarm app.

Hmmm. I’m confused how the Background Tasks framework fits into that goal. There are two types of background tasks:

  • BGProcessingTask — This gives your app extended execution time when the device is idle, typically in the middle of the night.

  • BGAppRefreshTask — This may give your app short periods of execution time during the day.

Either way, the system does not guarantee to run your tasks at a particular time, and thus they’re not suitable for an alarm clock function.

If you’re building an alarm app then I recommend that you use the User Notifications framework.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thank you for comment, When notification framework is used, the problem cannot execute notification sound for a long time. Due to the alarm characteristics, the alarm sound must be executed for at least 1 minute. So I thought about bgtaskschedular, is there any other way the app can play music at least 1 minute on suspend or background mode?

how to test in ios device about bgtaskscheduler function not using debug function
 
 
Q