I have the following function setPath()
which is called whenever the user taps on a button:
var loadSuccessfulTimer: Timer? = nil
func setPath(index: Int) {
self.loadSuccessfulTimer?.invalidate()
self.loadSuccessfulTimer = nil
print("setting path")
self.pause(releaseAudioSession: false)
self.reset(index: index)
let song = DataManager.getInstance().getQueueSong(index: index)
superpowered.setPath(song.url, true)
self.loadSuccessfulTimer = Timer.scheduledTimer(timeInterval: 0.2, target: self, selector: #selector(checkLoadSucess), userInfo: nil, repeats: true)
self.loadSuccessfulTimer!.fire()
}
@objc func checkLoadSucess() {
let status = self.superpowered.getLoadSuccessful()
print(status)
if(status != -1) {
self.loadSuccessfulTimer?.invalidate()
self.loadSuccessfulTimer = nil
if(status == 1){
print("success")
} else if(status == 2){
print("failed")
}
}
}
So whenever the setPath()
function gets called, I want the timer to trigger every 0.2
seconds to check on a the value of status = self.superpowered.getLoadSuccessful()
. The variable status would have values -1, 1, 2
I want to stop the timer when it's either 1
or 2
. However, the following scenario is happening:
On the first tap it is working as expected and printing the following:
setting path
-1
-1
-1
-1
-1
-1
1
success
On the second tap the timer is only triggered one time (I guess it is from the .fire()
) and the following is being printed:
setting path
-1
I tried to look up what might be going wrong, but all I could see was this is the recommended way of using a Timer
.
Update
The second time setPath()
is being called from DispatchQueue.global()
, maybe this is related to the issue.
NSTimer requires run loop to work properly. The main queue has a run loop for free, for other queues you need to make sure run loop is available.
Make sure you read the documentation: https://developer.apple.com/documentation/foundation/nstimer
Also, remember to invalidate NSTimer object from the same run loop (thread) is has been created (scheduled) from.