iOS-Swift UIApplication.shared.isIdleTimerDisabled = true not working after review from AppStore
Asked Answered
C

4

9

Trying to Achieve Stop the screen going to sleep on certain View Controller

What I have done I have tested my app with the following code on a physical iPhone 6 running on iOS 12.1.12. I set the phone Dislpay & Brigthness > Auto-Lock to 30 seconds. I ran the app and on the particular VC with UIApplication.shared.isIdleTimerDisabled = true, the screen remains on even after 30 seconds. And when I switch to other VC without UIApplication.shared.isIdleTimerDisabled = true, the screen will turn off after 30 seconds.

I distributed to AppStore and I am positive that I have uploaded the correct version and dowloaded a fresh copy from AppStore, the screen always on thingy doesn't work at all, the screen will always turn off following the Auto-Lock setting.

I have read some articles https://docs.kioskproapp.com/article/899-ios-12-with-guided-access-causing-kiosk-pro-to-sleep and isIdleTimerDisabled not working in iOS 12

I tried the Guided Access and switched on Guided Access and Mirror Display Auto-Lock > ON. Still it is not working for the App from AppStore. Please help.

Code

override func viewDidLoad() {

    super.viewDidLoad()
    //==== For the screen to remains on
    UIApplication.shared.isIdleTimerDisabled = true
}


override func viewDidDisappear(_ animated: Bool) {

    //=== Switch off the screen always on, back to the phone settings. 
    UIApplication.shared.isIdleTimerDisabled = false
}
Counterchange answered 2/1, 2019 at 7:23 Comment(4)
When is your VC loaded? You set the IdleTimerDisabled in viewDidLoad which might only occur once if it is in a Navigation stack and get disabled when you push or pop because of your viewDidDisappear? Do you want to reinstate it in viewDidAppear?Gymnastics
Well the VC is embedded in a Navigation controller. Even if the code is at viewDidLoad, ideally it should load once. But the problem is it doesn't even load at all. I think it is a bug in iOSCounterchange
Is there a solution to this issue? I have a video call app, and I need the device to disable auto-dimming of the screen during the video calls. Is there a way to achieve thisCerda
Any news? Solution?Ootid
S
14

I had the same issue on iOS 13. And I found this great article explaining why .isIdleTimerDiabled appears to be not working.

In short, as iOS 13 introduced SceneDelegate, just by setting .isIdleTimerDisabled to false in AppDelegate is not enough, you need to set it in SceneDelegate too

class SceneDelegate: NSObject, UIWindowSceneDelegate {
    var window: UIWindow?
    
    @available(iOS 13.0, *)
    func sceneDidBecomeActive(_ scene: UIScene) {
        UIApplication.shared.isIdleTimerDisabled = true
    }
}

Code above made my app immune to autolock, but this is just a quick dirty solution, a better way is to toggle isIdleTimerDisabled on and off based on ViewController user is using, below is Apple's documentation about this property.

You should set this property (isIdleTimerDisabled) only if necessary and should be sure to reset it to false when the need no longer exists. Most apps should let the system turn off the screen when the idle timer elapses. This includes audio apps. With appropriate use of Audio Session Services, playback and recording proceed uninterrupted when the screen turns off. The only apps that should disable the idle timer are mapping apps, games, or programs where the app needs to continue displaying content when user interaction is minimal.

Schist answered 7/10, 2020 at 0:48 Comment(2)
You don't have to always set the isIdleTimerDisabled to false from the SceneDelegate. In the case of the article you provided, the need was to set the isIdleTimerDisabled to false when the application starts. In that specific case the Application Lifecycle matters, so you might need to set the flag to false from the SceneDelegate. In the above case, though, there is no reason to call isIdleTimerDisabled from the SceneDelegate. You can call it from any place in your application.Benetta
Adding to Vladimir's comment: That article does not say that setting it in SceneDelegate is the only place to fix this. The fix for original post might be as simple as moving the ... = true line to viewDidAppear. Either viewDidLoad happened too early, or viewDidDisappear ran, setting back to false. And the view did not load again, just appeared again. Anything removed in viewDidDisappear should be set in viewDidAppear!Magocsi
I
7

Just wanted to also share that the provided answer from https://mcmap.net/q/1132234/-ios-swift-uiapplication-shared-isidletimerdisabled-true-not-working-after-review-from-appstore @Daniel Hu was great but I had issues why it wasn't working while running it thru Xcode. This little snippet was the key (from This Link)

Test Note: Running applications under the debugger through Xcode will automatically disable the idle timer. When building or testing the app, make sure to install it, then launch it “by hand” on a test device. The effects will be most obvious if the “Auto-Lock” setting is 30 seconds.

Inward answered 22/1, 2022 at 1:21 Comment(0)
B
1

Here's how to set isIdleTimerDisabled from the scene delegate for a SwiftUI application on iOS 13+:

import SwiftUI

@main
struct MyApp: App {
    @Environment(\.scenePhase) var scenePhase

    var body: some Scene {
        WindowGroup {
            MainView()
        }
        .onChange(of: scenePhase) { (phase) in
            switch phase {
            case .active:
                // In iOS 13+, idle timer needs to be set in scene to override default
                UIApplication.shared.isIdleTimerDisabled = true
            case .inactive: break
            case .background: break
            @unknown default: print("ScenePhase: unexpected state")
            }
        }
    }
}
Borgia answered 15/1, 2023 at 15:38 Comment(0)
H
0

You must be opening another view controller from current view controller. That set the value of isIdleTimerDisabled to false when viewDidDisappear calls. So, you should set UIApplication.shared.isIdleTimerDisabled = true in viewDidAppear. Hope this will solve your issue.

Huston answered 2/3, 2022 at 9:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.