Files
CoreStore/HardcoreData
2015-05-07 00:30:45 +09:00
..
2015-05-04 12:40:16 +09:00
2015-05-04 12:40:16 +09:00
2015-05-04 12:40:16 +09:00
2015-05-04 12:40:16 +09:00
2015-05-04 12:40:16 +09:00
2015-05-04 12:40:16 +09:00
2015-04-28 01:26:34 +09:00
2015-05-04 12:40:16 +09:00
2014-12-07 21:38:54 +09:00
2015-05-04 12:40:16 +09:00
2014-09-14 21:51:40 +09:00
2014-12-07 21:38:54 +09:00
2015-05-04 12:40:16 +09:00
2015-05-04 12:40:16 +09:00
2015-02-21 21:14:19 +09:00
2015-05-06 01:06:22 +09:00
2015-02-21 21:14:19 +09:00
2015-05-04 12:40:16 +09:00
2015-05-04 12:40:16 +09:00
2015-02-22 23:01:45 +09:00
2015-05-04 12:40:16 +09:00

HardcoreData

Version Platform License

Simple, elegant, and smart Core Data programming with Swift

Features

  • Supports multiple persistent stores per data stack, just the way .xcdatamodeld files are supposed to. HardcoreData will also manage one data stack by default, but you can create and manage as many as you need. (see "Setting up")
  • Ability to plug-in your own logging framework (or your favorite 3rd-party logger). (see "Logging and error handling")
  • Makes it hard to fall into common concurrency mistakes. All Core Data tasks are encapsulated into safer, higher-level abstractions without sacrificing flexibility and customizability. (see "Saving and processing transactions")
  • Provides convenient API for common use cases. (see "Fetching and querying")
  • Pleasant API designed around Swifts code elegance and type safety. (see "TL;DR sample codes")

TL;DR sample codes

Quick-setup:

HardcoreData.defaultStack.addSQLiteStore("MyStore.sqlite")

Simple transactions:

HardcoreData.beginAsynchronous { (transaction) -> Void in
    let object = transaction.create(MyEntity)
    object.entityID = 1
    object.name = "test entity"

    transaction.commit { (result) -> Void in
        switch result {
            case .Success(let hasChanges): println("success!")
            case .Failure(let error): println(error)
        }
    }
}

Easy fetching:

let objects = HardcoreData.fetchAll(From(MyEntity))
let objects = HardcoreData.fetchAll(
    From(MyEntity),
    Where("entityID", isEqualTo: 1),
    SortedBy(.Ascending("entityID"), .Descending("name")),
    CustomizeFetch { (fetchRequest) -> Void in
        fetchRequest.includesPendingChanges = true
    }
)

Simple queries:

let count = HardcoreData.queryValue(
    From(MyEntity),
    Select<Int>(.Count("entityID"))
)

Architecture

For maximum safety and performance, HardcoreData will enforce coding patterns and practices it was designed for. (Don't worry, it's not as scary as it sounds.) But it is advisable to understand the "magic" of HardcoreData before you use it in your apps.

If you are already familiar with the inner workings of CoreData, here is a mapping of HardcoreData abstractions:

Core Data HardcoreData
NSManagedObjectModel / NSPersistentStoreCoordinator
(.xcdatamodeld file)
DataStack
NSPersistentStore
("Configuration"s in the .xcdatamodeld file)
DataStack configuration
(multiple sqlite / in-memory stores per stack)
NSManagedObjectContext BaseDataTransaction subclasses
(SynchronousDataTransaction, AsynchronousDataTransaction, DetachedDataTransaction)

RestKit and MagicalRecord set up their NSManagedObjectContexts this way:

nested contexts

This ensures maximum data integrity between contexts without blocking the main queue. But as Florian Kugler's investigation found out, merging contexts is still by far faster than saving nested contexts. HardcoreData's DataStack takes the best of both worlds by treating the main NSManagedObjectContext as a read-only context, and only allows changes to be made within transactions:

nested contexts and merge hybrid

This allows for a butter-smooth main thread, while still taking advantage of safe nested contexts.

Setting up

Saving and processing transactions

Fetching and querying

Logging and error handling

Observing changes and notifications (currently in the works)