Small library for managing screen sleep in your app.
Don't let the screen go sleep on this ViewController:
let manager = ScreenSleepManager.instance
// ...
func viewDidAppear() {
manager.requestToDisableSleep(withKey: "PlayerView")
}
func viewDidDisappear() {
manager.removeRequest(forKey: "PlayerView")
}
or - don't let it sleep when something is being proceeded:
class AudioProcessor {
func startProcessing() {
// ...
manager.requestToDisableSleep(withKey: "AudioProcessor")
}
// callback
func processingFinished() {
manager.removeRequest(forKey: "AudioProcessor")
}
}
Let's say you don't want the screen to "go sleep" in particular ViewController. You will need to use isIdleTimerDisabled
and set it to true
. When user leaves this screen you will have to set it back to false
- otherwise your app will never let your screen to turn off.
In simple cases that's OK. Easy to set, easy to remember.
If you have multiple ViewsControllers in your app and on some of them you want to disable "screen lock" but on others don't.
You can somehow manage it with isIdleTimerDisabled
but it would be really easy to make a mistake (true
instead of false
etc.) or just forget about enabling/disabling. Also when user leaves a ViewController and it will call isIdleTimerDisabled = false
- it might be wrong because there may be other module that doesn't want screen to go sleep.
I found a really simple and nice library called Insomnia for such scenario. However in our (pretty big) music app we encountered some advanced cases and we wanted more suitable solution for this. Also - as we are usually doing TDD - we needed something easy and modularized for testing.
As I already mention we are responsible for maintaining one of the biggest music app in Poland. It allows you to record video, add audio filters, browse through thousands of videos, listen to songs etc. We had some special requirements like:
- don't let the screen lock on specified Views
- don't let the screen lock when user is recording or listening to songs
- and at last but not least - don't let the screen lock when user's recording is being proceeded in background (user can be on any View)
- in every other scenario we have to let the system do what it want with the screen
We have to handle case in which many independent modules will try to enable and disable idleTimer.
ScreenSleepManager implements IScreenSleepManager (sorry for my Java habits - I like to know which objects are interface/protocol at a glance)
protocol IScreenSleepManager {
func requestToDisableSleep(withKey key: String)
func removeRequest(forKey key: String)
}
You can send as many requests as you need and screen will be "ready to turn off" only when there are no more requests on stack. It's kind of a counter but with keys so you can control it better.
You can test it as an inter-module and see if isDisabled
has proper value:
audioProcessor.startProcessign()
router.navigate(to: .Login)
presenter.clickSmth()
XCTAssert(ScreenSleepManager.instance.isDisabled == false)
You can also inject ScreenSleepManager object to your View/Presenter/ViewModel and test your calls:
let mockScreenManager = MockScreenSleepManager()
let presenter = Presenter(..., mockScreenSleepManager)
presenter.startRecordingClicked()
verify(mockScreenManager).requestToDisableSleep(withKey: "XYZ")
// ...
presenter.stopRecordingClicked()
verify(mockScreenManager).removeRequest(forKey: "XYZ")
MIT License © Sparing Interactive