Skip to content

Instantly share code, notes, and snippets.

@jparishy
Created August 21, 2014 03:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jparishy/01dd7923dda41ad641d5 to your computer and use it in GitHub Desktop.
Save jparishy/01dd7923dda41ad641d5 to your computer and use it in GitHub Desktop.
Core Data in Swift
//
// main.swift
// SwiftData
//
// Created by Julius Parishy on 8/20/14.
// Copyright (c) 2014 le. All rights reserved.
//
import Foundation
import CoreData
class Stack {
let modelURL: NSURL
let storeURL: NSURL?
let storeType: String?
let storeOptions: NSDictionary?
init(modelURL: NSURL, storeURL: NSURL?, storeType: String?, storeOptions: NSDictionary?) {
self.modelURL = modelURL
self.storeURL = storeURL
self.storeType = storeType
self.storeOptions = storeOptions
}
convenience init(modelURL: NSURL, storeURL: NSURL?) {
self.init(modelURL: modelURL, storeURL: storeURL, storeType: NSSQLiteStoreType, storeOptions: nil)
}
lazy var persistentStoreCoordinator : NSPersistentStoreCoordinator? = {
return Stack._persistentStoreCoordinator(self.modelURL, storeURL: self.storeURL, storeType: self.storeType, storeOptions: self.storeOptions)
}()
lazy var backgroundQueueContext : Context? = {
if let masterManagedObjectContext = Stack._managedObjectContextWithConcurrencyType(self, concurrencyType: .PrivateQueueConcurrencyType) {
masterManagedObjectContext.persistentStoreCoordinator = self.persistentStoreCoordinator
return Context(stack: self, masterManagedObjectContext: masterManagedObjectContext)
} else {
return nil
}
}()
lazy var mainQueueContext : Context? = {
if let masterManagedObjectContext = Stack._managedObjectContextWithConcurrencyType(self, concurrencyType: .MainQueueConcurrencyType) {
if let background = self.backgroundQueueContext {
masterManagedObjectContext.parentContext = background.masterManagedObjectContext
return Context(stack: self, masterManagedObjectContext: masterManagedObjectContext)
} else {
return nil
}
} else {
return nil
}
}()
private class func _managedObjectContextWithConcurrencyType(stack: Stack, concurrencyType: NSManagedObjectContextConcurrencyType) -> NSManagedObjectContext? {
if let coordinator = stack.persistentStoreCoordinator {
let masterManagedObjectContext = NSManagedObjectContext(concurrencyType: concurrencyType)
masterManagedObjectContext.undoManager = nil
return masterManagedObjectContext
} else {
return nil
}
}
private class func _persistentStoreCoordinator(modelURL: NSURL, storeURL: NSURL?, storeType: String?, storeOptions: NSDictionary?) -> NSPersistentStoreCoordinator? {
let model = NSManagedObjectModel(contentsOfURL: modelURL)
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: model)
var error: NSError?
if !coordinator.addPersistentStoreWithType(storeType, configuration: nil, URL: storeURL, options: storeOptions, error: &error) {
return nil
}
return coordinator
}
}
class Transaction {
let context: Context
let managedObjectContext: NSManagedObjectContext
private init(context: Context) {
self.context = context
self.managedObjectContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
self.managedObjectContext.parentContext = self.context.masterManagedObjectContext
}
func executeQuery<T : AnyObject>(query: Query) -> Array<T>? {
let fetchRequest = NSFetchRequest(entityName: query.entityName)
fetchRequest.predicate = query.predicate
fetchRequest.sortDescriptors = query.sortDescriptors
var error: NSError?
if let results = self.managedObjectContext.executeFetchRequest(fetchRequest, error: &error) {
return results as? Array<T>
} else {
return nil
}
}
class func begin(context: Context, work: (Transaction) -> (Bool), success: (() -> ())?, failure: ((NSError) -> ())?) {
let transaction: Transaction = Transaction(context: context)
if work(transaction) {
var error: NSError?
if !transaction.managedObjectContext.save(&error) {
if let f = failure {
f(error!)
}
} else {
if let s = success {
s()
}
}
}
}
}
class Context {
let stack: Stack
internal let masterManagedObjectContext: NSManagedObjectContext
internal init(stack: Stack, masterManagedObjectContext: NSManagedObjectContext) {
self.stack = stack
self.masterManagedObjectContext = masterManagedObjectContext
}
internal convenience init(stack: Stack) {
let masterManagedObjectContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
masterManagedObjectContext.persistentStoreCoordinator = stack.persistentStoreCoordinator
self.init(stack: stack, masterManagedObjectContext: masterManagedObjectContext)
}
}
class Query {
private var sortDescriptors = [NSSortDescriptor]()
let entityName: String
let clauses: Dictionary<String, AnyObject>
init(entityName: String, clauses: Dictionary<String, AnyObject>) {
self.entityName = entityName
self.clauses = clauses
}
var predicate : NSPredicate? {
if clauses.count == 0 {
return nil
}
var string = ""
var index = 0
for (key, value) in clauses {
string += "\(key) == '\(value)'"
if index < clauses.count - 1 {
string += " && "
}
index++
}
return NSPredicate(format: string)
}
func sort(descriptors: [NSSortDescriptor]) -> Query {
for descriptor in descriptors {
sortDescriptors.append(descriptor)
}
return self
}
}
class SwiftDataModel : NSManagedObject {
class func coreDataEntityName() -> String {
return NSStringFromClass(self)
}
class func query(clauses: Dictionary<String, AnyObject>) -> Query {
let entityName = self.coreDataEntityName()
return Query(entityName: entityName, clauses: clauses)
}
}
@objc(Note) class Note : SwiftDataModel {
@NSManaged var text : NSString!
}
var stack = Stack(modelURL: NSURL(string: "Example.momd"), storeURL: NSURL(string: "Example.sqlite"), storeType: NSInMemoryStoreType, storeOptions: nil)
let context = stack.mainQueueContext
func doStuff() {
if let c = context {
Transaction.begin(c, work: { (transaction) in
var managedObjectContext = transaction.managedObjectContext
var entity = NSEntityDescription.entityForName(Note.coreDataEntityName(), inManagedObjectContext: managedObjectContext)
let texts = [ "Hello!", "Sup tho" ]
for text in texts {
var note : Note = NSManagedObject(entity: entity, insertIntoManagedObjectContext: managedObjectContext) as Note
note.text = text
}
return true
}, success: nil, failure: { (error) in
println("Failed :( \(error.localizedDescription)")
})
Transaction.begin(c, work: { (transaction) in
let query = Note.query([:]).sort([ NSSortDescriptor(key: "text", ascending: false) ])
if let results : Array<Note> = transaction.executeQuery(query) {
println("Results: \(results.map { (note) in note.text })")
}
return true
}, success: nil, failure: { (error) in
println("Query failed: \(error.localizedDescription)")
})
}
}
doStuff()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment