Stack 2.0.0

Stack 2.0.0

LangLanguage SwiftSwift
License MIT
ReleasedLast Release Feb 2016
SPMSupports SPM

Maintained by Shaps.

Stack 2.0.0


Wouldn’t it be great to have a type-safe CoreData Stack?


let stack = Stack.defaultStack()
let query = Query<Person>().sort(byKey: "name", direction: .Ascending).filter("name == %@", name)
let results = try! stack.fetch(query)


let stack = Stack.defaultStack()
stack.write({ (transaction) -> Void in
  let person = try transaction.fetchOrInsert("name", identifier: name) as Person
  person.age = 35
}, completion: nil)

Introducing Stack

CoreData is a powerful API, but its easily misused and misunderstood. Stack attempts to remove many of the issues associated with using CoreData in your applications.

Specifically, Stack adds both type-safety and thread-safety (ish) methods for dealing with queries and updates.

Additionally, Stack provides a much more expressive API through features like:

  • Type-safe inserts, updates and deletes
  • Query chaining
  • Custom Query class for setting up sorting, filtering, etc… (see Docs for more)
  • Transaction based API – No access to contexts!
  • Asynchronous
  • Lightweight – Swift function overloads allow the API to remain clean and concise
  • NSFetchedResultsController support – convenience init()


The aim of Stack is to provide a clean, expressive abstraction from CoreData. Giving you the flexibility and power of CoreData, without all the headache surrounding contexts and thread management.

With Swift, Stack now supports type-safe queries giving you more confidence when implementing CoreData in your applications.

Stack 2.0 provides read-only access through the Stack itself, moving all write methods into a transaction. This prevents you from making mistakes and attempting to update objects outside of a transaction.

Stack is used in various production apps, but I still consider it an ever changing concept so input is welcome :)

Need to Know


Once you have a Stack, reading is easy. You just need to construct a query and then call one of the fetch methods on your stack. Note: The optional is required since a fetch may return nil.

let person = try! stack.fetch("name", identifier: "123") as? Person

Now we can update that same object. Note: Thanks to Swift closures, we can safely re-define the variable with the same name.

let stack = Stack.defaultStack()
stack.write({ (transaction) -> Void in
  let person = transaction.copy(person)
  person.age = 35
}, completion: nil)

As you can see, all write actions occur ONLY inside a transaction, which prevents many common mistakes when implementing CoreData.

You probably noticed that copy() function? This is another nice feature provided by Stack. Basically it will copy the object(s) into the current transaction/context so you don’t try to modify an object on the wrong thread. And don’t worry, all changes will be propogated to your other threads automatically ;)


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


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

pod “Stack”


Shaps, [email protected]


Stack is available under the MIT license. See the LICENSE file for more info.


  • All code is my own, no 3rd party code is used in this project at all.