Skip to content

BabyShung/SplashWindow

Repository files navigation

SplashWindow

Carthage compatible Swift Version Platform

About

This is an UIWindow-based touchID authentication view framework written in Swift.

Framework is designed for:

  • You want a relatively decoupled touchID framework (Only couple with your AppDelegate and your SettingsVC)
  • Your app is information-sensitive and you want touchID automaticlly on (A device supports and has touchID on)

Screenshots

Integrate framework

1. Carthage - github "BabyShung/SplashWindow"

  • install carthage

  • create Cartfile (touch Cartfile)

  • add framework in Cartfile: github "BabyShung/SplashWindow"

  • run "carthage update"

  • bind frameworks in your project (add a shell script in build phase and bind the paths of frameworks)

There is another example project using Carthage to import the framework: https://github.com/BabyShung/UsingZHFrameworks

2. Manually configure

There is a "Demo" folder in the repo. You will find three targets, two of them are the needed frameworks. Just run the project and you can drag both SplashWindow.framework and ZHExtension.framework to your "Linked Frameworks and Libraries".

Warnings (Please read)

  • Framework supports iOS8+
  • The framework doesn't contain a authentication settings page. There is a "Demo" project in the repo showing the authSettings view controller for reference. Definitely you can create your own settings view controller and just call APIs in AppAuthentication to turn on/off touchID
  • The only authentication for now is touchID and passcode view is not implemented for simplicity
  • By default, touchID is turned on once you integrate this framework
  • Sometimes after you've set the launchScreen image in your storyboard or xib, the splash screen is showing a blank view when running. This is a cache issue. To fix it, clean your project. If it still doesn't work, reboot your device or reset your similator.
  • Make sure "Always Embed Swift Standard Libraries" in "Build Settings" is set to Yes.

Import and setup in your project

Once you've added the framework in your project, just go to AppDelegate.swift and do a few steps.

  • import SplashWindow
  • declare a SplashWindow property and pass your window, launchVC etc
  • in didFinishLaunchingWithOptions, setup your initial view controller and call SplashWindow API
  • in applicationWillResignActive, call showSplashView()
  • in applicationDidEnterBackground, call enteredBackground()
  • in applicationDidBecomeActive, call authenticateUser
  • go to your launchScreen.storyboard or launchScreen.xib and set your image:

Demo project

There is a "Demo" project in the folder where everything is setup in AppDelegate

Comments are there explaining what to configure in AppDelegate (Code also attached below):

Once you've configured your AppDelegate, touchID should work.

import UIKit
import SplashWindow

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    
    lazy var splashWindow: SplashWindow = {
        let identifier = "LaunchScreen"
        let vc = UIStoryboard.named(identifier, vc: identifier)
        let splashWindow = SplashWindow.init(window: self.window!, launchViewController: vc)
        
        /** Customization - otherwise default
         
            AppAuthentication.shared.touchIDMessage = "YOUR MESSAGE"
            splashWindow.touchIDBtnImage = UIImage(named: "user.png")
            splashWindow.logoutBtnImage = UIImage(named: "user.png")
         */
        
        //Auth succeeded closure
        splashWindow.authSucceededClosure = { _ in }
        
        //Return a loginVC after clicking logout
        splashWindow.logoutClosure = { _ in
            return UIStoryboard.named("Login", vc: "LoginViewController")
        }
        return splashWindow
    }()
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        
        let initialVC = UINavigationController(rootViewController: AuthFlowController().authSettingVC)
        /*
         Use your logic to determine whether your app is loggedIn
         initialVC can be any of your viewController, but must make sure if it's loggedIn when showing this VC
         */
        splashWindow.authenticateUser(isLoggedIn: true, initialVC: initialVC)
        
        return true
    }
    
    func applicationWillResignActive(_ application: UIApplication) {
        
        splashWindow.showSplashView()
    }
    
    func applicationDidEnterBackground(_ application: UIApplication) {
        
        splashWindow.enteredBackground()
    }
    
    func applicationDidBecomeActive(_ application: UIApplication) {
        
        /*
         Use your logic to determine whether your app is loggedIn
         
         If you already have some code here in didBecomeActive such as refreshing
         network request or load data from database, if you want to bypass
         these actions before authentication, use self.splashWindow.isAuthenticating:
         
            //1. call authenticateUser first
            splashWindow.authenticateUser(isLoggedIn: true)
            
            //2. if you are authenticating, here it skips YOUR NETWORK CODE or DATABASE CODE
            guard !splashWindow.isAuthenticating else { return }
   
            //...
            //YOUR NETWORK CODE or DATABASE CODE
            //...
            
         */
        
        let rootIsLoginVC = window?.rootViewController is LoginViewController
        splashWindow.authenticateUser(isLoggedIn: !rootIsLoginVC)
    }
}

TODO

  • Fix some small UI issues
  • Add more unit tests
  • Refactor some of the code