How to build a Workout app on WatchOS with audio feedback?
Asked Answered
C

1

6

I am building a very simple workout app on WatchOS: One of it functions is to give audio feedback during the training. I am able to play a file when the display is on, but when the display is dark, the watch doesnt play my file.

Can some one look over my swift code and help my figuring out what I am missing?

Here is my extensionDelegate.swift:

var audioPlayer = AVAudioPlayer()

class ExtensionDelegate: NSObject, WKExtensionDelegate {
    func applicationDidFinishLaunching() {
        let audioSession = AVAudioSession.sharedInstance()
        do {
            try audioSession.setCategory(AVAudioSessionCategoryAmbient, with: .duckOthers)
        } catch {
            print("audiosession cannot be set")
        }
        do { try audioSession.setActive(true) }
        catch {
            print ("audiosession cannot be activated")
        }

        let test = URL(fileURLWithPath: Bundle.main.path(forResource: "1", ofType: "m4a")!)
        try! audioPlayer = AVAudioPlayer(contentsOf: test)
        audioPlayer.prepareToPlay()
        audioPlayer.play()
    }

    func applicationDidBecomeActive() {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
        do {
            try AVAudioSession.sharedInstance().setActive(true)
        } catch {
            print ("shared Instance could not be activated")
        }
    }

    func handle(_ backgroundTasks: Set<WKRefreshBackgroundTask>) {
        // Sent when the system needs to launch the application in the background to process tasks. Tasks arrive in a set, so loop through and process each one.
        for task : WKRefreshBackgroundTask in backgroundTasks {
            // Check the Class of each task to decide how to process it
            print ("received background tasks")
            if task is WKApplicationRefreshBackgroundTask {
                // Be sure to complete the background task once you’re done.
                let backgroundTask : WKApplicationRefreshBackgroundTask = task as! WKApplicationRefreshBackgroundTask
                backgroundTask.setTaskCompleted()
            } else if task is WKSnapshotRefreshBackgroundTask {
                // Snapshot tasks have a unique completion call, make sure to set your expiration date
                let backgroundTask : WKSnapshotRefreshBackgroundTask = task as! WKSnapshotRefreshBackgroundTask
                backgroundTask.setTaskCompleted(restoredDefaultState: true, estimatedSnapshotExpiration: .distantFuture, userInfo: nil)
            } else if task is WKWatchConnectivityRefreshBackgroundTask {
                // Be sure to complete the background task once you’re done.
                let backgroundTask : WKWatchConnectivityRefreshBackgroundTask = task as! WKWatchConnectivityRefreshBackgroundTask
                backgroundTask.setTaskCompleted()
            } else if task is WKURLSessionRefreshBackgroundTask {
                // Be sure to complete the background task once you’re done.
                let backgroundTask : WKURLSessionRefreshBackgroundTask = task as! WKURLSessionRefreshBackgroundTask
                backgroundTask.setTaskCompleted()
            } else {
                // make sure to complete unhandled task types
                task.setTaskCompleted()
            }
        }
    }
}

And in InterfaceController.swift I call the function:

func startTimer() {
    // every 30 seconds
    print ("timer function started")    
    timer = Timer.scheduledTimer(withTimeInterval: 30.0, repeats: true) { [weak self] _ in
        print("play")
        audioPlayer.play()
    }
}
Cnossus answered 3/4, 2017 at 16:55 Comment(0)
C
4

I figured out what I did wrong: For the sound to play with the screen off, it is very important to set the category to AVAudioSessionCategoryPlayback, not ambient.

So that is all I did to get it working: I changed one word in line 10 of my extensionDelegate.swift:

        try audioSession.setCategory(AVAudioSessionCategoryPlayback, with: .duckOthers)
Cnossus answered 3/4, 2017 at 18:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.