I am using a for loop coupled with a DispatchQueue with async to incrementally increase playback volume over the course of a 5 or 10-minute duration.
How I am currently implementing it is:
for i in (0...(numberOfSecondsToFadeOut*timesChangePerSecond)) {
DispatchQueue.main.asyncAfter(deadline: .now() + Double(i)/Double(timesChangePerSecond)) {
if self.activityHasEnded {
NSLog("Activity has ended") //This will keep on printing
} else {
let volumeSetTo = originalVolume - (reductionAmount)*Float(i)
self.setVolume(volumeSetTo)
}
}
if self.activityHasEnded {
break
}
}
My goal is to have activityHasEnded
to act as the breaker. The issue as noted in the comment is that despite using break
, the NSLog
will keep on printing over every period. What would be the better way to fully break out of this for loop that uses DispatchQueue.main.asyncAfter
?
Updated: As noted by Rob, it makes more sense to use a Timer
. Here is what I did:
self.fadeOutTimer = Timer.scheduledTimer(withTimeInterval: timerFrequency, repeats: true) { (timer) in
let currentVolume = self.getCurrentVolume()
if currentVolume > destinationVolume {
let volumeSetTo = currentVolume - reductionAmount
self.setVolume(volumeSetTo)
print ("Lowered volume to \(volumeSetTo)")
}
}
When the timer is no longer needed, I call self.fadeOutTimer?.invalidate()