A lightweight key-value store to share data across ViewControllers and or SKScenes
AppSession is a simple wrapper around a dictionary type that allows one
to easily share data across different SpriteKit Scenes and or ViewControllers
for the duration of a single session of an App.
AppSession is available through CocoaPods. To install
it, simply add the following line to your Podfile:
pod 'AppSession', '0.2.0'
Modify your “Cartfile” to include the following line
github "taywils/SwiftAppSession" "0.2.0"
Then run the command from the base directory of your project where the Cartfile is located
carthage update SwiftAppSession
AppSession uses the sharedInstance pattern to represent a Singleton.
Thus there is no need for declaring any AppSession objects.
Store something in AppSession using set
let foobar = 42
AppSession.set("foo", value: foobar)
Later on take something out of AppSession with get
let barFoo = AppSession.get("foo") as? Int
Use delete to get rid of something you don’t need in AppSession anymore
AppSession.delete("foo")
Use the group parameter of AppSession.set to reduce key collisions, or to mark data as related
Example: Pretend we are on the menu page of a restaurant app
AppSession.set("main_dish", value: "Steak", group: "order")
AppSession.set("side_dish", value: "Salad", group: "order")
AppSession.set("coupon", value: "12231", group: "order")
Now when you segue over to the checkout page, you pull the “order” from the AppSession.
Included with AppSession is a typealias AppSessionGroup
typealias AppSessionGroup = [String: Any]
Use the typealias when extracting groups from AppSession.
let customerOrder = AppSession.get("order") as? AppSessionGroup
From there you can then access the values since its a dictionary with Any
let mainDishName = customerOrder?["main_dish"] as? String
let sideDishName = customerOrder?["side_dish"] as? String
let couponCode = customerOrder?["coupon"] as? String
Then if the coupon causes some modal view to display over the checkout page that needs to update the order
we can just update the AppSession “order” group
AppSession.set("special_discount", value: 0.20, group: "order")
Then when you dismiss the modal you can just pop the discount and apply it to your price
let discount = AppSession.pop("special_discount") as? Double
Now isn’t that neat? We didn’t have to fire any NSNotifications or re-wire our Storyboards or add a specialDiscount property to a Model or modify our unit tests that probably would have broken the build on our CI server due to some random place in the code that wasn’t updated to rely on the new specialDiscount property.
AppSession allows you to store complex types such as classes, structs and nested arrays.
The trick with using them is to properly typecast the value upon retrieval.
Consider a struct that you’ve defined in your code, you place it in the AppSession.
struct BasicStruct {
var property: String
init(property: String) {
self.property = property
}
}
let basicStruct = BasicStruct(property: "hello world")
AppSession.set("basic_struct", value: basicStruct)
Just like any other type you can obtain the struct by casting the value from the AppSession.
let myStruct = AppSession.get("basic_struct") as? BasicStruct
Classes, being reference types are a bit different in that AppSession does not create a separate copy of your class.
If you update the value of the object outside the session its changes will update the shared reference in the AppSession.
/* WARNING: Storing reference types within AppSession could lead to accidental state changes */
class BasicClass {
var prop: Int
init(prop: Int) {
self.prop = prop
}
func method() -> String {
return String(self.prop)
}
}
Update the class by setting a property value.
let basicClass: BasicClass? = BasicClass(prop: 42)
// Store the class in the session
AppSession.set("basic_class", value: basicClass)
Now outside of the session we set the prop again.
basicClass?.prop = 777
Once you get the class from the session it will have the updated value.
let basicClassFromSession = AppSession.get("basic_class") as? BasicClass
assert(basicClass?.prop == basicClassFromSession?.prop)
Always be cautious about storing reference types in AppSession.
Some of the other methods include the following:
Count returns the number of keys within AppSession.
AppSession.count
Keys will return a Set of all the keys
AppSession.keys
groups will return a Set of all the group names as strings
AppSession.groups
Completely wipes the entire AppSession.
AppSession.clear()
Returns true if the given key exists in the current AppSession
AppSession.contains("some_key")
// This is equivalent to
AppSession.keys.contains("some_key".lowercaseString)
Prints a DEBUG dump of the current items stored within AppSession
AppSession.info()
AppSession was created due to my frustrations with existing tools that either needed to access the disk for caching,
required modifying my code to implement some strange Protocol(s) and or couldn’t handle storing reference types.
So during the creation/debugging of one of my SpriteKit games I started building a class that let me initialize a SKScene
based on any arbitrary game data; I extracted the code from my game and re-named it AppSession.
AppSession is available under the MIT license. See the LICENSE file for more info.