sparingsoftware / ScreenSleepManager

Easy way to handle advanced isIdleTimerDisabled use cases

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ScreenSleepManager

Small library for managing screen sleep in your app.

Usage

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

Simple case

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.


Not simple case

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.


Advanced case

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.


Solution

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.


Tests

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")

License

MIT License © Sparing Interactive

About

Easy way to handle advanced isIdleTimerDisabled use cases

License:MIT License


Languages

Language:Swift 100.0%