Couples: powered by CoreStore (english ver)


Hi guys! I’m John, one of the iOS developers in the Couples team.
I’m also the author of CoreStore, a Swift Core Data library which we use heavily in our very-popular Couples app.

I started writing CoreStore a year ago when Swift was first released, and has since then grown to be the stable powerhouse it is today (and still improving!) thanks to the heavy demands of our app.

Today I’d like to share CoreStore’s features that provides foundation to the Couples iOS app.

Couples × CoreStore

Type Safety

With the wide array of data stored and displayed in the Couples app, our Core Data model contains more than 40 data entities including Messages, Q&As, Calendars, Links, Albums, Photos, Articles, Stamps, etc.
CoreStore allows no type-casts by exposing type-safe generic classes and utilities:

extension ArticlesViewController: ListObjectObserver {
func listMonitor(monitor: ListMonitor<Article>, didUpdateObject object: Article, atIndexPath indexPath: NSIndexPath) {

let article: Article = monitor[indexPath]
// ...
The Couples app keeps a record of a couple's photos, messages, anniversaries, etc. that gets updated in the background. Multiple reads and writes on a single database is usually unsafe as it introduces race conditions that may break data in a way that the user does not expect.
CoreStore prevents this problem by making reads execute on the main thread, while executing background updates within transactions:
CoreStore.beginAsynchronous { (transaction) -> Void in
let event: Event = transaction.create(Into(Event))
event.eventDate = eventDate
event.startDate = startDate
event.endDate = endDate
// ...
transaction.commit { result in
// ...

Internally, CoreStore executes these transactions in a serial queue.
1 SQLite file = 1 Transaction Queue.
You might be worried then, wouldn't this setup cause bottlenecks?
Data Separation
The answer is that CoreStore heavily supports multiple Data Stacks. The Couples app separates the data stack for unrelated data so transactions within them can run independently:
Data Import
When the app receives updates from our webserver, CoreStore efficiently imports lists of data by using an efficient batch update-insert algorithm. In our code, all we have to do is implement the ImportableUniqueObject protocol and its methods:
class Article: NSManagedObject, ImportableUniqueObject {
// ...
func updateFromImportSource(source: JSON, inTransaction transaction: BaseDataTransaction) throws {
self.linkURL = source["url"] as? String
self.siteTitle = source["title"] as? String
self.siteDescription = source["desc"] as? String
// ...

Now anytime we receive a JSON response from our server, we just have to start a transaction and import our JSON array
CoreStore.beginAsynchronous { (transaction) -> Void in
do {
let articles: [Article] = try transaction.importUniqueObjects(
sourceArray: json["articles"]
// ...
transaction.commit { result in
// ...

To prevent duplicates, this importing utility also manages uniquing when a unique ID is provided.
Real-time Updates
To provide users their latest chat messages, photos, and other notifications from their loved one, Couples need to display data to the user as soon as possible. CoreStore provides a ListMonitor and an ObjectMonitor class that replaces NSFetchedResultsController and KVO.
let anniversaryListMonitor: ListMonitor = CoreStore.monitorList(
Where("isAnniversary == true")
&& Where("startDate >= %@", dateToday)
&& Where("startDate <= %@", dateTomorrow),
These classes can send notifications to multiple observers, which means a single list can be shared by multiple view controllers.
// ...
This saves a lot of memory!


One of the headaches when releasing app updates is Core Data migrations. Normally you need to provide mapping models from all previous versions to the latest version:
This is hard to maintain! CoreStore saved us from all the maintenance burden by allowing incremental migration.
This means we only need to add a new version and CoreStore takes care of the rest!
CoreStore.defaultStack = DataStack(
modelName: "CouplesData",
migrationChain: ["CouplesDataV1", "CouplesDataV2", "CouplesDataV3", "CouplesDataV4"]
For apps that need heavy data management, such as social networking apps and other media content apps, I definitely recommend CoreStore. I update the Github repository regularly and I'd be happy to answer any questions. Just send an issue or a pull request anytime!