Swift
iOS
screen lock prevention
app development
SwiftUI

How to prevent screen lock on my application with swift on iOS

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

On iOS, the screen auto-lock behavior is controlled by the app's idle timer. If your app shows turn-by-turn navigation, workouts, kiosk flows, or long-running reading content, you may need to keep the display awake temporarily. The correct API is UIApplication.shared.isIdleTimerDisabled. Many implementations work initially but fail when app state changes, because the flag is global and should be toggled intentionally as users move through screens. This guide shows a safe pattern for enabling and disabling screen lock prevention without draining battery unnecessarily.

Use isIdleTimerDisabled Intentionally

The simplest implementation sets the property when entering a screen and restores it when leaving.

swift
1import UIKit
2
3final class WorkoutViewController: UIViewController {
4    override func viewDidAppear(_ animated: Bool) {
5        super.viewDidAppear(animated)
6        UIApplication.shared.isIdleTimerDisabled = true
7    }
8
9    override func viewWillDisappear(_ animated: Bool) {
10        super.viewWillDisappear(animated)
11        UIApplication.shared.isIdleTimerDisabled = false
12    }
13}

This is usually enough for single-flow apps. The key is to always turn it back off when the feature no longer needs persistent screen-on behavior.

Centralize Control for Multiple Screens

If multiple features can request screen-on mode, avoid each screen toggling the global flag independently. Use a shared coordinator with reference counting.

swift
1final class IdleTimerManager {
2    static let shared = IdleTimerManager()
3    private var requests = 0
4
5    private init() {}
6
7    func acquire() {
8        requests += 1
9        UIApplication.shared.isIdleTimerDisabled = true
10    }
11
12    func release() {
13        requests = max(0, requests - 1)
14        UIApplication.shared.isIdleTimerDisabled = requests > 0
15    }
16}

Usage:

swift
IdleTimerManager.shared.acquire()
// ... feature active ...
IdleTimerManager.shared.release()

This prevents one screen from accidentally re-enabling auto-lock while another still needs it disabled.

Handle App Lifecycle and Background Transitions

When the app backgrounds, system behavior can reset user context. Restore policy predictably on foreground.

swift
1final class AppLifecycleObserver {
2    init() {
3        NotificationCenter.default.addObserver(
4            self,
5            selector: #selector(willEnterForeground),
6            name: UIApplication.willEnterForegroundNotification,
7            object: nil
8        )
9    }
10
11    @objc private func willEnterForeground() {
12        UIApplication.shared.isIdleTimerDisabled = IdleTimerManager.sharedIsActive
13    }
14}

If you do not maintain centralized state, foreground transitions can produce inconsistent lock behavior.

UX and Battery Considerations

Keeping the screen awake increases battery usage and can create OLED burn-in risk for static screens. Limit this mode to workflows where it is clearly user-beneficial. Also consider offering a user setting such as “Keep screen awake during workout.”

For long sessions, use dimmable UI, periodic movement in static widgets, and prompt users about battery impact.

Practical Verification Workflow

A reliable way to avoid regressions is to validate the solution in three passes: baseline, controlled change, and repeatability check. First, capture a baseline outcome before you apply fixes. This could be a failing command, a wrong output sample, a stack trace, or a screenshot of current behavior. Second, apply one focused change and rerun exactly the same checks so you can attribute improvements to a specific edit. Third, rerun the checks multiple times or with slightly different inputs to ensure the fix is not accidental or data-specific.

A lightweight template you can adapt for most projects looks like this:

bash
1# 1) reproduce current behavior
2./run_example.sh > before.txt
3
4# 2) apply your change
5# edit config/code based on this article
6
7# 3) verify behavior after change
8./run_example.sh > after.txt
9diff -u before.txt after.txt

If your environment involves tests, add at least one focused regression test that would fail before the fix and pass after it. This turns a one-time troubleshooting success into a durable maintenance improvement, which is especially important when teams rotate ownership or upgrade dependencies later.

Common Pitfalls

  • Setting isIdleTimerDisabled = true once and never resetting it when the flow ends.
  • Toggling the global flag from multiple screens without centralized ownership rules.
  • Assuming there is an Info.plist key for this behavior instead of using runtime API control.
  • Forgetting to test behavior after background/foreground transitions.
  • Forcing screen-on for all users without a feature-scoped or user-configurable policy.

Summary

To prevent screen lock in Swift, use UIApplication.shared.isIdleTimerDisabled and scope it to the exact feature that needs it. For multi-screen apps, centralize requests so toggling remains consistent. Always restore default behavior when screen-on mode is no longer required, and balance usability with battery and accessibility considerations.


Course illustration
Course illustration

All Rights Reserved.