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

Overview

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.

You might also like...
Venice - Coroutines, structured concurrency and CSP for Swift on macOS and Linux.
Venice - Coroutines, structured concurrency and CSP for Swift on macOS and Linux.

Venice provides structured concurrency and CSP for Swift. Features Coroutines Coroutine cancelation Coroutine groups Channels Receive-only chan

Syntactic sugar in Swift for asynchronous dispatches in Grand Central Dispatch

Async Now more than syntactic sugar for asynchronous dispatches in Grand Central Dispatch (GCD) in Swift Async sugar looks like this: Async.userInitia

Elegant ⏱ interface for Swift apps

Each Elegant ⏱ interface for Swift apps Each is a NSTimer bridge library written in Swift. Features Requirements Installation Usage Leaks License Feat

 GCDTimer - Well tested Grand Central Dispatch (GCD) Timer in Swift
GCDTimer - Well tested Grand Central Dispatch (GCD) Timer in Swift

GCDTimer Well tested Grand Central Dispatch (GCD) Timer in Swift. Checkout the test file. Usage Long running timer import GCDTimer

Schedule timing task in Swift using a fluent API. (A friendly alternative to Timer)
Schedule timing task in Swift using a fluent API. (A friendly alternative to Timer)

Schedule(简体中文) Schedule is a timing tasks scheduler written in Swift. It allows you run timing tasks with elegant and intuitive syntax. Features Elega

Grand Central Dispatch simplified with swift.

GCDKit GCDKit is Grand Central Dispatch simplified with Swift. for Swift 1.2: Use version 1.0.1 for Swift 2.1 / 2.2: Use the master branch Introductio

Queues, timers, and task groups in Swift
Queues, timers, and task groups in Swift

Dispatcher eases the pain of using Grand Central Dispatch by introducing 4 new Swift classes. Dispatcher Queue Group Timer Requirements Swift 2.0+ Ins

A wrapper of Grand Central Dispatch written in Swift

GCD A wrapper of Grand Central Dispatch written in Swift. Examples gcd // submit your code for asynchronous execution on a global queue with high prio

A Swift microframework for very easy atomic values.

Atomic Atomic is a fast, safe class for making values thread-safe in Swift. It is backed by pthread_mutex_lock which is the fastest, most-efficient lo

Releases(1.2)
Kommander is a Swift library to manage the task execution in different threads.

A lightweight, pure-Swift library for manage the task execution in different threads. Through the definition a simple but powerful concept, Kommand.

Intelygenz 173 Apr 11, 2022
AwaitKit is a powerful Swift library which provides a powerful way to write asynchronous code in a sequential manner.

AwaitKit is a powerful Swift library inspired by the Async/Await specification in ES8 (ECMAScript 2017) which provides a powerful way to write asynchronous code in a sequential manner.

Yannick Loriot 752 Dec 5, 2022
An actor model library for swift.

Aojet Aojet is an actor model implemetion for swift. Features Asynchronous, non-blocking and highly performant message-driven programming model Safe a

null 37 Apr 7, 2022
Hydra: Lightweight full-featured Promises, Async-Await Library in Swift

Async Functions for ECMAScript The introduction of Promises and Generators in EC

Ecma TC39 1.6k Oct 17, 2022
A declarative state management and dependency injection library for SwiftUI x Concurrency

A declarative state management and dependency injection library for SwiftUI x Concurrency

Ryo Aoyama 199 Jan 1, 2023
Lightweight async/await networking library with interceptor support - usable from iOS 13+.

Lightweight async/await networking library with interceptor support. ?? Getting started AsyncNetwork's session acts as a wrapper to URLSession by addi

Paul 9 Oct 4, 2022
A complete set of primitives for concurrency and reactive programming on Swift

A complete set of primitives for concurrency and reactive programming on Swift 1.4.0 is the latest and greatest, but only for Swift 4.2 and 5.0 use 1.

AsyncNinja 156 Aug 31, 2022
Futures is a cross-platform framework for simplifying asynchronous programming, written in Swift.

Futures Futures is a cross-platform framework for simplifying asynchronous programming, written in Swift. It's lightweight, fast, and easy to understa

David Ask 60 Aug 11, 2022
GroupWork is an easy to use Swift framework that helps you orchestrate your concurrent, asynchronous functions in a clean and organized way

GroupWork is an easy to use Swift framework that helps you orchestrate your concurrent, asynchronous functions in a clean and organized way. This help

Quan Vo 42 Oct 5, 2022
SwiftCoroutine - Swift coroutines for iOS, macOS and Linux.

Many languages, such as Kotlin, Go, JavaScript, Python, Rust, C#, C++ and others, already have coroutines support that makes the async/await pattern i

Alex Belozierov 808 Dec 1, 2022