Skip to content

AdnanYousaf813/AutoLogout

Repository files navigation

AutoLogout

AutoLogout is a swift library for managing user's session on inactivity.

What it does

On user inactivity, it will show an alert box to continue session or Logout as shown in screen shot, according to time set.

ScreenShot

alt text

Installation

AutoLogout is only available via CocoaPods:

pod 'AutoLogout'

Usage

  • To reset timer on touch event, override sendEvent function.
  • To get notify on touch event create protocol.
import UIKit

public protocol WindowDelegate: AnyObject {
    func window(_ window: Window, touchDetectedIn event: UIEvent)
}

public class Window: UIWindow {
    
    public weak var delegate: WindowDelegate?
    
    public override func sendEvent(_ event: UIEvent) {
        super.sendEvent(event)
        
        let touches = event.allTouches?
            .filter( { $0.phase == .began || $0.phase == .ended } ) ?? []
        if touches.count > 0 {
            delegate?.window(self, touchDetectedIn: event)
        }
        
    }
}
  • Setup inactivity Timer as below
    private var inactivityAlertShowAfterMinutes = 1.0 /// Time after which pop up will appear for remaining time
    private var sessionTimeoutAfterMinutes = 2.0 /// Total Session Time Out Time
    
    private func setupInactivityTimers() {
        guard inactivityAlertTimer == nil else { return }
        inactivityAlertTimer = WatchTimer(duration: .minutes(inactivityAlertShowAfterMinutes)) { [weak self] in
            self?.showInactivityAlert()
            self?.inactivityAlertTimer = nil
        }
        sessionTimeoutTimer = WatchTimer(duration: .minutes(sessionTimeoutAfterMinutes)) { [weak self] in
            self?.logout()
        }
    }
  • ShowInactivityALert func is for showing alert box.
    private func showInactivityAlert(animated: Bool = true) {
        
        guard let sessionTimeoutTimer = sessionTimeoutTimer else { return }
        
        let inactivityAlertController = InactivityAlertController(timer: sessionTimeoutTimer)
        inactivityAlertController.delegate = self

        /// Handle your logic here regarding current view controller
//        var topViewController: UIViewController = rootViewController
//        while let presentedViewController = topViewController.presentedViewController {
//            topViewController = presentedViewController
//        }
//        topViewController.present(inactivityAlertController, animated: animated)
        
        inactivityAlertController.modalPresentationStyle = .custom
        rootViewController.present(inactivityAlertController, animated: animated)
    
        self.inactivityAlertController = inactivityAlertController
        
    }
  • To reset timers on touch event, call this function
   func resetInactivityTimer() {
       inactivityAlertTimer = nil
       sessionTimeoutTimer = nil
       setupInactivityTimers()
   }
  • To pause and resume timers while swtiching from background to forground vise versa
    func pauseTimerOnbackground() {
        let inactivityRemainingSeconds = inactivityAlertTimer?.remainingTime?.in(.seconds) ?? 0
        inactivityEndDate = Calendar.current.date(byAdding: .second, value: Int(inactivityRemainingSeconds), to: Date())
        
        let sessionTimoutRemainingSeconds = sessionTimeoutTimer?.remainingTime?.in(.seconds) ?? 0
        sessionTimeoutEndDate = Calendar.current.date(byAdding: .second, value: Int(sessionTimoutRemainingSeconds), to: Date())
        
        inactivityAlertTimer?.stop()
        sessionTimeoutTimer?.stop()
    }
    
    /// if the time is remaining it will resume timer on foreground other wise user will logout automaticaly.
    func resumeTimerOnForeground() {
        
        if let sessionTimeOutDate = sessionTimeoutEndDate{
            if Date() > sessionTimeOutDate{
                self.logout()
            }else{
                let differenceInSeconds = sessionTimeOutDate.timeIntervalSince(Date())
                sessionTimeoutTimer = WatchTimer(duration: .seconds(differenceInSeconds)) { [weak self] in
                    self?.logout()
                }
            }
        }
        
        if let inactivityDate = inactivityEndDate{
            if Date() > inactivityDate{
                if inactivityAlertController != nil{
                    inactivityAlertController?.dismiss(animated: false, completion: {
                        self.showInactivityAlert(animated: false)
                        self.inactivityAlertTimer = nil
                    })
                }else{
                    self.showInactivityAlert(animated: true)
                    self.inactivityAlertTimer = nil
                }
            }else{
                let differenceInSeconds = inactivityDate.timeIntervalSince(Date())
                inactivityAlertTimer = WatchTimer(duration: .seconds(differenceInSeconds)) { [weak self] in
                    self?.showInactivityAlert()
                    self?.inactivityAlertTimer = nil
                }
            }
        }
    }
  • Logout func where you add necessary code
    func logout() {
        
        /// Handle here to move on required screen
        inactivityAlertTimer = nil
        sessionTimeoutTimer = nil
        self.inactivityAlertController?.dismiss(animated: true, completion: nil)
    }
  • delegate function of InactivityAlertController for Continue and Logout Button actions
extension AppCoordinator: InactivityAlertControllerDelegate {
    func inactivityAlertControllerDidSelectLogout(_ inactivityAlertController: InactivityAlertController) {
        logout()
    }
    
    func inactivityAlertControllerDidSelectContinue(_ inactivityAlertController: InactivityAlertController) {
        setupInactivityTimers()
        inactivityAlertController.presentingViewController?.dismiss(animated: true)
    }
}
  • To reset Timers when user touch on screen, this delegate function will get call.
extension AppCoordinator: WindowDelegate {
    func window(_ window: Window, touchDetectedIn event: UIEvent) {
        resetInactivityTimer()
    }
}
  • You can call this function from AppDelegate class in life cycle functions
    func applicationDidEnterBackground() {
        pauseTimerOnbackground()
    }
    
    func applicationWillEnterForeground() {
        resumeTimerOnForeground()
    }

For more Detail See Example project.

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

License

AutoLogout is released under the MIT license.

About

On user inactivity, it will show an alert box to continue session or Logout as shown in screen shot, according to time set.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published