Skip to content

Instantly share code, notes, and snippets.

@dimazen
Created April 1, 2015 07:18
Show Gist options
  • Save dimazen/b5e00bcfc9ddb5838122 to your computer and use it in GitHub Desktop.
Save dimazen/b5e00bcfc9ddb5838122 to your computer and use it in GitHub Desktop.
User Session
import Foundation
enum UserSessionState: Int {
case Initialized, Opened, Closed
}
class UserSession {
let identifier: String
private(set) lazy var serviceLocator: ServiceLocator = { [unowned self] in
let locator = ServiceLocator()
let keychain = FXKeychain(service: NSBundle.mainBundle().bundleIdentifier!, accessGroup: nil)
locator.registerService(keychain, forClass: FXKeychain.self)
let stackSettings = CoreDataStackSettings(modelName: "ModelName", rootPath: "\(self.rootPath)/data")
let coreDataStack = CoreDataStack(settings: stackSettings)
locator.registerService(coreDataStack, forClass: CoreDataStack.self)
return locator
}()
private(set) var credentials: UserSessionCredentials!
init?(restorationIdentifier identifier: String) {
self.identifier = identifier
let credentials = UserSessionCredentials(keychain: serviceLocator.serviceForClass(FXKeychain.self) as! FXKeychain)
if credentials.valid {
self.credentials = credentials
} else {
return nil
}
}
init(sessionPrototype: UserSessionPrototype) {
identifier = NSUUID().UUIDString
credentials = UserSessionCredentials(keychain: serviceLocator.serviceForClass(FXKeychain.self) as! FXKeychain)
credentials.token = sessionPrototype.token
}
// MARK: - State
private(set) var state = UserSessionState.Initialized
func open() {
assert(state == .Initialized, "Session can be opened once")
// can be used for futher resources warm-up
state = .Opened
}
func close() {
assert(state == .Opened, "Only opened session can be closed")
// can be used for futher resources cleanup
state = .Closed
}
}
extension UserSession {
// MARK: - Path
var rootPath: String {
#if os(iOS)
let directory = NSSearchPathForDirectoriesInDomains(
.DocumentDirectory,
.UserDomainMask,
true
).first as! String
let result = "\(directory)/session/\(identifier)"
return result
#else
let directory = NSSearchPathForDirectoriesInDomains(
.ApplicationSupportDirectory,
.UserDomainMask,
true
).first as! String
let result = "\(directory)/\(NSBundle.mainBundle().bundleIdentifier!)/session/\(identifier)"
return result
#endif
}
}
import Foundation
class UserSessionController {
private static let sessionIdentifierKey = "\(NSBundle.mainBundle().bundleIdentifier!).sessionController.sessionIdentifier"
private var storedSessionIdentifier: String? {
get {
let value = userDefaults.objectForKey(UserSessionController.sessionIdentifierKey) as? String
return value
}
set {
userDefaults.setObject(newValue, forKey: UserSessionController.sessionIdentifierKey)
userDefaults.synchronize()
}
}
private let userDefaults: NSUserDefaults
init(userDefaults: NSUserDefaults) {
self.userDefaults = userDefaults
}
// MARK: - Session
private(set) var session: UserSession? {
didSet {
oldValue?.close()
storedSessionIdentifier = session?.identifier
session?.open()
}
}
// MARK: - Session Management
func openSessionFromPrototype(prototype: UserSessionPrototype) -> UserSession {
assert(session == nil, "Can`t open 2 sessions")
session = UserSession(sessionPrototype: prototype)
return session!
}
func closeSession() {
assert(session != nil, "Can`t open nil session")
session = nil
}
func restorePreviousSession() -> UserSession? {
assert(session == nil, "Can`t open 2 sessions")
if let identifier = storedSessionIdentifier, let session = UserSession(restorationIdentifier: identifier) {
self.session = session
return session
}
return nil
}
func canRestorePreviousSession() -> Bool {
return storedSessionIdentifier != nil
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment