Latest 1.0.0
Homepage https://github.com/BottleRocketStudios/iOS-SessionTools
License Apache
Platforms ios 9.0
Frameworks Foundation
Authors

CI Status
Version
License
Platform

Purpose

This library makes session management easier. There are a few main goals:

  • Provide a simple way to create "session" objects for storing, updating, deleting, and refreshing session-related data (credentials, tokens, etc.).
  • Provide a pre-built UserSession to simplify the work needed to deal with user login/logout.
  • Broadcast login/logout/update notifications when your model object changes.
  • Store your model object in a secure storage mechanism since it usually contains sensitve information.

Key Concepts

  • Session – A base class for creating something that can store, retrieve, and delete an item in a SessionContainer. Can post notifications by providing a NotificationPoster.
  • SessionContainer – A conatiner for storing data to the keychain.
  • Refreshable – Represents something that can be refreshable. In our use case, a Session.
  • NotficationPosting – Represents something that can post a notification.
  • UserSession – Handles storage, deletion, and retrieval of the current user. Broadcasts notifications when user session state changes. Can call a RefreshHandler block if provided.
  • KeychainStorageContainer – A container that uses the keychain as the backing store. You can make your own container by subclassing SessionContainer.
  • KeychainContainerConfig – A class to configure the KeychainStorageContainer for use.

Usage

SessionTools out of the box uses the keychain to store your session data. To allow for maximum flexibility, you can use the SessionTools/Base subspec to integrate SessionTools without the keychain dependencies. Going forward, we are assuming you are using this on iOS and want to use the keychain. You’ll need to create a few things before working with a Session.

1. Create a model object that conforms to Codable.

struct Model: Codable {
    let firstName: String
    let lastName: String
    let email: String
    let token: String
}

2. Create a KeychainContainerConfig supplied with a keychainName.

let config = KeychainContainerConfig(keychainName: "your.keychain.name")

3. Create a KeychainStorageContainer supplied with a KeychainContainerConfig. (Or create your own SessionContainer subclass and instantiate it)

let container = KeychainStorageContainer<Model>(config: config)

4. Wrap your storage container in a type erased container.

let anyContainer = AnySessionContainer(container)

Now you can make use of a Session in a few different ways.

Option 1 – Use Session as is by suppling your placeholder type.

let session = Session<Model>(container: anyContainer, storageIdentifier: "identifier.for.your.model.object")

Option 2 – Create a subclass of Session with your model as the placeholder type. Optionally, conform to Refreshable to refresh your session.

class ModelSession: Session<Model>, Refreshable {
    // your class code here

    // MARK: - Refreshable

    func refresh(completion: @escaping RefreshCompletion) {
        // your refresh code here
        completion(nil)
    }
}

Option 3 – Use UserSession, a Session already setup for you to deal with logging in/out and broadcasting notifications.

let userSession = UserSession<Model>(container: anyContainer, storageIdentifier: "identifier.for.your.model.object", notificationPoster: NotificationCenter.default)

You can also supply a refreshHandler to UserSession to use whenever refreshing.

private static func userRefreshHandler(_ completion: @escaping RefreshCompletion) -> Void {
    // your refresh code
    completion(nil)
}

let userSession = UserSession<Model>(container: container, storageIdentifier: "identifier.for.your.model.object", notificationPoster: NotificationCenter.default, refreshHandler: userRefreshHandler)

Get current user info.

userSession.currentUser
userSession.isLoggedIn

Handle logging in, logging out, and updating.

do {
    try userSession.didLogIn(model)
    try userSession.didLogOut(nil)
    try userSession.didUpdate(model)
} catch {
    //Handle container errors here
}

Observe notifications.

NotificationCenter.default.addObserver(self, selector: #selector(didUpdateUser:), name: .sessionStateDidChange, object: nil)

Easily get the state change from the notification payload.

@objc private func didUpdateUser(_ notification: Notification) {
    guard let sessionState = notification.userSessionState else { return }
    //Do something with the state
}

Example

To run the example project, clone the repo, and run pod install from the Example directory first.

Requirements

  • iOS 9.0+
  • Swift 4.1

Installation

SessionTools is available through CocoaPods. To install
it, simply add the following line to your Podfile:

pod 'SessionTools'

Or if you’re not working in an environment with access to the keychain, use the base subspec:

pod 'SessionTools/Base'

Contributing

See the CONTRIBUTING document. Thank you, contributors!

Latest podspec

{
    "name": "SessionTools",
    "version": "1.0.0",
    "summary": "Provides a simple way to make "session" objects for storing, deleting, and refreshing data.",
    "description": "Provides a simple way to create "session" objects for use in your own session manager setup. It can store, delete, and refresh any info you want. You can also broadcast notifications when your info changes.",
    "homepage": "https://github.com/BottleRocketStudios/iOS-SessionTools",
    "license": {
        "type": "Apache",
        "file": "LICENSE"
    },
    "authors": {
        "Bottle Rocket Studios": "[email protected]"
    },
    "source": {
        "git": "https://github.com/bottlerocketstudios/iOS-SessionTools.git",
        "tag": "1.0.0"
    },
    "platforms": {
        "ios": "9.0"
    },
    "frameworks": "Foundation",
    "source_files": [
        "SessionTools/Classes/Base/*",
        "SessionTools/Classes/KeychainStorage/*"
    ],
    "subspecs": [
        {
            "name": "Base",
            "source_files": "SessionTools/Classes/Base/*"
        },
        {
            "name": "KeychainStorage",
            "dependencies": {
                "KeychainAccess": []
            }
        }
    ]
}

Pin It on Pinterest

Share This